Merge pull request #106678 from bertinatto/azure-file-e2e

Add storage tests for Azure File in-tree storage plugin
This commit is contained in:
Kubernetes Prow Robot 2022-03-28 06:43:34 -07:00 committed by GitHub
commit 36142cc0b7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 200 additions and 2 deletions

View File

@ -21,7 +21,7 @@ import (
"os"
"sync"
"k8s.io/api/core/v1"
v1 "k8s.io/api/core/v1"
clientset "k8s.io/client-go/kubernetes"
)
@ -97,6 +97,9 @@ type ProviderInterface interface {
CreatePD(zone string) (string, error)
DeletePD(pdName string) error
CreateShare() (string, string, string, error)
DeleteShare(accountName, shareName string) error
CreatePVSource(zone, diskName string) (*v1.PersistentVolumeSource, error)
DeletePVSource(pvSource *v1.PersistentVolumeSource) error
@ -137,6 +140,14 @@ func (n NullProvider) DeleteNode(node *v1.Node) error {
return fmt.Errorf("provider does not support DeleteNode")
}
func (n NullProvider) CreateShare() (string, string, string, error) {
return "", "", "", fmt.Errorf("provider does not support volume creation")
}
func (n NullProvider) DeleteShare(accountName, shareName string) error {
return fmt.Errorf("provider does not support volume deletion")
}
// CreatePD is a base implementation which creates PD.
func (n NullProvider) CreatePD(zone string) (string, error) {
return "", fmt.Errorf("provider does not support volume creation")

View File

@ -26,7 +26,7 @@ import (
"github.com/aws/aws-sdk-go/service/autoscaling"
"github.com/aws/aws-sdk-go/service/ec2"
"k8s.io/api/core/v1"
v1 "k8s.io/api/core/v1"
"k8s.io/kubernetes/test/e2e/framework"
e2epv "k8s.io/kubernetes/test/e2e/framework/pv"
awscloud "k8s.io/legacy-cloud-providers/aws"
@ -93,6 +93,14 @@ func (p *Provider) DeleteNode(node *v1.Node) error {
return err
}
func (p *Provider) CreateShare() (string, string, string, error) {
return "", "", "", nil
}
func (p *Provider) DeleteShare(accountName, shareName string) error {
return nil
}
// CreatePD creates a persistent volume on the specified availability zone
func (p *Provider) CreatePD(zone string) (string, error) {
client := newAWSClient(zone)

View File

@ -27,6 +27,7 @@ import (
"k8s.io/apimachinery/pkg/util/uuid"
"k8s.io/kubernetes/test/e2e/framework"
"k8s.io/legacy-cloud-providers/azure"
"k8s.io/legacy-cloud-providers/azure/clients/fileclient"
)
func init() {
@ -84,6 +85,39 @@ func (p *Provider) CreatePD(zone string) (string, error) {
return p.azureCloud.CreateManagedDisk(volumeOptions)
}
// CreateShare creates a share and return its account name and key.
func (p *Provider) CreateShare() (string, string, string, error) {
accountOptions := &azure.AccountOptions{
Name: "",
Type: string(compute.StandardLRS),
ResourceGroup: p.azureCloud.ResourceGroup,
Location: p.azureCloud.GetLocation(),
EnableHTTPSTrafficOnly: true,
Tags: nil,
VirtualNetworkResourceIDs: nil,
}
shareOptions := &fileclient.ShareOptions{
Name: fmt.Sprintf("%s-%s", framework.TestContext.Prefix, string(uuid.NewUUID())),
RequestGiB: 1,
}
accountName, accountKey, err := p.azureCloud.CreateFileShare(accountOptions, shareOptions)
if err != nil {
return "", "", "", err
}
return accountName, accountKey, shareOptions.Name, nil
}
func (p *Provider) DeleteShare(accountName, shareName string) error {
err := p.azureCloud.DeleteFileShare(p.azureCloud.ResourceGroup, accountName, shareName)
if err != nil {
framework.Logf("failed to delete Azure File share %q: %v", shareName, err)
}
return err
}
// DeletePD deletes a persistent volume
func (p *Provider) DeletePD(pdName string) error {
if err := p.azureCloud.DeleteManagedDisk(pdName); err != nil {

View File

@ -225,6 +225,14 @@ func (p *Provider) DeleteNode(node *v1.Node) error {
return p.gceCloud.DeleteInstance(project, zone, node.Name)
}
func (p *Provider) CreateShare() (string, string, string, error) {
return "", "", "", nil
}
func (p *Provider) DeleteShare(accountName, shareName string) error {
return nil
}
// CreatePD creates a persistent volume
func (p *Provider) CreatePD(zone string) (string, error) {
pdName := fmt.Sprintf("%s-%s", framework.TestContext.Prefix, string(uuid.NewUUID()))

View File

@ -673,6 +673,14 @@ func createPDWithRetry(zone string) (string, error) {
return "", err
}
func CreateShare() (string, string, string, error) {
return framework.TestContext.CloudConfig.Provider.CreateShare()
}
func DeleteShare(accountName, shareName string) error {
return framework.TestContext.CloudConfig.Provider.DeleteShare(accountName, shareName)
}
// CreatePDWithRetry creates PD with retry.
func CreatePDWithRetry() (string, error) {
return createPDWithRetry("")

View File

@ -2025,3 +2025,131 @@ func cleanUpVolumeServerWithSecret(f *framework.Framework, serverPod *v1.Pod, se
framework.Logf("Server pod delete failed: %v", err)
}
}
// Azure File
type azureFileDriver struct {
driverInfo storageframework.DriverInfo
}
type azureFileVolume struct {
accountName string
shareName string
secretName string
secretNamespace string
}
var _ storageframework.TestDriver = &azureFileDriver{}
var _ storageframework.PreprovisionedVolumeTestDriver = &azureFileDriver{}
var _ storageframework.InlineVolumeTestDriver = &azureFileDriver{}
var _ storageframework.PreprovisionedPVTestDriver = &azureFileDriver{}
var _ storageframework.DynamicPVTestDriver = &azureFileDriver{}
// InitAzureFileDriver returns azureFileDriver that implements TestDriver interface
func InitAzureFileDriver() storageframework.TestDriver {
return &azureFileDriver{
driverInfo: storageframework.DriverInfo{
Name: "azure-file",
InTreePluginName: "kubernetes.io/azure-file",
MaxFileSize: storageframework.FileSizeMedium,
SupportedSizeRange: e2evolume.SizeRange{
Min: "1Gi",
},
SupportedFsType: sets.NewString(
"", // Default fsType
),
Capabilities: map[storageframework.Capability]bool{
storageframework.CapPersistence: true,
storageframework.CapExec: true,
storageframework.CapRWX: true,
storageframework.CapMultiPODs: true,
storageframework.CapControllerExpansion: true,
storageframework.CapNodeExpansion: true,
},
},
}
}
func (a *azureFileDriver) GetDriverInfo() *storageframework.DriverInfo {
return &a.driverInfo
}
func (a *azureFileDriver) SkipUnsupportedTest(pattern storageframework.TestPattern) {
e2eskipper.SkipUnlessProviderIs("azure")
}
func (a *azureFileDriver) GetVolumeSource(readOnly bool, fsType string, e2evolume storageframework.TestVolume) *v1.VolumeSource {
av, ok := e2evolume.(*azureFileVolume)
framework.ExpectEqual(ok, true, "Failed to cast test volume to Azure test volume")
volSource := v1.VolumeSource{
AzureFile: &v1.AzureFileVolumeSource{
SecretName: av.secretName,
ShareName: av.shareName,
ReadOnly: readOnly,
},
}
return &volSource
}
func (a *azureFileDriver) GetPersistentVolumeSource(readOnly bool, fsType string, e2evolume storageframework.TestVolume) (*v1.PersistentVolumeSource, *v1.VolumeNodeAffinity) {
av, ok := e2evolume.(*azureFileVolume)
framework.ExpectEqual(ok, true, "Failed to cast test volume to Azure test volume")
pvSource := v1.PersistentVolumeSource{
AzureFile: &v1.AzureFilePersistentVolumeSource{
SecretName: av.secretName,
ShareName: av.shareName,
SecretNamespace: &av.secretNamespace,
ReadOnly: readOnly,
},
}
return &pvSource, nil
}
func (a *azureFileDriver) GetDynamicProvisionStorageClass(config *storageframework.PerTestConfig, fsType string) *storagev1.StorageClass {
provisioner := "kubernetes.io/azure-file"
parameters := map[string]string{}
ns := config.Framework.Namespace.Name
immediateBinding := storagev1.VolumeBindingImmediate
return storageframework.GetStorageClass(provisioner, parameters, &immediateBinding, ns)
}
func (a *azureFileDriver) PrepareTest(f *framework.Framework) (*storageframework.PerTestConfig, func()) {
return &storageframework.PerTestConfig{
Driver: a,
Prefix: "azure-file",
Framework: f,
}, func() {}
}
func (a *azureFileDriver) CreateVolume(config *storageframework.PerTestConfig, volType storageframework.TestVolType) storageframework.TestVolume {
ginkgo.By("creating a test azure file volume")
accountName, accountKey, shareName, err := e2epv.CreateShare()
framework.ExpectNoError(err)
secretName := "azure-storage-account-" + accountName + "-secret"
secret := &v1.Secret{
ObjectMeta: metav1.ObjectMeta{
Namespace: config.Framework.Namespace.Name,
Name: secretName,
},
Data: map[string][]byte{
"azurestorageaccountname": []byte(accountName),
"azurestorageaccountkey": []byte(accountKey),
},
Type: "Opaque",
}
_, err = config.Framework.ClientSet.CoreV1().Secrets(config.Framework.Namespace.Name).Create(context.TODO(), secret, metav1.CreateOptions{})
framework.ExpectNoError(err)
return &azureFileVolume{
accountName: accountName,
shareName: shareName,
secretName: secretName,
secretNamespace: config.Framework.Namespace.Name,
}
}
func (v *azureFileVolume) DeleteVolume() {
err := e2epv.DeleteShare(v.accountName, v.shareName)
framework.ExpectNoError(err)
}

View File

@ -39,6 +39,7 @@ var testDrivers = []func() storageframework.TestDriver{
drivers.InitWindowsGcePdDriver,
drivers.InitVSphereDriver,
drivers.InitAzureDiskDriver,
drivers.InitAzureFileDriver,
drivers.InitAwsDriver,
drivers.InitLocalDriverWithVolumeType(utils.LocalVolumeDirectory),
drivers.InitLocalDriverWithVolumeType(utils.LocalVolumeDirectoryLink),