Skip to content

Commit 7676d9f

Browse files
committed
refactor keyvault e2e test
1 parent e68c679 commit 7676d9f

File tree

64 files changed

+323
-22053
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+323
-22053
lines changed

go.mod

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ require (
3737
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
40-
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.4.1
4140
k8s.io/apiserver v0.24.0
4241
)
4342

go.sum

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,6 @@ github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal v1.0.0 h1:lMW1lD/
5353
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/keyvault/armkeyvault v1.0.0 h1:Jc2KcpCDMu7wJfkrzn7fs/53QMDXH78GuqnH4HOd7zs=
5454
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/keyvault/armkeyvault v1.0.0/go.mod h1:PFVgFsclKzPqYRT/BiwpfUN22cab0C7FlgXR3iWpwMo=
5555
github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.0.0 h1:ECsQtyERDVz3NP3kvDOTLvbQhqWp/x9EsGKtb4ogUr8=
56-
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.4.1 h1:QSdcrd/UFJv6Bp/CfoVf2SrENpFn9P6Yh8yb+xNhYMM=
57-
github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.4.1/go.mod h1:eZ4g6GUvXiGulfIbbhh1Xr4XwUYaYaWMqzGD/284wCA=
5856
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
5957
github.com/Azure/go-ansiterm v0.0.0-20210608223527-2377c96fe795/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
6058
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=

test/e2e/testsuites/pre_provisioned_keyvault_tester.go

Lines changed: 23 additions & 311 deletions
Original file line numberDiff line numberDiff line change
@@ -19,61 +19,28 @@ package testsuites
1919
import (
2020
"context"
2121
"fmt"
22-
"net/url"
23-
"time"
2422

25-
"github.com/Azure/azure-sdk-for-go/sdk/azcore"
26-
"github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
27-
"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
28-
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/keyvault/armkeyvault"
29-
"github.com/Azure/azure-sdk-for-go/sdk/storage/azblob"
30-
"github.com/Azure/azure-sdk-for-go/services/graphrbac/1.6/graphrbac"
31-
"github.com/Azure/azure-sdk-for-go/services/msi/mgmt/2018-11-30/msi"
32-
"github.com/Azure/go-autorest/autorest"
33-
"github.com/Azure/go-autorest/autorest/adal"
34-
"github.com/Azure/go-autorest/autorest/azure"
3523
"github.com/onsi/ginkgo"
3624
v1 "k8s.io/api/core/v1"
37-
"k8s.io/apiserver/pkg/storage/names"
3825
clientset "k8s.io/client-go/kubernetes"
3926
"k8s.io/kubernetes/test/e2e/framework"
4027
"sigs.k8s.io/blob-csi-driver/pkg/blob"
4128
"sigs.k8s.io/blob-csi-driver/test/e2e/driver"
42-
"sigs.k8s.io/blob-csi-driver/test/utils/credentials"
43-
)
44-
45-
var (
46-
subscriptionID string
47-
resourceGroupName string
48-
location string
49-
vaultName string
50-
TenantID string
51-
cloud string
52-
clientID string
53-
clientSecret string
29+
"sigs.k8s.io/blob-csi-driver/test/utils/azure"
5430
)
5531

5632
// PreProvisionedKeyVaultTest will provision required PV(s), PVC(s) and Pod(s)
5733
// Testing that the Pod(s) can be created successfully with provided Key Vault
58-
// which is used to store storage account name and key(or sastoken)
34+
// which is used to store storage account name and key
5935
type PreProvisionedKeyVaultTest struct {
6036
CSIDriver driver.PreProvisionedVolumeTestDriver
6137
Pods []PodDetails
6238
Driver *blob.Driver
6339
}
6440

6541
func (t *PreProvisionedKeyVaultTest) Run(client clientset.Interface, namespace *v1.Namespace) {
66-
e2eCred, err := credentials.ParseAzureCredentialFile()
67-
framework.ExpectNoError(err, fmt.Sprintf("Error ParseAzureCredentialFile: %v", err))
68-
69-
subscriptionID = e2eCred.SubscriptionID
70-
resourceGroupName = e2eCred.ResourceGroup
71-
location = e2eCred.Location
72-
TenantID = e2eCred.TenantID
73-
cloud = e2eCred.Cloud
74-
clientID = e2eCred.AADClientID
75-
clientSecret = e2eCred.AADClientSecret
76-
vaultName = names.SimpleNameGenerator.GenerateName("blob-csi-test-kv-")
42+
keyVaultClient, err := azure.NewKeyVaultClient()
43+
framework.ExpectNoError(err)
7744

7845
for _, pod := range t.Pods {
7946
for n, volume := range pod.Volumes {
@@ -82,291 +49,36 @@ func (t *PreProvisionedKeyVaultTest) Run(client clientset.Interface, namespace *
8249
accountName, accountKey, _, containerName, err := t.Driver.GetStorageAccountAndContainer(context.TODO(), volume.VolumeID, nil, nil)
8350
framework.ExpectNoError(err, fmt.Sprintf("Error GetStorageAccountAndContainer from volumeID(%s): %v", volume.VolumeID, err))
8451

85-
azureCred, err := azidentity.NewDefaultAzureCredential(nil)
86-
framework.ExpectNoError(err)
87-
8852
ginkgo.By("creating KeyVault...")
89-
vault, err := createVault(context.TODO(), azureCred)
53+
vault, err := keyVaultClient.CreateVault(context.TODO())
9054
framework.ExpectNoError(err)
91-
defer cleanVault(context.TODO(), azureCred)
55+
defer func() {
56+
err := keyVaultClient.CleanVault(context.TODO())
57+
framework.ExpectNoError(err)
58+
}()
9259

9360
ginkgo.By("creating secret for storage account key...")
94-
accountKeySecret, err := createSecret(context.TODO(), azureCred, accountName+"-key", accountKey)
61+
accountKeySecret, err := keyVaultClient.CreateSecret(context.TODO(), accountName+"-key", accountKey)
9562
framework.ExpectNoError(err)
9663

9764
pod.Volumes[n].ContainerName = containerName
9865
pod.Volumes[n].StorageAccountname = accountName
9966
pod.Volumes[n].KeyVaultURL = *vault.Properties.VaultURI
10067
pod.Volumes[n].KeyVaultSecretName = *accountKeySecret.Name
101-
// test for Account key
102-
ginkgo.By("test storage account key...")
103-
run(pod, client, namespace, t.CSIDriver)
104-
105-
ginkgo.By("generate SAS token...")
106-
sasToken := generateSASToken(accountName, accountKey)
107-
108-
ginkgo.By("creating secret for SAS token...")
109-
accountSASSecret, err := createSecret(context.TODO(), azureCred, accountName+"-sas", sasToken)
110-
framework.ExpectNoError(err)
11168

112-
pod.Volumes[n].KeyVaultSecretName = *accountSASSecret.Name
113-
// TODO: test for SAS token
114-
// ginkgo.By("test SAS token...")
115-
// run(pod, client, namespace, t.CSIDriver)
69+
ginkgo.By("test storage account key...")
70+
tpod, cleanup := pod.SetupWithPreProvisionedVolumes(client, namespace, t.CSIDriver)
71+
// defer must be called here for resources not get removed before using them
72+
for i := range cleanup {
73+
defer cleanup[i]()
74+
}
75+
76+
ginkgo.By("deploying the pod")
77+
tpod.Create()
78+
defer tpod.Cleanup()
79+
80+
ginkgo.By("checking that the pods command exits with no error")
81+
tpod.WaitForSuccess()
11682
}
11783
}
11884
}
119-
120-
func run(pod PodDetails, client clientset.Interface, namespace *v1.Namespace, csidriver driver.PreProvisionedVolumeTestDriver) {
121-
tpod, cleanup := pod.SetupWithPreProvisionedVolumes(client, namespace, csidriver)
122-
// defer must be called here for resources not get removed before using them
123-
for i := range cleanup {
124-
defer cleanup[i]()
125-
}
126-
127-
ginkgo.By("deploying the pod")
128-
tpod.Create()
129-
defer tpod.Cleanup()
130-
131-
ginkgo.By("checking that the pods command exits with no error")
132-
tpod.WaitForSuccess()
133-
}
134-
135-
func generateSASToken(accountName, accountKey string) string {
136-
credential, err := azblob.NewSharedKeyCredential(accountName, accountKey)
137-
framework.ExpectNoError(err)
138-
serviceClient, err := azblob.NewServiceClientWithSharedKey(fmt.Sprintf("https://%s.blob.core.windows.net/", accountName), credential, nil)
139-
framework.ExpectNoError(err)
140-
sasURL, err := serviceClient.GetSASURL(
141-
azblob.AccountSASResourceTypes{Object: true, Service: true, Container: true},
142-
azblob.AccountSASPermissions{Read: true, List: true, Write: true, Delete: true, Add: true, Create: true, Update: true},
143-
time.Now(), time.Now().Add(12*time.Hour))
144-
framework.ExpectNoError(err)
145-
ginkgo.By("sas URL: " + sasURL)
146-
u, err := url.Parse(sasURL)
147-
framework.ExpectNoError(err)
148-
queryUnescape, err := url.QueryUnescape(u.RawQuery)
149-
framework.ExpectNoError(err)
150-
sasToken := "?" + queryUnescape
151-
ginkgo.By("sas Token: " + sasToken)
152-
return sasToken
153-
}
154-
155-
func createVault(ctx context.Context, cred azcore.TokenCredential) (*armkeyvault.Vault, error) {
156-
vaultsClient, err := armkeyvault.NewVaultsClient(subscriptionID, cred, nil)
157-
if err != nil {
158-
return nil, err
159-
}
160-
161-
pollerResp, err := vaultsClient.BeginCreateOrUpdate(
162-
ctx,
163-
resourceGroupName,
164-
vaultName,
165-
armkeyvault.VaultCreateOrUpdateParameters{
166-
Location: to.Ptr(location),
167-
Properties: &armkeyvault.VaultProperties{
168-
SKU: &armkeyvault.SKU{
169-
Family: to.Ptr(armkeyvault.SKUFamilyA),
170-
Name: to.Ptr(armkeyvault.SKUNameStandard),
171-
},
172-
TenantID: to.Ptr(TenantID),
173-
AccessPolicies: getAccessPolicy(ctx),
174-
},
175-
},
176-
nil,
177-
)
178-
if err != nil {
179-
return nil, err
180-
}
181-
182-
resp, err := pollerResp.PollUntilDone(ctx, nil)
183-
if err != nil {
184-
return nil, err
185-
}
186-
return &resp.Vault, nil
187-
}
188-
189-
func getAccessPolicy(ctx context.Context) []*armkeyvault.AccessPolicyEntry {
190-
accessPolicyEntry := []*armkeyvault.AccessPolicyEntry{}
191-
192-
// vault secret permission for upstream e2e test, which uses application service principal
193-
clientObjectID, err := getServicePrincipalObjectID(ctx, clientID)
194-
if err == nil {
195-
ginkgo.By("client object ID: " + clientObjectID)
196-
accessPolicyEntry = append(accessPolicyEntry, &armkeyvault.AccessPolicyEntry{
197-
TenantID: to.Ptr(TenantID),
198-
ObjectID: to.Ptr(clientObjectID),
199-
Permissions: &armkeyvault.Permissions{
200-
Secrets: []*armkeyvault.SecretPermissions{
201-
to.Ptr(armkeyvault.SecretPermissionsGet),
202-
},
203-
},
204-
})
205-
}
206-
207-
// vault secret permission for upstream e2e-vmss test, which uses msi blobfuse-csi-driver-e2e-test-id
208-
msiObjectID, err := getMSIObjectID(ctx, "blobfuse-csi-driver-e2e-test-id")
209-
if err == nil {
210-
ginkgo.By("MSI object ID: " + msiObjectID)
211-
accessPolicyEntry = append(accessPolicyEntry, &armkeyvault.AccessPolicyEntry{
212-
TenantID: to.Ptr(TenantID),
213-
ObjectID: to.Ptr(msiObjectID),
214-
Permissions: &armkeyvault.Permissions{
215-
Secrets: []*armkeyvault.SecretPermissions{
216-
to.Ptr(armkeyvault.SecretPermissionsGet),
217-
},
218-
},
219-
})
220-
}
221-
222-
return accessPolicyEntry
223-
}
224-
225-
func cleanVault(ctx context.Context, cred azcore.TokenCredential) {
226-
err := deleteVault(ctx, cred)
227-
framework.ExpectNoError(err)
228-
229-
err = purgeDeleted(ctx, cred)
230-
framework.ExpectNoError(err)
231-
}
232-
233-
func deleteVault(ctx context.Context, cred azcore.TokenCredential) error {
234-
vaultsClient, err := armkeyvault.NewVaultsClient(subscriptionID, cred, nil)
235-
if err != nil {
236-
return err
237-
}
238-
239-
_, err = vaultsClient.Delete(ctx, resourceGroupName, vaultName, nil)
240-
if err != nil {
241-
return err
242-
}
243-
return nil
244-
}
245-
246-
func purgeDeleted(ctx context.Context, cred azcore.TokenCredential) error {
247-
vaultsClient, err := armkeyvault.NewVaultsClient(subscriptionID, cred, nil)
248-
if err != nil {
249-
return err
250-
}
251-
252-
pollerResp, err := vaultsClient.BeginPurgeDeleted(ctx, vaultName, location, nil)
253-
if err != nil {
254-
return err
255-
}
256-
257-
_, err = pollerResp.PollUntilDone(ctx, nil)
258-
if err != nil {
259-
return err
260-
}
261-
262-
return nil
263-
}
264-
265-
func createSecret(ctx context.Context, cred azcore.TokenCredential, secretName, secretValue string) (*armkeyvault.Secret, error) {
266-
secretsClient, err := armkeyvault.NewSecretsClient(subscriptionID, cred, nil)
267-
if err != nil {
268-
return nil, err
269-
}
270-
271-
secretResp, err := secretsClient.CreateOrUpdate(
272-
ctx,
273-
resourceGroupName,
274-
vaultName,
275-
secretName,
276-
armkeyvault.SecretCreateOrUpdateParameters{
277-
Properties: &armkeyvault.SecretProperties{
278-
Attributes: &armkeyvault.SecretAttributes{
279-
Enabled: to.Ptr(true),
280-
},
281-
Value: to.Ptr(secretValue),
282-
},
283-
},
284-
nil,
285-
)
286-
if err != nil {
287-
return nil, err
288-
}
289-
290-
return &secretResp.Secret, nil
291-
}
292-
293-
func getServicePrincipalObjectID(ctx context.Context, clientID string) (string, error) {
294-
spClient, err := getServicePrincipalsClient()
295-
if err != nil {
296-
return "", err
297-
}
298-
299-
page, err := spClient.List(ctx, fmt.Sprintf("servicePrincipalNames/any(c:c eq '%s')", clientID))
300-
if err != nil {
301-
return "", err
302-
}
303-
servicePrincipals := page.Values()
304-
if len(servicePrincipals) == 0 {
305-
return "", fmt.Errorf("didn't find any service principals for client ID %s", clientID)
306-
}
307-
return *servicePrincipals[0].ObjectID, nil
308-
}
309-
310-
func getServicePrincipalsClient() (*graphrbac.ServicePrincipalsClient, error) {
311-
spClient := graphrbac.NewServicePrincipalsClient(TenantID)
312-
313-
env, err := azure.EnvironmentFromName(cloud)
314-
if err != nil {
315-
return nil, err
316-
}
317-
318-
oauthConfig, err := adal.NewOAuthConfig(env.ActiveDirectoryEndpoint, TenantID)
319-
if err != nil {
320-
return nil, err
321-
}
322-
323-
token, err := adal.NewServicePrincipalToken(*oauthConfig, clientID, clientSecret, env.GraphEndpoint)
324-
if err != nil {
325-
return nil, err
326-
}
327-
328-
authorizer := autorest.NewBearerAuthorizer(token)
329-
330-
spClient.Authorizer = authorizer
331-
332-
return &spClient, nil
333-
}
334-
335-
func getMSIUserAssignedIDClient() (*msi.UserAssignedIdentitiesClient, error) {
336-
msiClient := msi.NewUserAssignedIdentitiesClient(subscriptionID)
337-
338-
env, err := azure.EnvironmentFromName(cloud)
339-
if err != nil {
340-
return nil, err
341-
}
342-
343-
oauthConfig, err := adal.NewOAuthConfig(env.ActiveDirectoryEndpoint, TenantID)
344-
if err != nil {
345-
return nil, err
346-
}
347-
348-
token, err := adal.NewServicePrincipalToken(*oauthConfig, clientID, clientSecret, env.ResourceManagerEndpoint)
349-
if err != nil {
350-
return nil, err
351-
}
352-
353-
authorizer := autorest.NewBearerAuthorizer(token)
354-
355-
msiClient.Authorizer = authorizer
356-
357-
return &msiClient, nil
358-
}
359-
360-
func getMSIObjectID(ctx context.Context, identityName string) (string, error) {
361-
msiClient, err := getMSIUserAssignedIDClient()
362-
if err != nil {
363-
return "", err
364-
}
365-
366-
id, err := msiClient.Get(ctx, resourceGroupName, identityName)
367-
if err != nil {
368-
return "", err
369-
}
370-
371-
return id.UserAssignedIdentityProperties.PrincipalID.String(), err
372-
}

0 commit comments

Comments
 (0)