Skip to content

Commit

Permalink
test: use wi for e2e test
Browse files Browse the repository at this point in the history
  • Loading branch information
cvvz committed Aug 19, 2024
1 parent b471b1a commit 7deb843
Show file tree
Hide file tree
Showing 42 changed files with 49 additions and 5,964 deletions.
1 change: 0 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ require (
github.com/onsi/ginkgo/v2 v2.19.1
github.com/onsi/gomega v1.34.1
github.com/pborman/uuid v1.2.1
github.com/pelletier/go-toml v1.9.5
github.com/pkg/errors v0.9.1
github.com/satori/go.uuid v1.2.0
github.com/stretchr/testify v1.9.0
Expand Down
2 changes: 0 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -220,8 +220,6 @@ github.com/opencontainers/selinux v1.11.0 h1:+5Zbo97w3Lbmb3PeqQtpmTkMwsW5nRI3YaL
github.com/opencontainers/selinux v1.11.0/go.mod h1:E5dMC3VPuVvVHDYmi78qvhJp8+M586T4DlDRYpFkyec=
github.com/pborman/uuid v1.2.1 h1:+ZZIw58t/ozdjRaXh/3awHfmWRbzYxJoAdNJxe/3pvw=
github.com/pborman/uuid v1.2.1/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k=
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ=
github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
Expand Down
3 changes: 3 additions & 0 deletions hack/verify-examples.sh
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ rollout_and_wait() {
}

echo "begin to create deployment examples ..."

kubectl config set-context --current --namespace=default

if [ -v EXTERNAL_E2E_TEST_BLOBFUSE_v2 ]; then
echo "create blobfuse2 storage class ..."
kubectl apply -f deploy/example/storageclass-blobfuse2.yaml
Expand Down
4 changes: 4 additions & 0 deletions pkg/util/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,10 @@ func parseAzcopyJobShow(jobshow string) (AzcopyJobState, string, error) {
func GetKubeClient(kubeconfig string, kubeAPIQPS float64, kubeAPIBurst int, userAgent string) (kubernetes.Interface, error) {
var err error
var kubeCfg *rest.Config
if kubeconfig == "no-need-kubeconfig" {
klog.V(2).Infof("kubeconfig is set as no-need-kubeconfig, kubeClient will be nil")
return nil, nil
}
if kubeCfg, err = clientcmd.BuildConfigFromFlags("", kubeconfig); err != nil {
return nil, err
}
Expand Down
36 changes: 2 additions & 34 deletions test/e2e/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ package e2e

import (
"context"
"encoding/json"
"flag"
"fmt"
"log"
Expand All @@ -42,7 +41,6 @@ import (
"sigs.k8s.io/blob-csi-driver/pkg/util"
"sigs.k8s.io/blob-csi-driver/test/utils/azure"
"sigs.k8s.io/blob-csi-driver/test/utils/credentials"
"sigs.k8s.io/blob-csi-driver/test/utils/testutil"
)

const (
Expand Down Expand Up @@ -90,24 +88,11 @@ func TestE2E(t *testing.T) {
var _ = ginkgo.SynchronizedBeforeSuite(func(ctx ginkgo.SpecContext) []byte {
creds, err := credentials.CreateAzureCredentialFile()
gomega.Expect(err).NotTo(gomega.HaveOccurred())
azureClient, err := azure.GetClient(creds.Cloud, creds.SubscriptionID, creds.AADClientID, creds.TenantID, creds.AADClientSecret)
azureClient, err := azure.GetClient(creds.Cloud, creds.SubscriptionID, creds.AADClientID, creds.TenantID, creds.AADClientSecret, creds.AADFederatedTokenFile)
gomega.Expect(err).NotTo(gomega.HaveOccurred())
_, err = azureClient.EnsureResourceGroup(ctx, creds.ResourceGroup, creds.Location, nil)
gomega.Expect(err).NotTo(gomega.HaveOccurred())

if testutil.IsRunningInProw() {
// Need to login to ACR using SP credential if we are running in Prow so we can push test images.
// If running locally, user should run 'docker login' before running E2E tests
registry := os.Getenv("REGISTRY")
gomega.Expect(registry).NotTo(gomega.Equal(""))

log.Println("Attempting docker login with Azure service principal")
cmd := exec.Command("docker", "login", fmt.Sprintf("--username=%s", creds.AADClientID), fmt.Sprintf("--password=%s", creds.AADClientSecret), registry)
err = cmd.Run()
gomega.Expect(err).NotTo(gomega.HaveOccurred())
log.Println("docker login is successful")
}

// Install Azure Blob Storage CSI driver on cluster from project root
e2eBootstrap := testCmd{
command: "make",
Expand All @@ -123,25 +108,8 @@ var _ = ginkgo.SynchronizedBeforeSuite(func(ctx ginkgo.SpecContext) []byte {
endLog: "metrics service created",
}
execTestCmd([]testCmd{e2eBootstrap, createMetricsSVC})

if testutil.IsRunningInProw() {
data, err := json.Marshal(creds)
gomega.Expect(err).NotTo(gomega.HaveOccurred())
return data
}

return nil
}, func(ctx ginkgo.SpecContext, data []byte) {
if testutil.IsRunningInProw() {
creds := &credentials.Credentials{}
err := json.Unmarshal(data, creds)
gomega.Expect(err).NotTo(gomega.HaveOccurred())
// set env for azidentity.EnvironmentCredential
os.Setenv("AZURE_TENANT_ID", creds.TenantID)
os.Setenv("AZURE_CLIENT_ID", creds.AADClientID)
os.Setenv("AZURE_CLIENT_SECRET", creds.AADClientSecret)
}

// k8s.io/kubernetes/test/e2e/framework requires env KUBECONFIG to be set
// it does not fall back to defaults
if os.Getenv(kubeconfigEnvVar) == "" {
Expand Down Expand Up @@ -230,7 +198,7 @@ func execTestCmd(cmds []testCmd) {
func checkAccountCreationLeak(ctx context.Context) {
creds, err := credentials.CreateAzureCredentialFile()
gomega.Expect(err).NotTo(gomega.HaveOccurred())
azureClient, err := azure.GetClient(creds.Cloud, creds.SubscriptionID, creds.AADClientID, creds.TenantID, creds.AADClientSecret)
azureClient, err := azure.GetClient(creds.Cloud, creds.SubscriptionID, creds.AADClientID, creds.TenantID, creds.AADClientSecret, creds.AADFederatedTokenFile)
gomega.Expect(err).NotTo(gomega.HaveOccurred())

accountNum, err := azureClient.GetAccountNumByResourceGroup(ctx, creds.ResourceGroup)
Expand Down
4 changes: 2 additions & 2 deletions test/sanity/run-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ if [ ! -f "$azcopyPath" ]; then
chmod +x /usr/local/bin/azcopy
fi

_output/amd64/blobplugin --endpoint "$controllerendpoint" -v=5 &
_output/amd64/blobplugin --endpoint "$nodeendpoint" --nodeid "$nodeid" --enable-blob-mock-mount -v=5 &
_output/amd64/blobplugin --endpoint "$controllerendpoint" -v=5 --kubeconfig "no-need-kubeconfig" &
_output/amd64/blobplugin --endpoint "$nodeendpoint" --nodeid "$nodeid" --enable-blob-mock-mount -v=5 --kubeconfig "no-need-kubeconfig" &

echo "Begin to run sanity test..."
readonly CSI_SANITY_BIN='csi-sanity'
Expand Down
2 changes: 1 addition & 1 deletion test/sanity/sanity_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func TestSanity(t *testing.T) {

os.Setenv("AZURE_CREDENTIAL_FILE", credentials.TempAzureCredentialFilePath)

azureClient, err := azure.GetClient(creds.Cloud, creds.SubscriptionID, creds.AADClientID, creds.TenantID, creds.AADClientSecret)
azureClient, err := azure.GetClient(creds.Cloud, creds.SubscriptionID, creds.AADClientID, creds.TenantID, creds.AADClientSecret, creds.AADFederatedTokenFile)
assert.NoError(t, err)

ctx := context.Background()
Expand Down
12 changes: 9 additions & 3 deletions test/utils/azure/azure_helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,20 @@ type Client struct {
accountsClient accountclient.Interface
}

func GetClient(cloud, subscriptionID, clientID, tenantID, clientSecret string) (*Client, error) {
func GetClient(cloud, subscriptionID, clientID, tenantID, clientSecret string, aadFederatedTokenFile string) (*Client, error) {
armConfig := &azclient.ARMClientConfig{
Cloud: cloud,
TenantID: tenantID,
}
useFederatedWorkloadIdentityExtension := false
if aadFederatedTokenFile != "" {
useFederatedWorkloadIdentityExtension = true
}
credProvider, err := azclient.NewAuthProvider(armConfig, &azclient.AzureAuthConfig{
AADClientID: clientID,
AADClientSecret: clientSecret,
AADClientID: clientID,
AADClientSecret: clientSecret,
AADFederatedTokenFile: aadFederatedTokenFile,
UseFederatedWorkloadIdentityExtension: useFederatedWorkloadIdentityExtension,
})
if err != nil {
return nil, err
Expand Down
62 changes: 17 additions & 45 deletions test/utils/credentials/credentials.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,9 @@ import (
"encoding/json"
"fmt"
"html/template"
"log"
"os"

"sigs.k8s.io/blob-csi-driver/test/utils/testutil"

"github.com/pborman/uuid"
"github.com/pelletier/go-toml"
)

const (
Expand All @@ -41,7 +37,8 @@ const (
"aadClientId": "{{.AADClientID}}",
"aadClientSecret": "{{.AADClientSecret}}",
"resourceGroup": "{{.ResourceGroup}}",
"location": "{{.Location}}"
"location": "{{.Location}}",
"aadFederatedTokenFile": "{{.AADFederatedTokenFile}}"
}`
defaultAzurePublicCloudLocation = "eastus2"

Expand All @@ -53,6 +50,7 @@ const (
aadClientSecretEnvVar = "AZURE_CLIENT_SECRET"
resourceGroupEnvVar = "AZURE_RESOURCE_GROUP"
locationEnvVar = "AZURE_LOCATION"
federatedTokenFileVar = "AZURE_FEDERATED_TOKEN_FILE"
)

// Config is used in Prow to store Azure credentials
Expand All @@ -74,20 +72,21 @@ type FromProw struct {

// Credentials is used in Azure Blob Storage CSI driver to store Azure credentials
type Credentials struct {
Cloud string
TenantID string
SubscriptionID string
AADClientID string
AADClientSecret string
ResourceGroup string
Location string
Cloud string
TenantID string
SubscriptionID string
AADClientID string
AADClientSecret string
AADFederatedTokenFile string
ResourceGroup string
Location string
}

// CreateAzureCredentialFile creates a temporary Azure credential file for
// Azure Blob Storage CSI driver tests and returns the credentials
func CreateAzureCredentialFile() (*Credentials, error) {
// Search credentials through env vars first
var cloud, tenantID, subscriptionID, aadClientID, aadClientSecret, resourceGroup, location string
var cloud, tenantID, subscriptionID, aadClientID, aadClientSecret, resourceGroup, location, aadFederatedTokenFile string
cloud = os.Getenv(cloudNameEnvVar)
if cloud == "" {
cloud = AzurePublicCloud
Expand All @@ -98,6 +97,7 @@ func CreateAzureCredentialFile() (*Credentials, error) {
aadClientSecret = os.Getenv(aadClientSecretEnvVar)
resourceGroup = os.Getenv(resourceGroupEnvVar)
location = os.Getenv(locationEnvVar)
aadFederatedTokenFile = os.Getenv(federatedTokenFileVar)

if resourceGroup == "" {
resourceGroup = ResourceGroupPrefix + uuid.NewUUID().String()
Expand All @@ -107,20 +107,8 @@ func CreateAzureCredentialFile() (*Credentials, error) {
location = defaultAzurePublicCloudLocation
}

// Running test locally
if tenantID != "" && subscriptionID != "" && aadClientID != "" && aadClientSecret != "" {
return parseAndExecuteTemplate(cloud, tenantID, subscriptionID, aadClientID, aadClientSecret, resourceGroup, location)
}

// If the tests are being run in Prow, credentials are not supplied through env vars. Instead, it is supplied
// through env var AZURE_CREDENTIALS. We need to convert it to AZURE_CREDENTIAL_FILE for sanity, integration and E2E tests
if testutil.IsRunningInProw() {
log.Println("Running in Prow, converting AZURE_CREDENTIALS to AZURE_CREDENTIAL_FILE")
c, err := getCredentialsFromAzureCredentials(os.Getenv("AZURE_CREDENTIALS"))
if err != nil {
return nil, err
}
return parseAndExecuteTemplate(cloud, c.TenantID, c.SubscriptionID, c.ClientID, c.ClientSecret, resourceGroup, location)
if tenantID != "" && subscriptionID != "" && aadClientID != "" && (aadClientSecret != "" || aadFederatedTokenFile != "") {
return parseAndExecuteTemplate(cloud, tenantID, subscriptionID, aadClientID, aadClientSecret, aadFederatedTokenFile, resourceGroup, location)
}

return nil, fmt.Errorf("If you are running tests locally, you will need to set the following env vars: $%s, $%s, $%s, $%s, $%s, $%s",
Expand Down Expand Up @@ -152,25 +140,8 @@ func ParseAzureCredentialFile() (*Credentials, error) {
return cred, nil
}

// getCredentialsFromAzureCredentials parses the azure credentials toml (AZURE_CREDENTIALS)
// in Prow and returns the credential information usable to Azure Blob Storage CSI driver
func getCredentialsFromAzureCredentials(azureCredentialsPath string) (*FromProw, error) {
content, err := os.ReadFile(azureCredentialsPath)
log.Printf("Reading credentials file %v", azureCredentialsPath)
if err != nil {
return nil, fmt.Errorf("error reading credentials file %v %w", azureCredentialsPath, err)
}

c := Config{}
if err := toml.Unmarshal(content, &c); err != nil {
return nil, fmt.Errorf("error parsing credentials file %v %w", azureCredentialsPath, err)
}

return &c.Creds, nil
}

// parseAndExecuteTemplate replaces credential placeholders in azureCredentialFileTemplate with actual credentials
func parseAndExecuteTemplate(cloud, tenantID, subscriptionID, aadClientID, aadClientSecret, resourceGroup, location string) (*Credentials, error) {
func parseAndExecuteTemplate(cloud, tenantID, subscriptionID, aadClientID, aadClientSecret, aadFederatedTokenFile, resourceGroup, location string) (*Credentials, error) {
t := template.New("AzureCredentialFileTemplate")
t, err := t.Parse(azureCredentialFileTemplate)
if err != nil {
Expand All @@ -189,6 +160,7 @@ func parseAndExecuteTemplate(cloud, tenantID, subscriptionID, aadClientID, aadCl
subscriptionID,
aadClientID,
aadClientSecret,
aadFederatedTokenFile,
resourceGroup,
location,
}
Expand Down
Loading

0 comments on commit 7deb843

Please sign in to comment.