diff --git a/internal/common/client_options.go b/internal/common/client_options.go index 6eba6eeaedcc0..1b5c831b5d3b4 100644 --- a/internal/common/client_options.go +++ b/internal/common/client_options.go @@ -13,7 +13,6 @@ import ( "github.com/hashicorp/go-azure-helpers/sender" "github.com/hashicorp/go-azure-sdk/sdk/auth" "github.com/hashicorp/go-azure-sdk/sdk/client" - "github.com/hashicorp/go-azure-sdk/sdk/client/resourcemanager" "github.com/hashicorp/go-azure-sdk/sdk/environments" "github.com/hashicorp/terraform-plugin-sdk/v2/meta" "github.com/hashicorp/terraform-provider-azurerm/internal/features" @@ -66,24 +65,20 @@ type ClientOptions struct { } // Configure set up a resourcemanager.Client using an auth.Authorizer from hashicorp/go-azure-sdk -func (o ClientOptions) Configure(c *resourcemanager.Client, authorizer auth.Authorizer) { - c.Authorizer = authorizer - c.UserAgent = userAgent(c.UserAgent, o.TerraformVersion, o.PartnerId, o.DisableTerraformPartnerID) +func (o ClientOptions) Configure(c client.BaseClient, authorizer auth.Authorizer) { + c.SetAuthorizer(authorizer) + c.SetUserAgent(userAgent(c.GetUserAgent(), o.TerraformVersion, o.PartnerId, o.DisableTerraformPartnerID)) - requestMiddlewares := make([]client.RequestMiddleware, 0) if !o.DisableCorrelationRequestID { id := o.CustomCorrelationRequestID if id == "" { id = correlationRequestID() } - requestMiddlewares = append(requestMiddlewares, correlationRequestIDMiddleware(id)) + c.AppendRequestMiddleware(correlationRequestIDMiddleware(id)) } - requestMiddlewares = append(requestMiddlewares, requestLoggerMiddleware("AzureRM")) - c.RequestMiddlewares = &requestMiddlewares - c.ResponseMiddlewares = &[]client.ResponseMiddleware{ - responseLoggerMiddleware("AzureRM"), - } + c.AppendRequestMiddleware(requestLoggerMiddleware("AzureRM")) + c.AppendResponseMiddleware(responseLoggerMiddleware("AzureRM")) } // ConfigureClient sets up an autorest.Client using an autorest.Authorizer diff --git a/internal/provider/helpers.go b/internal/provider/helpers.go new file mode 100644 index 0000000000000..eb1ce774a23d3 --- /dev/null +++ b/internal/provider/helpers.go @@ -0,0 +1,128 @@ +package provider + +import ( + "encoding/base64" + "fmt" + "os" + "strings" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func decodeCertificate(clientCertificate string) ([]byte, error) { + var pfx []byte + if clientCertificate != "" { + out := make([]byte, base64.StdEncoding.DecodedLen(len(clientCertificate))) + n, err := base64.StdEncoding.Decode(out, []byte(clientCertificate)) + if err != nil { + return pfx, fmt.Errorf("could not decode client certificate data: %v", err) + } + pfx = out[:n] + } + return pfx, nil +} + +func getOidcToken(d *schema.ResourceData) (*string, error) { + idToken := strings.TrimSpace(d.Get("oidc_token").(string)) + + if path := d.Get("oidc_token_file_path").(string); path != "" { + fileTokenRaw, err := os.ReadFile(path) + + if err != nil { + return nil, fmt.Errorf("reading OIDC Token from file %q: %v", path, err) + } + + fileToken := strings.TrimSpace(string(fileTokenRaw)) + + if idToken != "" && idToken != fileToken { + return nil, fmt.Errorf("mismatch between supplied OIDC token and supplied OIDC token file contents - please either remove one or ensure they match") + } + + idToken = fileToken + } + + if d.Get("use_aks_workload_identity").(bool) && os.Getenv("AZURE_FEDERATED_TOKEN_FILE") != "" { + path := os.Getenv("AZURE_FEDERATED_TOKEN_FILE") + fileTokenRaw, err := os.ReadFile(os.Getenv("AZURE_FEDERATED_TOKEN_FILE")) + + if err != nil { + return nil, fmt.Errorf("reading OIDC Token from file %q provided by AKS Workload Identity: %v", path, err) + } + + fileToken := strings.TrimSpace(string(fileTokenRaw)) + + if idToken != "" && idToken != fileToken { + return nil, fmt.Errorf("mismatch between supplied OIDC token and OIDC token file contents provided by AKS Workload Identity - please either remove one, ensure they match, or disable use_aks_workload_identity") + } + + idToken = fileToken + } + + return &idToken, nil +} + +func getClientId(d *schema.ResourceData) (*string, error) { + clientId := strings.TrimSpace(d.Get("client_id").(string)) + + if path := d.Get("client_id_file_path").(string); path != "" { + fileClientIdRaw, err := os.ReadFile(path) + + if err != nil { + return nil, fmt.Errorf("reading Client ID from file %q: %v", path, err) + } + + fileClientId := strings.TrimSpace(string(fileClientIdRaw)) + + if clientId != "" && clientId != fileClientId { + return nil, fmt.Errorf("mismatch between supplied Client ID and supplied Client ID file contents - please either remove one or ensure they match") + } + + clientId = fileClientId + } + + if d.Get("use_aks_workload_identity").(bool) && os.Getenv("AZURE_CLIENT_ID") != "" { + aksClientId := os.Getenv("AZURE_CLIENT_ID") + if clientId != "" && clientId != aksClientId { + return nil, fmt.Errorf("mismatch between supplied Client ID and that provided by AKS Workload Identity - please remove, ensure they match, or disable use_aks_workload_identity") + } + clientId = aksClientId + } + + return &clientId, nil +} + +func getClientSecret(d *schema.ResourceData) (*string, error) { + clientSecret := strings.TrimSpace(d.Get("client_secret").(string)) + + if path := d.Get("client_secret_file_path").(string); path != "" { + fileSecretRaw, err := os.ReadFile(path) + + if err != nil { + return nil, fmt.Errorf("reading Client Secret from file %q: %v", path, err) + } + + fileSecret := strings.TrimSpace(string(fileSecretRaw)) + + if clientSecret != "" && clientSecret != fileSecret { + return nil, fmt.Errorf("mismatch between supplied Client Secret and supplied Client Secret file contents - please either remove one or ensure they match") + } + + clientSecret = fileSecret + } + + return &clientSecret, nil +} + +func getTenantId(d *schema.ResourceData) (*string, error) { + tenantId := strings.TrimSpace(d.Get("tenant_id").(string)) + + if d.Get("use_aks_workload_identity").(bool) && os.Getenv("AZURE_TENANT_ID") != "" { + aksTenantId := os.Getenv("AZURE_TENANT_ID") + if tenantId != "" && tenantId != aksTenantId { + return nil, fmt.Errorf("mismatch between supplied Tenant ID and that provided by AKS Workload Identity - please remove, ensure they match, or disable use_aks_workload_identity") + } + tenantId = aksTenantId + } + + return &tenantId, nil +} diff --git a/internal/provider/provider.go b/internal/provider/provider.go index 5c2d5fc23fe8b..4c6fbac839488 100644 --- a/internal/provider/provider.go +++ b/internal/provider/provider.go @@ -5,7 +5,6 @@ package provider import ( "context" - "encoding/base64" "fmt" "log" "os" @@ -510,124 +509,6 @@ func buildClient(ctx context.Context, p *schema.Provider, d *schema.ResourceData return client, nil } -func decodeCertificate(clientCertificate string) ([]byte, error) { - var pfx []byte - if clientCertificate != "" { - out := make([]byte, base64.StdEncoding.DecodedLen(len(clientCertificate))) - n, err := base64.StdEncoding.Decode(out, []byte(clientCertificate)) - if err != nil { - return pfx, fmt.Errorf("could not decode client certificate data: %v", err) - } - pfx = out[:n] - } - return pfx, nil -} - -func getOidcToken(d *schema.ResourceData) (*string, error) { - idToken := strings.TrimSpace(d.Get("oidc_token").(string)) - - if path := d.Get("oidc_token_file_path").(string); path != "" { - fileTokenRaw, err := os.ReadFile(path) - - if err != nil { - return nil, fmt.Errorf("reading OIDC Token from file %q: %v", path, err) - } - - fileToken := strings.TrimSpace(string(fileTokenRaw)) - - if idToken != "" && idToken != fileToken { - return nil, fmt.Errorf("mismatch between supplied OIDC token and supplied OIDC token file contents - please either remove one or ensure they match") - } - - idToken = fileToken - } - - if d.Get("use_aks_workload_identity").(bool) && os.Getenv("AZURE_FEDERATED_TOKEN_FILE") != "" { - path := os.Getenv("AZURE_FEDERATED_TOKEN_FILE") - fileTokenRaw, err := os.ReadFile(os.Getenv("AZURE_FEDERATED_TOKEN_FILE")) - - if err != nil { - return nil, fmt.Errorf("reading OIDC Token from file %q provided by AKS Workload Identity: %v", path, err) - } - - fileToken := strings.TrimSpace(string(fileTokenRaw)) - - if idToken != "" && idToken != fileToken { - return nil, fmt.Errorf("mismatch between supplied OIDC token and OIDC token file contents provided by AKS Workload Identity - please either remove one, ensure they match, or disable use_aks_workload_identity") - } - - idToken = fileToken - } - - return &idToken, nil -} - -func getClientId(d *schema.ResourceData) (*string, error) { - clientId := strings.TrimSpace(d.Get("client_id").(string)) - - if path := d.Get("client_id_file_path").(string); path != "" { - fileClientIdRaw, err := os.ReadFile(path) - - if err != nil { - return nil, fmt.Errorf("reading Client ID from file %q: %v", path, err) - } - - fileClientId := strings.TrimSpace(string(fileClientIdRaw)) - - if clientId != "" && clientId != fileClientId { - return nil, fmt.Errorf("mismatch between supplied Client ID and supplied Client ID file contents - please either remove one or ensure they match") - } - - clientId = fileClientId - } - - if d.Get("use_aks_workload_identity").(bool) && os.Getenv("AZURE_CLIENT_ID") != "" { - aksClientId := os.Getenv("AZURE_CLIENT_ID") - if clientId != "" && clientId != aksClientId { - return nil, fmt.Errorf("mismatch between supplied Client ID and that provided by AKS Workload Identity - please remove, ensure they match, or disable use_aks_workload_identity") - } - clientId = aksClientId - } - - return &clientId, nil -} - -func getClientSecret(d *schema.ResourceData) (*string, error) { - clientSecret := strings.TrimSpace(d.Get("client_secret").(string)) - - if path := d.Get("client_secret_file_path").(string); path != "" { - fileSecretRaw, err := os.ReadFile(path) - - if err != nil { - return nil, fmt.Errorf("reading Client Secret from file %q: %v", path, err) - } - - fileSecret := strings.TrimSpace(string(fileSecretRaw)) - - if clientSecret != "" && clientSecret != fileSecret { - return nil, fmt.Errorf("mismatch between supplied Client Secret and supplied Client Secret file contents - please either remove one or ensure they match") - } - - clientSecret = fileSecret - } - - return &clientSecret, nil -} - -func getTenantId(d *schema.ResourceData) (*string, error) { - tenantId := strings.TrimSpace(d.Get("tenant_id").(string)) - - if d.Get("use_aks_workload_identity").(bool) && os.Getenv("AZURE_TENANT_ID") != "" { - aksTenantId := os.Getenv("AZURE_TENANT_ID") - if tenantId != "" && tenantId != aksTenantId { - return nil, fmt.Errorf("mismatch between supplied Tenant ID and that provided by AKS Workload Identity - please remove, ensure they match, or disable use_aks_workload_identity") - } - tenantId = aksTenantId - } - - return &tenantId, nil -} - const resourceProviderRegistrationErrorFmt = `Error ensuring Resource Providers are registered. Terraform automatically attempts to register the Resource Providers it supports to diff --git a/internal/services/arckubernetes/arc_kubernetes_flux_configuration_resource.go b/internal/services/arckubernetes/arc_kubernetes_flux_configuration_resource.go index ccdac918aa825..5ec30309b0e57 100644 --- a/internal/services/arckubernetes/arc_kubernetes_flux_configuration_resource.go +++ b/internal/services/arckubernetes/arc_kubernetes_flux_configuration_resource.go @@ -239,7 +239,7 @@ func (r ArcKubernetesFluxConfigurationResource) Arguments() map[string]*pluginsd "container_id": { Type: pluginsdk.TypeString, Required: true, - ValidateFunc: storageValidate.StorageContainerDataPlaneID, + ValidateFunc: storageValidate.StorageContainerDataPlaneIDForDomainSuffix(""), // TODO need to know the storage domain suffix at schema time! }, "account_key": { @@ -570,7 +570,7 @@ func (r ArcKubernetesFluxConfigurationResource) Create() sdk.ResourceFunc { properties.Properties.Bucket, properties.Properties.ConfigurationProtectedSettings = expandBucketDefinitionModel(model.Bucket) } else if _, exists = metadata.ResourceData.GetOk("blob_storage"); exists { properties.Properties.SourceKind = pointer.To(fluxconfiguration.SourceKindTypeAzureBlob) - azureBlob, err := expandArcAzureBlobDefinitionModel(model.BlobStorage) + azureBlob, err := expandArcAzureBlobDefinitionModel(model.BlobStorage, metadata.Client.Storage.StorageDomainSuffix) if err != nil { return fmt.Errorf("expanding `blob_storage`: %+v", err) } @@ -624,7 +624,7 @@ func (r ArcKubernetesFluxConfigurationResource) Update() sdk.ResourceFunc { properties.Properties.ConfigurationProtectedSettings = nil if metadata.ResourceData.HasChange("blob_storage") { - azureBlob, err := expandArcAzureBlobDefinitionModel(model.BlobStorage) + azureBlob, err := expandArcAzureBlobDefinitionModel(model.BlobStorage, metadata.Client.Storage.StorageDomainSuffix) if err != nil { return fmt.Errorf("expanding `blob_storage`: %+v", err) } @@ -717,7 +717,7 @@ func (r ArcKubernetesFluxConfigurationResource) Read() sdk.ResourceFunc { if model := resp.Model; model != nil { if properties := model.Properties; properties != nil { - blobStorage, err := flattenArcAzureBlobDefinitionModel(properties.AzureBlob, configModel.BlobStorage) + blobStorage, err := flattenArcAzureBlobDefinitionModel(properties.AzureBlob, configModel.BlobStorage, metadata.Client.Storage.StorageDomainSuffix) if err != nil { return fmt.Errorf("flattening `blob_storage`: %+v", err) } @@ -762,7 +762,7 @@ func (r ArcKubernetesFluxConfigurationResource) Delete() sdk.ResourceFunc { } } -func expandArcAzureBlobDefinitionModel(inputList []AzureBlobDefinitionModel) (*fluxconfiguration.AzureBlobDefinition, error) { +func expandArcAzureBlobDefinitionModel(inputList []AzureBlobDefinitionModel, storageDomainSuffix string) (*fluxconfiguration.AzureBlobDefinition, error) { if len(inputList) == 0 { return nil, nil } @@ -778,7 +778,7 @@ func expandArcAzureBlobDefinitionModel(inputList []AzureBlobDefinitionModel) (*f } if input.ContainerID != "" { - id, err := parse.StorageContainerDataPlaneID(input.ContainerID) + id, err := parse.StorageContainerDataPlaneID(input.ContainerID, storageDomainSuffix) if err != nil { return nil, err } @@ -969,13 +969,13 @@ func expandRepositoryRefDefinitionModel(referenceType string, referenceValue str return &output, nil } -func flattenArcAzureBlobDefinitionModel(input *fluxconfiguration.AzureBlobDefinition, azureBlob []AzureBlobDefinitionModel) ([]AzureBlobDefinitionModel, error) { +func flattenArcAzureBlobDefinitionModel(input *fluxconfiguration.AzureBlobDefinition, azureBlob []AzureBlobDefinitionModel, storageDomainSuffix string) ([]AzureBlobDefinitionModel, error) { outputList := make([]AzureBlobDefinitionModel, 0) if input == nil { return outputList, nil } - id, err := parse.StorageContainerDataPlaneID(fmt.Sprintf("%s/%s", pointer.From(input.Url), pointer.From(input.ContainerName))) + id, err := parse.StorageContainerDataPlaneID(fmt.Sprintf("%s/%s", pointer.From(input.Url), pointer.From(input.ContainerName)), storageDomainSuffix) if err != nil { return nil, err } diff --git a/internal/services/containers/kubernetes_flux_configuration_resource.go b/internal/services/containers/kubernetes_flux_configuration_resource.go index d5b25970cdf89..2fb11f833b1f3 100644 --- a/internal/services/containers/kubernetes_flux_configuration_resource.go +++ b/internal/services/containers/kubernetes_flux_configuration_resource.go @@ -244,7 +244,7 @@ func (r KubernetesFluxConfigurationResource) Arguments() map[string]*pluginsdk.S "container_id": { Type: pluginsdk.TypeString, Required: true, - ValidateFunc: storageValidate.StorageContainerDataPlaneID, + ValidateFunc: storageValidate.StorageContainerDataPlaneIDForDomainSuffix(""), // TODO need to know the storage domain suffix at schema time! }, "account_key": { @@ -589,7 +589,7 @@ func (r KubernetesFluxConfigurationResource) Create() sdk.ResourceFunc { properties.Properties.Bucket, properties.Properties.ConfigurationProtectedSettings = expandBucketDefinitionModel(model.Bucket) } else if _, exists = metadata.ResourceData.GetOk("blob_storage"); exists { properties.Properties.SourceKind = pointer.To(fluxconfiguration.SourceKindTypeAzureBlob) - azureBlob, err := expandAzureBlobDefinitionModel(model.BlobStorage) + azureBlob, err := expandAzureBlobDefinitionModel(model.BlobStorage, metadata.Client.Storage.StorageDomainSuffix) if err != nil { return fmt.Errorf("expanding `blob_storage`: %+v", err) } @@ -643,7 +643,7 @@ func (r KubernetesFluxConfigurationResource) Update() sdk.ResourceFunc { properties.Properties.ConfigurationProtectedSettings = nil if metadata.ResourceData.HasChange("blob_storage") { - azureBlob, err := expandAzureBlobDefinitionModel(model.BlobStorage) + azureBlob, err := expandAzureBlobDefinitionModel(model.BlobStorage, metadata.Client.Storage.StorageDomainSuffix) if err != nil { return fmt.Errorf("expanding `blob_storage`: %+v", err) } @@ -735,7 +735,7 @@ func (r KubernetesFluxConfigurationResource) Read() sdk.ResourceFunc { if model := resp.Model; model != nil { if properties := model.Properties; properties != nil { - blobStorage, err := flattenAzureBlobDefinitionModel(properties.AzureBlob, configModel.BlobStorage) + blobStorage, err := flattenAzureBlobDefinitionModel(properties.AzureBlob, configModel.BlobStorage, metadata.Client.Storage.StorageDomainSuffix) if err != nil { return fmt.Errorf("flattening `blob_storage`: %+v", err) } @@ -780,7 +780,7 @@ func (r KubernetesFluxConfigurationResource) Delete() sdk.ResourceFunc { } } -func expandAzureBlobDefinitionModel(inputList []AzureBlobDefinitionModel) (*fluxconfiguration.AzureBlobDefinition, error) { +func expandAzureBlobDefinitionModel(inputList []AzureBlobDefinitionModel, storageDomainSuffix string) (*fluxconfiguration.AzureBlobDefinition, error) { if len(inputList) == 0 { return nil, nil } @@ -797,7 +797,7 @@ func expandAzureBlobDefinitionModel(inputList []AzureBlobDefinitionModel) (*flux } if input.ContainerID != "" { - id, err := parse.StorageContainerDataPlaneID(input.ContainerID) + id, err := parse.StorageContainerDataPlaneID(input.ContainerID, storageDomainSuffix) if err != nil { return nil, err } @@ -1002,13 +1002,13 @@ func expandRepositoryRefDefinitionModel(referenceType string, referenceValue str return &output, nil } -func flattenAzureBlobDefinitionModel(input *fluxconfiguration.AzureBlobDefinition, azureBlob []AzureBlobDefinitionModel) ([]AzureBlobDefinitionModel, error) { +func flattenAzureBlobDefinitionModel(input *fluxconfiguration.AzureBlobDefinition, azureBlob []AzureBlobDefinitionModel, storageDomainSuffix string) ([]AzureBlobDefinitionModel, error) { outputList := make([]AzureBlobDefinitionModel, 0) if input == nil { return outputList, nil } - id, err := parse.StorageContainerDataPlaneID(fmt.Sprintf("%s/%s", pointer.From(input.Url), pointer.From(input.ContainerName))) + id, err := parse.StorageContainerDataPlaneID(fmt.Sprintf("%s/%s", pointer.From(input.Url), pointer.From(input.ContainerName)), storageDomainSuffix) if err != nil { return nil, err } diff --git a/internal/services/legacy/virtual_machine_resource.go b/internal/services/legacy/virtual_machine_resource.go index e1d7d72e3e377..a1fb4be0c7522 100644 --- a/internal/services/legacy/virtual_machine_resource.go +++ b/internal/services/legacy/virtual_machine_resource.go @@ -30,7 +30,7 @@ import ( "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" "github.com/hashicorp/terraform-provider-azurerm/internal/timeouts" "github.com/hashicorp/terraform-provider-azurerm/utils" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs" "github.com/tombuildsstuff/kermit/sdk/compute/2023-03-01/compute" "github.com/tombuildsstuff/kermit/sdk/network/2022-07-01/network" ) @@ -1033,24 +1033,24 @@ func resourceVirtualMachineDeleteVhd(ctx context.Context, storageClient *intStor } uri := *vhd.URI - id, err := blobs.ParseResourceID(uri) + id, err := blobs.ParseBlobID(uri, storageClient.StorageDomainSuffix) if err != nil { return fmt.Errorf("parsing %q: %s", uri, err) } - account, err := storageClient.FindAccount(ctx, id.AccountName) + account, err := storageClient.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Blob %q (Container %q): %s", id.AccountName, id.BlobName, id.ContainerName, err) + return fmt.Errorf("retrieving Account %q for Blob %q (Container %q): %s", id.AccountId.AccountName, id.BlobName, id.ContainerName, err) } if account == nil { - return fmt.Errorf("Unable to locate Storage Account %q (Disk %q)!", id.AccountName, uri) + return fmt.Errorf("Unable to locate Storage Account %q (Disk %q)!", id.AccountId.AccountName, uri) } if err != nil { return fmt.Errorf("building Blobs Client: %s", err) } - blobsClient, err := storageClient.BlobsClient(ctx, *account) + blobsClient, err := storageClient.BlobsDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { return fmt.Errorf("building Blobs Client: %s", err) } @@ -1058,8 +1058,8 @@ func resourceVirtualMachineDeleteVhd(ctx context.Context, storageClient *intStor input := blobs.DeleteInput{ DeleteSnapshots: false, } - if _, err := blobsClient.Delete(ctx, id.AccountName, id.ContainerName, id.BlobName, input); err != nil { - return fmt.Errorf("deleting Blob %q (Container %q / Account %q / Resource Group %q): %s", id.BlobName, id.ContainerName, id.AccountName, account.ResourceGroup, err) + if _, err := blobsClient.Delete(ctx, id.ContainerName, id.BlobName, input); err != nil { + return fmt.Errorf("deleting Blob %q (Container %q / Account %q / Resource Group %q): %s", id.BlobName, id.ContainerName, id.AccountId.AccountName, account.ResourceGroup, err) } return nil diff --git a/internal/services/legacy/virtual_machine_resource_test.go b/internal/services/legacy/virtual_machine_resource_test.go index 656633a55ee08..edf31b377ed5c 100644 --- a/internal/services/legacy/virtual_machine_resource_test.go +++ b/internal/services/legacy/virtual_machine_resource_test.go @@ -8,13 +8,14 @@ import ( "fmt" "testing" + "github.com/hashicorp/go-azure-helpers/lang/response" "github.com/hashicorp/go-azure-helpers/resourcemanager/commonids" "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance" "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/utils" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs" ) type VirtualMachineResource struct{} @@ -249,15 +250,15 @@ func (VirtualMachineResource) unmanagedDiskExistsInContainer(blobName string, sh return fmt.Errorf("Unable to locate Storage Account %q!", accountName) } - client, err := clients.Storage.BlobsClient(ctx, *account) + client, err := clients.Storage.BlobsDataPlaneClient(ctx, *account, clients.Storage.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { return fmt.Errorf("building Blobs Client: %s", err) } input := blobs.GetPropertiesInput{} - props, err := client.GetProperties(ctx, accountName, containerName, blobName, input) + props, err := client.GetProperties(ctx, containerName, blobName, input) if err != nil { - if utils.ResponseWasNotFound(props.Response) { + if response.WasNotFound(props.HttpResponse) { if !shouldExist { return nil } diff --git a/internal/services/storage/blobs.go b/internal/services/storage/blobs.go index 116c69ad9445e..70e59082642ba 100644 --- a/internal/services/storage/blobs.go +++ b/internal/services/storage/blobs.go @@ -14,14 +14,11 @@ import ( "runtime" "strings" "sync" - "time" "github.com/hashicorp/terraform-provider-azurerm/utils" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs" ) -const pollingInterval = time.Second * 15 - type BlobUpload struct { Client *blobs.Client @@ -96,7 +93,7 @@ func (sbu BlobUpload) copy(ctx context.Context) error { CopySource: sbu.SourceUri, MetaData: sbu.MetaData, } - if err := sbu.Client.CopyAndWait(ctx, sbu.AccountName, sbu.ContainerName, sbu.BlobName, input, pollingInterval); err != nil { + if err := sbu.Client.CopyAndWait(ctx, sbu.ContainerName, sbu.BlobName, input); err != nil { return fmt.Errorf("copy/waiting: %s", err) } @@ -108,7 +105,7 @@ func (sbu BlobUpload) createEmptyAppendBlob(ctx context.Context) error { ContentType: utils.String(sbu.ContentType), MetaData: sbu.MetaData, } - if _, err := sbu.Client.PutAppendBlob(ctx, sbu.AccountName, sbu.ContainerName, sbu.BlobName, input); err != nil { + if _, err := sbu.Client.PutAppendBlob(ctx, sbu.ContainerName, sbu.BlobName, input); err != nil { return fmt.Errorf("PutAppendBlob: %s", err) } @@ -124,7 +121,7 @@ func (sbu BlobUpload) createEmptyBlockBlob(ctx context.Context) error { ContentType: utils.String(sbu.ContentType), MetaData: sbu.MetaData, } - if _, err := sbu.Client.PutBlockBlob(ctx, sbu.AccountName, sbu.ContainerName, sbu.BlobName, input); err != nil { + if _, err := sbu.Client.PutBlockBlob(ctx, sbu.ContainerName, sbu.BlobName, input); err != nil { return fmt.Errorf("PutBlockBlob: %s", err) } @@ -161,7 +158,7 @@ func (sbu BlobUpload) uploadBlockBlob(ctx context.Context) error { if sbu.ContentMD5 != "" { input.ContentMD5 = utils.String(sbu.ContentMD5) } - if err := sbu.Client.PutBlockBlobFromFile(ctx, sbu.AccountName, sbu.ContainerName, sbu.BlobName, file, input); err != nil { + if err := sbu.Client.PutBlockBlobFromFile(ctx, sbu.ContainerName, sbu.BlobName, file, input); err != nil { return fmt.Errorf("PutBlockBlobFromFile: %s", err) } @@ -178,7 +175,7 @@ func (sbu BlobUpload) createEmptyPageBlob(ctx context.Context) error { ContentType: utils.String(sbu.ContentType), MetaData: sbu.MetaData, } - if _, err := sbu.Client.PutPageBlob(ctx, sbu.AccountName, sbu.ContainerName, sbu.BlobName, input); err != nil { + if _, err := sbu.Client.PutPageBlob(ctx, sbu.ContainerName, sbu.BlobName, input); err != nil { return fmt.Errorf("PutPageBlob: %s", err) } @@ -228,7 +225,7 @@ func (sbu BlobUpload) uploadPageBlob(ctx context.Context) error { ContentType: utils.String(sbu.ContentType), MetaData: sbu.MetaData, } - if _, err := sbu.Client.PutPageBlob(ctx, sbu.AccountName, sbu.ContainerName, sbu.BlobName, input); err != nil { + if _, err := sbu.Client.PutPageBlob(ctx, sbu.ContainerName, sbu.BlobName, input); err != nil { return fmt.Errorf("PutPageBlob: %s", err) } @@ -373,7 +370,7 @@ func (sbu BlobUpload) blobPageUploadWorker(ctx context.Context, uploadCtx blobPa Content: chunk, } - if _, err := sbu.Client.PutPageUpdate(ctx, sbu.AccountName, sbu.ContainerName, sbu.BlobName, input); err != nil { + if _, err := sbu.Client.PutPageUpdate(ctx, sbu.ContainerName, sbu.BlobName, input); err != nil { uploadCtx.errors <- fmt.Errorf("writing page at offset %d for file %q: %s", page.offset, sbu.Source, err) uploadCtx.wg.Done() continue diff --git a/internal/services/storage/client/client.go b/internal/services/storage/client/client.go index 199f0dbbfc56c..bcd5750ee6907 100644 --- a/internal/services/storage/client/client.go +++ b/internal/services/storage/client/client.go @@ -4,61 +4,63 @@ package client import ( - "context" "fmt" "github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2021-09-01/storage" // nolint: staticcheck - "github.com/Azure/go-autorest/autorest" "github.com/Azure/go-autorest/autorest/azure" storage_v2023_01_01 "github.com/hashicorp/go-azure-sdk/resource-manager/storage/2023-01-01" "github.com/hashicorp/go-azure-sdk/resource-manager/storagesync/2020-03-01/cloudendpointresource" "github.com/hashicorp/go-azure-sdk/resource-manager/storagesync/2020-03-01/storagesyncservicesresource" "github.com/hashicorp/go-azure-sdk/resource-manager/storagesync/2020-03-01/syncgroupresource" + "github.com/hashicorp/go-azure-sdk/sdk/auth" "github.com/hashicorp/go-azure-sdk/sdk/client/resourcemanager" "github.com/hashicorp/terraform-provider-azurerm/internal/common" - "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/shim" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths" ) type Client struct { - AccountsClient *storage.AccountsClient - FileSystemsClient *filesystems.Client + SubscriptionId string + ADLSGen2PathsClient *paths.Client - BlobServicesClient *storage.BlobServicesClient + AccountsClient *storage.AccountsClient BlobInventoryPoliciesClient *storage.BlobInventoryPoliciesClient + BlobServicesClient *storage.BlobServicesClient EncryptionScopesClient *storage.EncryptionScopesClient - Environment azure.Environment FileServicesClient *storage.FileServicesClient + FileSystemsClient *filesystems.Client SyncCloudEndpointsClient *cloudendpointresource.CloudEndpointResourceClient - SyncServiceClient *storagesyncservicesresource.StorageSyncServicesResourceClient SyncGroupsClient *syncgroupresource.SyncGroupResourceClient - SubscriptionId string + SyncServiceClient *storagesyncservicesresource.StorageSyncServicesResourceClient ResourceManager *storage_v2023_01_01.Client - resourceManagerAuthorizer autorest.Authorizer - storageAdAuth *autorest.Authorizer + AzureEnvironment azure.Environment + StorageDomainSuffix string + + authorizerForAad auth.Authorizer } func NewClient(o *common.ClientOptions) (*Client, error) { + storageSuffix, ok := o.Environment.Storage.DomainSuffix() + if !ok { + return nil, fmt.Errorf("determining domain suffix for storage in environment: %s", o.Environment.Name) + } + accountsClient := storage.NewAccountsClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) o.ConfigureClient(&accountsClient.Client, o.ResourceManagerAuthorizer) - fileSystemsClient := filesystems.NewWithEnvironment(o.AzureEnvironment) - o.ConfigureClient(&fileSystemsClient.Client, o.StorageAuthorizer) + fileSystemsClient, err := filesystems.NewWithBaseUri(*storageSuffix) + if err != nil { + return nil, fmt.Errorf("building Data Lake Store Filesystems client: %+v", err) + } + o.Configure(fileSystemsClient.Client, o.Authorizers.Storage) - adlsGen2PathsClient := paths.NewWithEnvironment(o.AzureEnvironment) - o.ConfigureClient(&adlsGen2PathsClient.Client, o.StorageAuthorizer) + adlsGen2PathsClient, err := paths.NewWithBaseUri(*storageSuffix) + if err != nil { + return nil, fmt.Errorf("building Data Lake Storage Path client: %+v", err) + } + o.Configure(adlsGen2PathsClient.Client, o.Authorizers.Storage) blobServicesClient := storage.NewBlobServicesClientWithBaseURI(o.ResourceManagerEndpoint, o.SubscriptionId) o.ConfigureClient(&blobServicesClient.Client, o.ResourceManagerAuthorizer) @@ -100,12 +102,11 @@ func NewClient(o *common.ClientOptions) (*Client, error) { // (which should fix #2977) when the storage clients have been moved in here client := Client{ AccountsClient: &accountsClient, - FileSystemsClient: &fileSystemsClient, - ADLSGen2PathsClient: &adlsGen2PathsClient, + FileSystemsClient: fileSystemsClient, + ADLSGen2PathsClient: adlsGen2PathsClient, BlobServicesClient: &blobServicesClient, BlobInventoryPoliciesClient: &blobInventoryPoliciesClient, EncryptionScopesClient: &encryptionScopesClient, - Environment: o.AzureEnvironment, FileServicesClient: &fileServicesClient, ResourceManager: resourceManager, SubscriptionId: o.SubscriptionId, @@ -113,195 +114,13 @@ func NewClient(o *common.ClientOptions) (*Client, error) { SyncServiceClient: syncServiceClient, SyncGroupsClient: syncGroupsClient, - resourceManagerAuthorizer: o.ResourceManagerAuthorizer, + AzureEnvironment: o.AzureEnvironment, + StorageDomainSuffix: *storageSuffix, } if o.StorageUseAzureAD { - client.storageAdAuth = &o.StorageAuthorizer + client.authorizerForAad = o.Authorizers.Storage } return &client, nil } - -func (client Client) AccountsDataPlaneClient(ctx context.Context, account accountDetails) (*accounts.Client, error) { - if client.storageAdAuth != nil { - accountsClient := accounts.NewWithEnvironment(client.Environment) - accountsClient.Client.Authorizer = *client.storageAdAuth - return &accountsClient, nil - } - - accountKey, err := account.AccountKey(ctx, client) - if err != nil { - return nil, fmt.Errorf("retrieving Account Key: %s", err) - } - - storageAuth, err := autorest.NewSharedKeyAuthorizer(account.name, *accountKey, autorest.SharedKey) - if err != nil { - return nil, fmt.Errorf("building Authorizer: %+v", err) - } - - accountsClient := accounts.NewWithEnvironment(client.Environment) - accountsClient.Client.Authorizer = storageAuth - return &accountsClient, nil -} - -func (client Client) BlobsClient(ctx context.Context, account accountDetails) (*blobs.Client, error) { - if client.storageAdAuth != nil { - blobsClient := blobs.NewWithEnvironment(client.Environment) - blobsClient.Client.Authorizer = *client.storageAdAuth - return &blobsClient, nil - } - - accountKey, err := account.AccountKey(ctx, client) - if err != nil { - return nil, fmt.Errorf("retrieving Account Key: %s", err) - } - - storageAuth, err := autorest.NewSharedKeyAuthorizer(account.name, *accountKey, autorest.SharedKey) - if err != nil { - return nil, fmt.Errorf("building Authorizer: %+v", err) - } - - blobsClient := blobs.NewWithEnvironment(client.Environment) - blobsClient.Client.Authorizer = storageAuth - return &blobsClient, nil -} - -func (client Client) ContainersClient(ctx context.Context, account accountDetails) (shim.StorageContainerWrapper, error) { - if client.storageAdAuth != nil { - containersClient := containers.NewWithEnvironment(client.Environment) - containersClient.Client.Authorizer = *client.storageAdAuth - shim := shim.NewDataPlaneStorageContainerWrapper(&containersClient) - return shim, nil - } - - accountKey, err := account.AccountKey(ctx, client) - if err != nil { - return nil, fmt.Errorf("retrieving Account Key: %s", err) - } - - storageAuth, err := autorest.NewSharedKeyAuthorizer(account.name, *accountKey, autorest.SharedKey) - if err != nil { - return nil, fmt.Errorf("building Authorizer: %+v", err) - } - - containersClient := containers.NewWithEnvironment(client.Environment) - containersClient.Client.Authorizer = storageAuth - - shim := shim.NewDataPlaneStorageContainerWrapper(&containersClient) - return shim, nil -} - -func (client Client) FileShareDirectoriesClient(ctx context.Context, account accountDetails) (*directories.Client, error) { - // NOTE: Files do not support AzureAD Authentication - - accountKey, err := account.AccountKey(ctx, client) - if err != nil { - return nil, fmt.Errorf("retrieving Account Key: %s", err) - } - - storageAuth, err := autorest.NewSharedKeyAuthorizer(account.name, *accountKey, autorest.SharedKeyLite) - if err != nil { - return nil, fmt.Errorf("building Authorizer: %+v", err) - } - - directoriesClient := directories.NewWithEnvironment(client.Environment) - directoriesClient.Client.Authorizer = storageAuth - return &directoriesClient, nil -} - -func (client Client) FileShareFilesClient(ctx context.Context, account accountDetails) (*files.Client, error) { - // NOTE: Files do not support AzureAD Authentication - - accountKey, err := account.AccountKey(ctx, client) - if err != nil { - return nil, fmt.Errorf("retrieving Account Key: %s", err) - } - - storageAuth, err := autorest.NewSharedKeyAuthorizer(account.name, *accountKey, autorest.SharedKeyLite) - if err != nil { - return nil, fmt.Errorf("building Authorizer: %+v", err) - } - - filesClient := files.NewWithEnvironment(client.Environment) - filesClient.Client.Authorizer = storageAuth - return &filesClient, nil -} - -func (client Client) FileSharesClient(ctx context.Context, account accountDetails) (shim.StorageShareWrapper, error) { - // NOTE: Files do not support AzureAD Authentication - - accountKey, err := account.AccountKey(ctx, client) - if err != nil { - return nil, fmt.Errorf("retrieving Account Key: %s", err) - } - - storageAuth, err := autorest.NewSharedKeyAuthorizer(account.name, *accountKey, autorest.SharedKeyLite) - if err != nil { - return nil, fmt.Errorf("building Authorizer: %+v", err) - } - - sharesClient := shares.NewWithEnvironment(client.Environment) - sharesClient.Client.Authorizer = storageAuth - shim := shim.NewDataPlaneStorageShareWrapper(&sharesClient) - return shim, nil -} - -func (client Client) QueuesClient(ctx context.Context, account accountDetails) (shim.StorageQueuesWrapper, error) { - if client.storageAdAuth != nil { - queueClient := queues.NewWithEnvironment(client.Environment) - queueClient.Client.Authorizer = *client.storageAdAuth - return shim.NewDataPlaneStorageQueueWrapper(&queueClient), nil - } - - accountKey, err := account.AccountKey(ctx, client) - if err != nil { - return nil, fmt.Errorf("retrieving Account Key: %s", err) - } - - storageAuth, err := autorest.NewSharedKeyAuthorizer(account.name, *accountKey, autorest.SharedKeyLite) - if err != nil { - return nil, fmt.Errorf("building Authorizer: %+v", err) - } - - queuesClient := queues.NewWithEnvironment(client.Environment) - queuesClient.Client.Authorizer = storageAuth - return shim.NewDataPlaneStorageQueueWrapper(&queuesClient), nil -} - -func (client Client) TableEntityClient(ctx context.Context, account accountDetails) (*entities.Client, error) { - // NOTE: Table Entity does not support AzureAD Authentication - - accountKey, err := account.AccountKey(ctx, client) - if err != nil { - return nil, fmt.Errorf("retrieving Account Key: %s", err) - } - - storageAuth, err := autorest.NewSharedKeyAuthorizer(account.name, *accountKey, autorest.SharedKeyLiteForTable) - if err != nil { - return nil, fmt.Errorf("building Authorizer: %+v", err) - } - - entitiesClient := entities.NewWithEnvironment(client.Environment) - entitiesClient.Client.Authorizer = storageAuth - return &entitiesClient, nil -} - -func (client Client) TablesClient(ctx context.Context, account accountDetails) (shim.StorageTableWrapper, error) { - // NOTE: Tables do not support AzureAD Authentication - - accountKey, err := account.AccountKey(ctx, client) - if err != nil { - return nil, fmt.Errorf("retrieving Account Key: %s", err) - } - - storageAuth, err := autorest.NewSharedKeyAuthorizer(account.name, *accountKey, autorest.SharedKeyLiteForTable) - if err != nil { - return nil, fmt.Errorf("building Authorizer: %+v", err) - } - - tablesClient := tables.NewWithEnvironment(client.Environment) - tablesClient.Client.Authorizer = storageAuth - shim := shim.NewDataPlaneStorageTableWrapper(&tablesClient) - return shim, nil -} diff --git a/internal/services/storage/client/data_plane.go b/internal/services/storage/client/data_plane.go new file mode 100644 index 0000000000000..740d778b16583 --- /dev/null +++ b/internal/services/storage/client/data_plane.go @@ -0,0 +1,299 @@ +package client + +import ( + "context" + "fmt" + "strings" + + "github.com/hashicorp/go-azure-sdk/sdk/auth" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/shim" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables" +) + +type DataPlaneOperation struct { + SupportsAadAuthentication bool + SupportsSharedKeyAuthentication bool +} + +type EndpointType string + +const ( + EndpointTypeBlob = "blob" + EndpointTypeFile = "file" + EndpointTypeQueue = "queue" + EndpointTypeTable = "table" +) + +func dataPlaneEndpoint(account accountDetails, endpointType EndpointType) (*string, error) { + if account.Properties == nil { + return nil, fmt.Errorf("storage account %q has no properties", account.name) + } + if account.Properties.PrimaryEndpoints == nil { + return nil, fmt.Errorf("storage account %q has missing endpoints", account.name) + } + + var baseUri string + + switch endpointType { + case EndpointTypeBlob: + if account.Properties.PrimaryEndpoints.Blob != nil { + baseUri = strings.TrimSuffix(*account.Properties.PrimaryEndpoints.Blob, "/") + } + case EndpointTypeFile: + if account.Properties.PrimaryEndpoints.File != nil { + baseUri = strings.TrimSuffix(*account.Properties.PrimaryEndpoints.File, "/") + } + case EndpointTypeQueue: + if account.Properties.PrimaryEndpoints.Queue != nil { + baseUri = strings.TrimSuffix(*account.Properties.PrimaryEndpoints.Queue, "/") + } + case EndpointTypeTable: + if account.Properties.PrimaryEndpoints.Table != nil { + baseUri = strings.TrimSuffix(*account.Properties.PrimaryEndpoints.Table, "/") + } + default: + return nil, fmt.Errorf("internal-error: unrecognised endpoint type %q when building storage client", endpointType) + } + + if baseUri == "" { + return nil, fmt.Errorf("determining storage account %s endpoint for : %q", endpointType, account.name) + } + + return &baseUri, nil +} + +func (Client) DataPlaneOperationSupportingAnyAuthMethod() DataPlaneOperation { + return DataPlaneOperation{ + SupportsAadAuthentication: true, + SupportsSharedKeyAuthentication: true, + } +} + +func (Client) DataPlaneOperationSupportingOnlySharedKeyAuth() DataPlaneOperation { + return DataPlaneOperation{ + SupportsAadAuthentication: false, + SupportsSharedKeyAuthentication: true, + } +} + +func (client Client) ConfigureDataPlane(ctx context.Context, baseUri, clientName string, baseClient client.BaseClient, account accountDetails, operation DataPlaneOperation) error { + if operation.SupportsAadAuthentication && client.authorizerForAad != nil { + baseClient.SetAuthorizer(client.authorizerForAad) + return nil + } + + if operation.SupportsSharedKeyAuthentication { + accountKey, err := account.AccountKey(ctx, client) + if err != nil { + return fmt.Errorf("retrieving Storage Account Key: %s", err) + } + + storageAuth, err := auth.NewSharedKeyAuthorizer(account.name, *accountKey, auth.SharedKey) + if err != nil { + return fmt.Errorf("building Shared Key Authorizer for %s client: %+v", clientName, err) + } + + baseClient.SetAuthorizer(storageAuth) + return nil + } + + return fmt.Errorf("building %s client: no configured authentication types are supported", clientName) +} + +func (client Client) AccountsDataPlaneClient(ctx context.Context, account accountDetails, operation DataPlaneOperation) (*accounts.Client, error) { + const clientName = "Blob Storage Accounts" + + baseUri, err := dataPlaneEndpoint(account, EndpointTypeBlob) + if err != nil { + return nil, err + } + + apiClient, err := accounts.NewWithBaseUri(*baseUri) + if err != nil { + return nil, fmt.Errorf("building %s client: %+v", clientName, err) + } + + err = client.ConfigureDataPlane(ctx, *baseUri, clientName, apiClient.Client, account, operation) + if err != nil { + return nil, err + } + + return apiClient, nil +} + +func (client Client) BlobsDataPlaneClient(ctx context.Context, account accountDetails, operation DataPlaneOperation) (*blobs.Client, error) { + const clientName = "Blob Storage Blobs" + + baseUri, err := dataPlaneEndpoint(account, EndpointTypeBlob) + if err != nil { + return nil, err + } + + apiClient, err := blobs.NewWithBaseUri(*baseUri) + if err != nil { + return nil, fmt.Errorf("building %s client: %+v", clientName, err) + } + + err = client.ConfigureDataPlane(ctx, *baseUri, clientName, apiClient.Client, account, operation) + if err != nil { + return nil, err + } + + return apiClient, nil +} + +func (client Client) ContainersDataPlaneClient(ctx context.Context, account accountDetails, operation DataPlaneOperation) (shim.StorageContainerWrapper, error) { + const clientName = "Blob Storage Containers" + + baseUri, err := dataPlaneEndpoint(account, EndpointTypeBlob) + if err != nil { + return nil, err + } + + apiClient, err := containers.NewWithBaseUri(*baseUri) + if err != nil { + return nil, fmt.Errorf("building %s client: %+v", clientName, err) + } + + err = client.ConfigureDataPlane(ctx, *baseUri, clientName, apiClient.Client, account, operation) + if err != nil { + return nil, err + } + + return shim.NewDataPlaneStorageContainerWrapper(apiClient), nil +} + +func (client Client) FileShareDirectoriesDataPlaneClient(ctx context.Context, account accountDetails, operation DataPlaneOperation) (*directories.Client, error) { + const clientName = "File Storage Shares" + + baseUri, err := dataPlaneEndpoint(account, EndpointTypeFile) + if err != nil { + return nil, err + } + + apiClient, err := directories.NewWithBaseUri(*baseUri) + if err != nil { + return nil, fmt.Errorf("building %s client: %+v", clientName, err) + } + + err = client.ConfigureDataPlane(ctx, *baseUri, clientName, apiClient.Client, account, operation) + if err != nil { + return nil, err + } + + return apiClient, nil +} + +func (client Client) FileShareFilesDataPlaneClient(ctx context.Context, account accountDetails, operation DataPlaneOperation) (*files.Client, error) { + const clientName = "File Storage Share Files" + + baseUri, err := dataPlaneEndpoint(account, EndpointTypeFile) + if err != nil { + return nil, err + } + + apiClient, err := files.NewWithBaseUri(*baseUri) + if err != nil { + return nil, fmt.Errorf("building %s client: %+v", clientName, err) + } + + err = client.ConfigureDataPlane(ctx, *baseUri, clientName, apiClient.Client, account, operation) + if err != nil { + return nil, err + } + + return apiClient, nil +} + +func (client Client) FileSharesDataPlaneClient(ctx context.Context, account accountDetails, operation DataPlaneOperation) (shim.StorageShareWrapper, error) { + const clientName = "File Storage Share Shares" + + baseUri, err := dataPlaneEndpoint(account, EndpointTypeFile) + if err != nil { + return nil, err + } + + apiClient, err := shares.NewWithBaseUri(*baseUri) + if err != nil { + return nil, fmt.Errorf("building %s client: %+v", clientName, err) + } + + err = client.ConfigureDataPlane(ctx, *baseUri, clientName, apiClient.Client, account, operation) + if err != nil { + return nil, err + } + + return shim.NewDataPlaneStorageShareWrapper(apiClient), nil +} + +func (client Client) QueuesDataPlaneClient(ctx context.Context, account accountDetails, operation DataPlaneOperation) (shim.StorageQueuesWrapper, error) { + const clientName = "File Storage Queue Queues" + + baseUri, err := dataPlaneEndpoint(account, EndpointTypeQueue) + if err != nil { + return nil, err + } + + apiClient, err := queues.NewWithBaseUri(*baseUri) + if err != nil { + return nil, fmt.Errorf("building %s client: %+v", clientName, err) + } + + err = client.ConfigureDataPlane(ctx, *baseUri, clientName, apiClient.Client, account, operation) + if err != nil { + return nil, err + } + + return shim.NewDataPlaneStorageQueueWrapper(apiClient), nil +} + +func (client Client) TableEntityDataPlaneClient(ctx context.Context, account accountDetails, operation DataPlaneOperation) (*entities.Client, error) { + const clientName = "Table Storage Share Entities" + + baseUri, err := dataPlaneEndpoint(account, EndpointTypeTable) + if err != nil { + return nil, err + } + + apiClient, err := entities.NewWithBaseUri(*baseUri) + if err != nil { + return nil, fmt.Errorf("building %s client: %+v", clientName, err) + } + + err = client.ConfigureDataPlane(ctx, *baseUri, clientName, apiClient.Client, account, operation) + if err != nil { + return nil, err + } + + return apiClient, nil +} + +func (client Client) TablesDataPlaneClient(ctx context.Context, account accountDetails, operation DataPlaneOperation) (shim.StorageTableWrapper, error) { + const clientName = "Table Storage Share Tables" + + baseUri, err := dataPlaneEndpoint(account, EndpointTypeFile) + if err != nil { + return nil, err + } + + apiClient, err := tables.NewWithBaseUri(*baseUri) + if err != nil { + return nil, fmt.Errorf("building %s client: %+v", clientName, err) + } + + err = client.ConfigureDataPlane(ctx, *baseUri, clientName, apiClient.Client, account, operation) + if err != nil { + return nil, err + } + + return shim.NewDataPlaneStorageTableWrapper(apiClient), nil +} diff --git a/internal/services/storage/helpers/schema.go b/internal/services/storage/helpers/schema.go new file mode 100644 index 0000000000000..eb073fd5670fc --- /dev/null +++ b/internal/services/storage/helpers/schema.go @@ -0,0 +1,22 @@ +package helpers + +import ( + "context" + "log" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-provider-azurerm/internal/clients" + "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" +) + +type StorageIDValidationFunc func(id, storageDomainSuffix string) error + +func ImporterValidatingStorageResourceId(validateFunc StorageIDValidationFunc) *schema.ResourceImporter { + return &schema.ResourceImporter{ + StateContext: func(_ context.Context, d *pluginsdk.ResourceData, meta interface{}) ([]*pluginsdk.ResourceData, error) { + storageDomainSuffix := meta.(*clients.Client).Storage.StorageDomainSuffix + log.Printf("[DEBUG] Importing Storage Resource - parsing %q using domain suffix %q", d.Id(), storageDomainSuffix) + return []*pluginsdk.ResourceData{d}, validateFunc(d.Id(), storageDomainSuffix) + }, + } +} diff --git a/internal/services/storage/migration/share.go b/internal/services/storage/migration/share.go index 6e48a71d3ae9a..75abecf1a189a 100644 --- a/internal/services/storage/migration/share.go +++ b/internal/services/storage/migration/share.go @@ -12,7 +12,8 @@ import ( "github.com/hashicorp/terraform-provider-azurerm/internal/clients" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares" ) var _ pluginsdk.StateUpgrade = ShareV0ToV1{} @@ -54,16 +55,18 @@ func (s ShareV1ToV2) UpgradeFunc() pluginsdk.StateUpgraderFunc { // name/resourceGroup/accountName parsedId := strings.Split(id, "/") if len(parsedId) != 3 { - return rawState, fmt.Errorf("Expected 3 segments in the ID but got %d", len(parsedId)) + return rawState, fmt.Errorf("expected 3 segments in the ID but got %d", len(parsedId)) } shareName := parsedId[0] accountName := parsedId[2] - environment := meta.(*clients.Client).Account.AzureEnvironment - client := shares.NewWithEnvironment(environment) + accountId, err := accounts.ParseAccountID(accountName, meta.(*clients.Client).Storage.StorageDomainSuffix) + if err != nil { + return rawState, fmt.Errorf("parsing Account ID: %v", err) + } - newResourceId := client.GetResourceID(accountName, shareName) + newResourceId := shares.NewShareID(*accountId, shareName) log.Printf("[DEBUG] Updating Resource ID from %q to %q", id, newResourceId) rawState["id"] = newResourceId @@ -72,7 +75,7 @@ func (s ShareV1ToV2) UpgradeFunc() pluginsdk.StateUpgraderFunc { } } -// the schema schema was used for both V0 and V1 +// this schema was used for both V0 and V1 func shareSchemaForV0AndV1() map[string]*pluginsdk.Schema { return map[string]*pluginsdk.Schema{ "name": { diff --git a/internal/services/storage/parse/storage_container_data_plane.go b/internal/services/storage/parse/storage_container_data_plane.go index 47dc25a7ec8ca..9dce550a5b760 100644 --- a/internal/services/storage/parse/storage_container_data_plane.go +++ b/internal/services/storage/parse/storage_container_data_plane.go @@ -9,7 +9,7 @@ import ( "strings" "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers" ) var _ resourceids.Id = StorageContainerDataPlaneId{} @@ -41,8 +41,8 @@ func NewStorageContainerDataPlaneId(accountName, domainSuffix, name string) Stor } } -func StorageContainerDataPlaneID(id string) (*StorageContainerDataPlaneId, error) { - parsed, err := containers.ParseResourceID(id) +func StorageContainerDataPlaneID(id, domainSuffix string) (*StorageContainerDataPlaneId, error) { + parsed, err := containers.ParseContainerID(id, domainSuffix) if err != nil { return nil, err } @@ -60,7 +60,7 @@ func StorageContainerDataPlaneID(id string) (*StorageContainerDataPlaneId, error domainNameSuffix := strings.TrimPrefix(host, fmt.Sprintf("%s.blob.", hostSegments[0])) return &StorageContainerDataPlaneId{ - AccountName: parsed.AccountName, + AccountName: parsed.AccountId.AccountName, DomainSuffix: domainNameSuffix, Name: parsed.ContainerName, }, nil diff --git a/internal/services/storage/parse/storage_queue_data_plane.go b/internal/services/storage/parse/storage_queue_data_plane.go index 3fd6770ec093d..fc09bf22d4d79 100644 --- a/internal/services/storage/parse/storage_queue_data_plane.go +++ b/internal/services/storage/parse/storage_queue_data_plane.go @@ -9,7 +9,7 @@ import ( "strings" "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues" ) var _ resourceids.Id = StorageQueueDataPlaneId{} @@ -41,8 +41,8 @@ func NewStorageQueueDataPlaneId(accountName, domainSuffix, name string) StorageQ } } -func StorageQueueDataPlaneID(id string) (*StorageQueueDataPlaneId, error) { - parsed, err := queues.ParseResourceID(id) +func StorageQueueDataPlaneID(id, domainSuffix string) (*StorageQueueDataPlaneId, error) { + parsed, err := queues.ParseQueueID(id, domainSuffix) if err != nil { return nil, err } @@ -60,7 +60,7 @@ func StorageQueueDataPlaneID(id string) (*StorageQueueDataPlaneId, error) { domainNameSuffix := strings.TrimPrefix(host, fmt.Sprintf("%s.queue.", hostSegments[0])) return &StorageQueueDataPlaneId{ - AccountName: parsed.AccountName, + AccountName: parsed.AccountId.AccountName, DomainSuffix: domainNameSuffix, Name: parsed.QueueName, }, nil diff --git a/internal/services/storage/parse/storage_share_data_plane.go b/internal/services/storage/parse/storage_share_data_plane.go index 321fff4a7a8fe..fa4335ebc6a9d 100644 --- a/internal/services/storage/parse/storage_share_data_plane.go +++ b/internal/services/storage/parse/storage_share_data_plane.go @@ -9,7 +9,7 @@ import ( "strings" "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares" ) // TODO: tests for this @@ -42,8 +42,8 @@ func NewStorageShareDataPlaneId(accountName, domainSuffix, name string) StorageS } } -func StorageShareDataPlaneID(id string) (*StorageShareDataPlaneId, error) { - parsed, err := shares.ParseResourceID(id) +func StorageShareDataPlaneID(id, domainSuffix string) (*StorageShareDataPlaneId, error) { + parsed, err := shares.ParseShareID(id, domainSuffix) if err != nil { return nil, err } @@ -61,7 +61,7 @@ func StorageShareDataPlaneID(id string) (*StorageShareDataPlaneId, error) { domainNameSuffix := strings.TrimPrefix(host, fmt.Sprintf("%s.file.", hostSegments[0])) return &StorageShareDataPlaneId{ - AccountName: parsed.AccountName, + AccountName: parsed.AccountId.AccountName, DomainSuffix: domainNameSuffix, Name: parsed.ShareName, }, nil diff --git a/internal/services/storage/parse/storage_table_data_plane.go b/internal/services/storage/parse/storage_table_data_plane.go index bf668f89f317e..789801810ab79 100644 --- a/internal/services/storage/parse/storage_table_data_plane.go +++ b/internal/services/storage/parse/storage_table_data_plane.go @@ -9,7 +9,7 @@ import ( "strings" "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables" ) // TODO: tests for this @@ -42,8 +42,8 @@ func NewStorageTableDataPlaneId(accountName, domainSuffix, name string) StorageT } } -func StorageTableDataPlaneID(input string) (*StorageTableDataPlaneId, error) { - parsed, err := tables.ParseResourceID(input) +func StorageTableDataPlaneID(input, domainSuffix string) (*StorageTableDataPlaneId, error) { + parsed, err := tables.ParseTableID(input, domainSuffix) if err != nil { return nil, err } @@ -61,7 +61,7 @@ func StorageTableDataPlaneID(input string) (*StorageTableDataPlaneId, error) { domainNameSuffix := strings.TrimPrefix(host, fmt.Sprintf("%s.table.", hostSegments[0])) return &StorageTableDataPlaneId{ - AccountName: parsed.AccountName, + AccountName: parsed.AccountId.AccountName, DomainSuffix: domainNameSuffix, Name: parsed.TableName, }, nil diff --git a/internal/services/storage/shim/containers.go b/internal/services/storage/shim/containers.go index 55156bb5d9f31..c29325ce4aa26 100644 --- a/internal/services/storage/shim/containers.go +++ b/internal/services/storage/shim/containers.go @@ -6,16 +6,16 @@ package shim import ( "context" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers" ) type StorageContainerWrapper interface { - Create(ctx context.Context, resourceGroup, accountName, containerName string, input containers.CreateInput) error - Delete(ctx context.Context, resourceGroup, accountName, containerName string) error - Exists(ctx context.Context, resourceGroup, accountName, containerName string) (*bool, error) - Get(ctx context.Context, resourceGroup, accountName, containerName string) (*StorageContainerProperties, error) - UpdateAccessLevel(ctx context.Context, resourceGroup, accountName, containerName string, level containers.AccessLevel) error - UpdateMetaData(ctx context.Context, resourceGroup, accountName, containerName string, metadata map[string]string) error + Create(ctx context.Context, containerName string, input containers.CreateInput) error + Delete(ctx context.Context, containerName string) error + Exists(ctx context.Context, containerName string) (*bool, error) + Get(ctx context.Context, containerName string) (*StorageContainerProperties, error) + UpdateAccessLevel(ctx context.Context, containerName string, level containers.AccessLevel) error + UpdateMetaData(ctx context.Context, containerName string, metaData map[string]string) error } type StorageContainerProperties struct { diff --git a/internal/services/storage/shim/containers_data_plane.go b/internal/services/storage/shim/containers_data_plane.go index 2310188f5230c..e365ef9819fbb 100644 --- a/internal/services/storage/shim/containers_data_plane.go +++ b/internal/services/storage/shim/containers_data_plane.go @@ -6,12 +6,10 @@ package shim import ( "context" "fmt" - "strings" - "time" - "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" - "github.com/hashicorp/terraform-provider-azurerm/utils" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers" + "github.com/hashicorp/go-azure-helpers/lang/pointer" + "github.com/hashicorp/go-azure-helpers/lang/response" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers" ) type DataPlaneStorageContainerWrapper struct { @@ -24,59 +22,37 @@ func NewDataPlaneStorageContainerWrapper(client *containers.Client) StorageConta } } -func (w DataPlaneStorageContainerWrapper) Create(ctx context.Context, _, accountName, containerName string, input containers.CreateInput) error { - timeout, ok := ctx.Deadline() - if !ok { - return fmt.Errorf("context is missing a timeout") - } - - if resp, err := w.client.Create(ctx, accountName, containerName, input); err != nil { - // If we fail due to previous delete still in progress, then we can retry - if utils.ResponseWasConflict(resp.Response) && strings.Contains(err.Error(), "ContainerBeingDeleted") { - stateConf := &pluginsdk.StateChangeConf{ - Pending: []string{"waitingOnDelete"}, - Target: []string{"succeeded"}, - Refresh: w.createRefreshFunc(ctx, accountName, containerName, input), - PollInterval: 10 * time.Second, - NotFoundChecks: 180, - Timeout: time.Until(timeout), - } - - if _, err := stateConf.WaitForStateContext(ctx); err != nil { - return fmt.Errorf("failed creating container: %+v", err) - } - } else { - return fmt.Errorf("failed creating container: %+v", err) - } +func (w DataPlaneStorageContainerWrapper) Create(ctx context.Context, containerName string, input containers.CreateInput) error { + if _, err := w.client.Create(ctx, containerName, input); err != nil { + return fmt.Errorf("creating container: %+v", err) } return nil } -func (w DataPlaneStorageContainerWrapper) Delete(ctx context.Context, _, accountName, containerName string) error { - resp, err := w.client.Delete(ctx, accountName, containerName) - if utils.ResponseWasNotFound(resp) { +func (w DataPlaneStorageContainerWrapper) Delete(ctx context.Context, containerName string) error { + resp, err := w.client.Delete(ctx, containerName) + if response.WasNotFound(resp.HttpResponse) { return nil } return err } -func (w DataPlaneStorageContainerWrapper) Exists(ctx context.Context, _, accountName, containerName string) (*bool, error) { - existing, err := w.client.GetProperties(ctx, accountName, containerName) +func (w DataPlaneStorageContainerWrapper) Exists(ctx context.Context, containerName string) (*bool, error) { + existing, err := w.client.GetProperties(ctx, containerName, containers.GetPropertiesInput{}) if err != nil { - if !utils.ResponseWasNotFound(existing.Response) { - return nil, err + if response.WasNotFound(existing.HttpResponse) { + return pointer.To(false), nil } + return nil, err } - - exists := !utils.ResponseWasNotFound(existing.Response) - return &exists, nil + return pointer.To(true), nil } -func (w DataPlaneStorageContainerWrapper) Get(ctx context.Context, _, accountName, containerName string) (*StorageContainerProperties, error) { - props, err := w.client.GetProperties(ctx, accountName, containerName) +func (w DataPlaneStorageContainerWrapper) Get(ctx context.Context, containerName string) (*StorageContainerProperties, error) { + props, err := w.client.GetProperties(ctx, containerName, containers.GetPropertiesInput{}) if err != nil { - if utils.ResponseWasNotFound(props.Response) { + if response.WasNotFound(props.HttpResponse) { return nil, nil } @@ -91,29 +67,18 @@ func (w DataPlaneStorageContainerWrapper) Get(ctx context.Context, _, accountNam }, nil } -func (w DataPlaneStorageContainerWrapper) UpdateAccessLevel(ctx context.Context, _, accountName, containerName string, level containers.AccessLevel) error { - _, err := w.client.SetAccessControl(ctx, accountName, containerName, level) - return err -} - -func (w DataPlaneStorageContainerWrapper) UpdateMetaData(ctx context.Context, _, accountName, containerName string, metaData map[string]string) error { - _, err := w.client.SetMetaData(ctx, accountName, containerName, metaData) +func (w DataPlaneStorageContainerWrapper) UpdateAccessLevel(ctx context.Context, containerName string, level containers.AccessLevel) error { + input := containers.SetAccessControlInput{ + AccessLevel: level, + } + _, err := w.client.SetAccessControl(ctx, containerName, input) return err } -func (w DataPlaneStorageContainerWrapper) createRefreshFunc(ctx context.Context, accountName string, containerName string, input containers.CreateInput) pluginsdk.StateRefreshFunc { - return func() (interface{}, string, error) { - resp, err := w.client.Create(ctx, accountName, containerName, input) - if err != nil { - if !utils.ResponseWasConflict(resp.Response) { - return nil, "", err - } - - if utils.ResponseWasConflict(resp.Response) && strings.Contains(err.Error(), "ContainerBeingDeleted") { - return nil, "waitingOnDelete", nil - } - } - - return "succeeded", "succeeded", nil +func (w DataPlaneStorageContainerWrapper) UpdateMetaData(ctx context.Context, containerName string, metaData map[string]string) error { + input := containers.SetMetaDataInput{ + MetaData: metaData, } + _, err := w.client.SetMetaData(ctx, containerName, input) + return err } diff --git a/internal/services/storage/shim/queues.go b/internal/services/storage/shim/queues.go index d145093014b02..d6d1d4e432c92 100644 --- a/internal/services/storage/shim/queues.go +++ b/internal/services/storage/shim/queues.go @@ -6,17 +6,17 @@ package shim import ( "context" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues" ) type StorageQueuesWrapper interface { - Create(ctx context.Context, resourceGroup, accountName, queueName string, metaData map[string]string) error - Delete(ctx context.Context, resourceGroup, accountName, queueName string) error - Exists(ctx context.Context, resourceGroup, accountName, queueName string) (*bool, error) - Get(ctx context.Context, resourceGroup, accountName, queueName string) (*StorageQueueProperties, error) - GetServiceProperties(ctx context.Context, resourceGroup, accountName string) (*queues.StorageServiceProperties, error) - UpdateMetaData(ctx context.Context, resourceGroup, accountName, queueName string, metaData map[string]string) error - UpdateServiceProperties(ctx context.Context, resourceGroup, accountName string, properties queues.StorageServiceProperties) error + Create(ctx context.Context, queueName string, metaData map[string]string) error + Delete(ctx context.Context, queueName string) error + Exists(ctx context.Context, queueName string) (*bool, error) + Get(ctx context.Context, queueName string) (*StorageQueueProperties, error) + GetServiceProperties(ctx context.Context) (*queues.StorageServiceProperties, error) + UpdateMetaData(ctx context.Context, queueName string, metaData map[string]string) error + UpdateServiceProperties(ctx context.Context, properties queues.StorageServiceProperties) error } type StorageQueueProperties struct { diff --git a/internal/services/storage/shim/queues_data_plane.go b/internal/services/storage/shim/queues_data_plane.go index 3052f205761af..8b52b1e9d0685 100644 --- a/internal/services/storage/shim/queues_data_plane.go +++ b/internal/services/storage/shim/queues_data_plane.go @@ -6,8 +6,9 @@ package shim import ( "context" - "github.com/hashicorp/terraform-provider-azurerm/utils" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues" + "github.com/hashicorp/go-azure-helpers/lang/pointer" + "github.com/hashicorp/go-azure-helpers/lang/response" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues" ) type DataPlaneStorageQueueWrapper struct { @@ -20,32 +21,34 @@ func NewDataPlaneStorageQueueWrapper(client *queues.Client) StorageQueuesWrapper } } -func (w DataPlaneStorageQueueWrapper) Create(ctx context.Context, _, accountName, queueName string, metaData map[string]string) error { - _, err := w.client.Create(ctx, accountName, queueName, metaData) +func (w DataPlaneStorageQueueWrapper) Create(ctx context.Context, queueName string, metaData map[string]string) error { + input := queues.CreateInput{ + MetaData: metaData, + } + _, err := w.client.Create(ctx, queueName, input) return err } -func (w DataPlaneStorageQueueWrapper) Delete(ctx context.Context, _, accountName, queueName string) error { - _, err := w.client.Delete(ctx, accountName, queueName) +func (w DataPlaneStorageQueueWrapper) Delete(ctx context.Context, queueName string) error { + _, err := w.client.Delete(ctx, queueName) return err } -func (w DataPlaneStorageQueueWrapper) Exists(ctx context.Context, _, accountName, queueName string) (*bool, error) { - existing, err := w.client.GetMetaData(ctx, accountName, queueName) +func (w DataPlaneStorageQueueWrapper) Exists(ctx context.Context, queueName string) (*bool, error) { + existing, err := w.client.GetMetaData(ctx, queueName) if err != nil { - if utils.ResponseWasNotFound(existing.Response) { - return utils.Bool(false), nil + if response.WasNotFound(existing.HttpResponse) { + return pointer.To(false), nil } return nil, err } - - return utils.Bool(true), nil + return pointer.To(true), nil } -func (w DataPlaneStorageQueueWrapper) Get(ctx context.Context, _, accountName, queueName string) (*StorageQueueProperties, error) { - props, err := w.client.GetMetaData(ctx, accountName, queueName) +func (w DataPlaneStorageQueueWrapper) Get(ctx context.Context, queueName string) (*StorageQueueProperties, error) { + props, err := w.client.GetMetaData(ctx, queueName) if err != nil { - if utils.ResponseWasNotFound(props.Response) { + if response.WasNotFound(props.HttpResponse) { return nil, nil } return nil, err @@ -56,10 +59,10 @@ func (w DataPlaneStorageQueueWrapper) Get(ctx context.Context, _, accountName, q }, nil } -func (w DataPlaneStorageQueueWrapper) GetServiceProperties(ctx context.Context, resourceGroup, accountName string) (*queues.StorageServiceProperties, error) { - serviceProps, err := w.client.GetServiceProperties(ctx, accountName) +func (w DataPlaneStorageQueueWrapper) GetServiceProperties(ctx context.Context) (*queues.StorageServiceProperties, error) { + serviceProps, err := w.client.GetServiceProperties(ctx) if err != nil { - if utils.ResponseWasNotFound(serviceProps.Response) { + if response.WasNotFound(serviceProps.HttpResponse) { return nil, nil } return nil, err @@ -68,12 +71,18 @@ func (w DataPlaneStorageQueueWrapper) GetServiceProperties(ctx context.Context, return &serviceProps.StorageServiceProperties, nil } -func (w DataPlaneStorageQueueWrapper) UpdateMetaData(ctx context.Context, _, accountName, queueName string, metaData map[string]string) error { - _, err := w.client.SetMetaData(ctx, accountName, queueName, metaData) +func (w DataPlaneStorageQueueWrapper) UpdateMetaData(ctx context.Context, queueName string, metaData map[string]string) error { + input := queues.SetMetaDataInput{ + MetaData: metaData, + } + _, err := w.client.SetMetaData(ctx, queueName, input) return err } -func (w DataPlaneStorageQueueWrapper) UpdateServiceProperties(ctx context.Context, _, accountName string, properties queues.StorageServiceProperties) error { - _, err := w.client.SetServiceProperties(ctx, accountName, properties) +func (w DataPlaneStorageQueueWrapper) UpdateServiceProperties(ctx context.Context, properties queues.StorageServiceProperties) error { + input := queues.SetStorageServicePropertiesInput{ + Properties: properties, + } + _, err := w.client.SetServiceProperties(ctx, input) return err } diff --git a/internal/services/storage/shim/shares.go b/internal/services/storage/shim/shares.go index 702e34b492b2e..375595520e300 100644 --- a/internal/services/storage/shim/shares.go +++ b/internal/services/storage/shim/shares.go @@ -6,18 +6,18 @@ package shim import ( "context" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares" ) type StorageShareWrapper interface { - Create(ctx context.Context, resourceGroup, accountName, shareName string, input shares.CreateInput) error - Delete(ctx context.Context, resourceGroup, accountName, shareName string) error - Exists(ctx context.Context, resourceGroup, accountName, shareName string) (*bool, error) - Get(ctx context.Context, resourceGroup, accountName, shareName string) (*StorageShareProperties, error) - UpdateACLs(ctx context.Context, resourceGroup, accountName, shareName string, acls []shares.SignedIdentifier) error - UpdateMetaData(ctx context.Context, resourceGroup, accountName, shareName string, metaData map[string]string) error - UpdateQuota(ctx context.Context, resourceGroup, accountName, shareName string, quotaGB int) error - UpdateTier(ctx context.Context, resourceGroup, accountName, shareName string, tier shares.AccessTier) error + Create(ctx context.Context, shareName string, input shares.CreateInput) error + Delete(ctx context.Context, shareName string) error + Exists(ctx context.Context, shareName string) (*bool, error) + Get(ctx context.Context, shareName string) (*StorageShareProperties, error) + UpdateACLs(ctx context.Context, shareName string, input shares.SetAclInput) error + UpdateMetaData(ctx context.Context, shareName string, metaData map[string]string) error + UpdateQuota(ctx context.Context, shareName string, quotaGB int) error + UpdateTier(ctx context.Context, shareName string, tier shares.AccessTier) error } type StorageShareProperties struct { diff --git a/internal/services/storage/shim/shares_data_plane.go b/internal/services/storage/shim/shares_data_plane.go index ae88b650cd55e..a251059fd1b3f 100644 --- a/internal/services/storage/shim/shares_data_plane.go +++ b/internal/services/storage/shim/shares_data_plane.go @@ -6,12 +6,10 @@ package shim import ( "context" "fmt" - "strings" - "time" - "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" - "github.com/hashicorp/terraform-provider-azurerm/utils" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares" + "github.com/hashicorp/go-azure-helpers/lang/pointer" + "github.com/hashicorp/go-azure-helpers/lang/response" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares" ) type DataPlaneStorageShareWrapper struct { @@ -24,66 +22,43 @@ func NewDataPlaneStorageShareWrapper(client *shares.Client) StorageShareWrapper } } -func (w DataPlaneStorageShareWrapper) Create(ctx context.Context, _, accountName, shareName string, input shares.CreateInput) error { - timeout, ok := ctx.Deadline() - if !ok { - return fmt.Errorf("context is missing a timeout") +func (w DataPlaneStorageShareWrapper) Create(ctx context.Context, shareName string, input shares.CreateInput) error { + if _, err := w.client.Create(ctx, shareName, input); err != nil { + return fmt.Errorf("creating share: %+v", err) } - - resp, err := w.client.Create(ctx, accountName, shareName, input) - if err == nil { - return nil - } - - // If we fail due to previous delete still in progress, then we can retry - if utils.ResponseWasConflict(resp) && strings.Contains(err.Error(), "ShareBeingDeleted") { - stateConf := &pluginsdk.StateChangeConf{ - Pending: []string{"waitingOnDelete"}, - Target: []string{"succeeded"}, - Refresh: w.createRefreshFunc(ctx, accountName, shareName, input), - PollInterval: 10 * time.Second, - NotFoundChecks: 180, - Timeout: time.Until(timeout), - } - - _, err := stateConf.WaitForStateContext(ctx) - return err - } - - // otherwise it's a legit error, so raise it - return err + return nil } -func (w DataPlaneStorageShareWrapper) Delete(ctx context.Context, _, accountName, shareName string) error { - deleteSnapshots := true - _, err := w.client.Delete(ctx, accountName, shareName, deleteSnapshots) +func (w DataPlaneStorageShareWrapper) Delete(ctx context.Context, shareName string) error { + input := shares.DeleteInput{ + DeleteSnapshots: true, + } + _, err := w.client.Delete(ctx, shareName, input) return err } -func (w DataPlaneStorageShareWrapper) Exists(ctx context.Context, _, accountName, shareName string) (*bool, error) { - existing, err := w.client.GetProperties(ctx, accountName, shareName) +func (w DataPlaneStorageShareWrapper) Exists(ctx context.Context, shareName string) (*bool, error) { + existing, err := w.client.GetProperties(ctx, shareName) if err != nil { - if utils.ResponseWasNotFound(existing.Response) { - return nil, nil + if response.WasNotFound(existing.HttpResponse) { + return pointer.To(false), nil } - return nil, err } - - return utils.Bool(true), nil + return pointer.To(true), nil } -func (w DataPlaneStorageShareWrapper) Get(ctx context.Context, _, accountName, shareName string) (*StorageShareProperties, error) { - props, err := w.client.GetProperties(ctx, accountName, shareName) +func (w DataPlaneStorageShareWrapper) Get(ctx context.Context, shareName string) (*StorageShareProperties, error) { + props, err := w.client.GetProperties(ctx, shareName) if err != nil { - if utils.ResponseWasNotFound(props.Response) { + if response.WasNotFound(props.HttpResponse) { return nil, nil } return nil, err } - acls, err := w.client.GetACL(ctx, accountName, shareName) + acls, err := w.client.GetACL(ctx, shareName) if err != nil { return nil, err } @@ -97,44 +72,30 @@ func (w DataPlaneStorageShareWrapper) Get(ctx context.Context, _, accountName, s }, nil } -func (w DataPlaneStorageShareWrapper) UpdateACLs(ctx context.Context, _, accountName, shareName string, acls []shares.SignedIdentifier) error { - _, err := w.client.SetACL(ctx, accountName, shareName, acls) +func (w DataPlaneStorageShareWrapper) UpdateACLs(ctx context.Context, shareName string, input shares.SetAclInput) error { + _, err := w.client.SetACL(ctx, shareName, input) return err } -func (w DataPlaneStorageShareWrapper) UpdateMetaData(ctx context.Context, _, accountName, shareName string, metaData map[string]string) error { - _, err := w.client.SetMetaData(ctx, accountName, shareName, metaData) +func (w DataPlaneStorageShareWrapper) UpdateMetaData(ctx context.Context, shareName string, metaData map[string]string) error { + input := shares.SetMetaDataInput{ + MetaData: metaData, + } + _, err := w.client.SetMetaData(ctx, shareName, input) return err } -func (w DataPlaneStorageShareWrapper) UpdateQuota(ctx context.Context, _, accountName, shareName string, quotaGB int) error { - _, err := w.client.SetProperties(ctx, accountName, shareName, shares.ShareProperties{ +func (w DataPlaneStorageShareWrapper) UpdateQuota(ctx context.Context, shareName string, quotaGB int) error { + _, err := w.client.SetProperties(ctx, shareName, shares.ShareProperties{ QuotaInGb: "aGB, }) return err } -func (w DataPlaneStorageShareWrapper) UpdateTier(ctx context.Context, _, accountname, shareName string, tier shares.AccessTier) error { +func (w DataPlaneStorageShareWrapper) UpdateTier(ctx context.Context, shareName string, tier shares.AccessTier) error { props := shares.ShareProperties{ AccessTier: &tier, } - _, err := w.client.SetProperties(ctx, accountname, shareName, props) + _, err := w.client.SetProperties(ctx, shareName, props) return err } - -func (w DataPlaneStorageShareWrapper) createRefreshFunc(ctx context.Context, accountName string, shareName string, input shares.CreateInput) pluginsdk.StateRefreshFunc { - return func() (interface{}, string, error) { - resp, err := w.client.Create(ctx, accountName, shareName, input) - if err != nil { - if !utils.ResponseWasConflict(resp) { - return nil, "", err - } - - if utils.ResponseWasConflict(resp) && strings.Contains(err.Error(), "ShareBeingDeleted") { - return nil, "waitingOnDelete", nil - } - } - - return "succeeded", "succeeded", nil - } -} diff --git a/internal/services/storage/shim/tables.go b/internal/services/storage/shim/tables.go index f928d83fcea03..0734e971a0465 100644 --- a/internal/services/storage/shim/tables.go +++ b/internal/services/storage/shim/tables.go @@ -6,13 +6,13 @@ package shim import ( "context" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables" ) type StorageTableWrapper interface { - Create(ctx context.Context, resourceGroup string, accountName string, tableName string) error - Delete(ctx context.Context, resourceGroup string, accountName string, tableName string) error - Exists(ctx context.Context, resourceGroup string, accountName string, tableName string) (*bool, error) - GetACLs(ctx context.Context, resourceGroup string, accountName string, tableName string) (*[]tables.SignedIdentifier, error) - UpdateACLs(ctx context.Context, resourceGroup string, accountName string, tableName string, acls []tables.SignedIdentifier) error + Create(ctx context.Context, tableName string) error + Delete(ctx context.Context, tableName string) error + Exists(ctx context.Context, tableName string) (*bool, error) + GetACLs(ctx context.Context, tableName string) (*[]tables.SignedIdentifier, error) + UpdateACLs(ctx context.Context, tableName string, acls []tables.SignedIdentifier) error } diff --git a/internal/services/storage/shim/tables_data_plane.go b/internal/services/storage/shim/tables_data_plane.go index f8a998f06069a..447fca8946776 100644 --- a/internal/services/storage/shim/tables_data_plane.go +++ b/internal/services/storage/shim/tables_data_plane.go @@ -6,8 +6,9 @@ package shim import ( "context" - "github.com/hashicorp/terraform-provider-azurerm/utils" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables" + "github.com/hashicorp/go-azure-helpers/lang/pointer" + "github.com/hashicorp/go-azure-helpers/lang/response" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables" ) type DataPlaneStorageTableWrapper struct { @@ -20,31 +21,29 @@ func NewDataPlaneStorageTableWrapper(client *tables.Client) StorageTableWrapper } } -func (w DataPlaneStorageTableWrapper) Create(ctx context.Context, _, accountName, tableName string) error { - _, err := w.client.Create(ctx, accountName, tableName) +func (w DataPlaneStorageTableWrapper) Create(ctx context.Context, tableName string) error { + _, err := w.client.Create(ctx, tableName) return err } -func (w DataPlaneStorageTableWrapper) Delete(ctx context.Context, _, accountName, tableName string) error { - _, err := w.client.Delete(ctx, accountName, tableName) +func (w DataPlaneStorageTableWrapper) Delete(ctx context.Context, tableName string) error { + _, err := w.client.Delete(ctx, tableName) return err } -func (w DataPlaneStorageTableWrapper) Exists(ctx context.Context, _, accountName, tableName string) (*bool, error) { - existing, err := w.client.Exists(ctx, accountName, tableName) +func (w DataPlaneStorageTableWrapper) Exists(ctx context.Context, tableName string) (*bool, error) { + existing, err := w.client.Exists(ctx, tableName) if err != nil { - if utils.ResponseWasNotFound(existing) { - return nil, nil + if response.WasNotFound(existing.HttpResponse) { + return pointer.To(false), nil } - return nil, err } - - return utils.Bool(true), nil + return pointer.To(true), nil } -func (w DataPlaneStorageTableWrapper) GetACLs(ctx context.Context, _, accountName, tableName string) (*[]tables.SignedIdentifier, error) { - acls, err := w.client.GetACL(ctx, accountName, tableName) +func (w DataPlaneStorageTableWrapper) GetACLs(ctx context.Context, tableName string) (*[]tables.SignedIdentifier, error) { + acls, err := w.client.GetACL(ctx, tableName) if err != nil { return nil, err } @@ -52,7 +51,7 @@ func (w DataPlaneStorageTableWrapper) GetACLs(ctx context.Context, _, accountNam return &acls.SignedIdentifiers, nil } -func (w DataPlaneStorageTableWrapper) UpdateACLs(ctx context.Context, _, accountName, tableName string, acls []tables.SignedIdentifier) error { - _, err := w.client.SetACL(ctx, accountName, tableName, acls) +func (w DataPlaneStorageTableWrapper) UpdateACLs(ctx context.Context, tableName string, acls []tables.SignedIdentifier) error { + _, err := w.client.SetACL(ctx, tableName, acls) return err } diff --git a/internal/services/storage/storage_account_resource.go b/internal/services/storage/storage_account_resource.go index b83c2a837e376..85e6971e4e19c 100644 --- a/internal/services/storage/storage_account_resource.go +++ b/internal/services/storage/storage_account_resource.go @@ -40,8 +40,8 @@ import ( "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" "github.com/hashicorp/terraform-provider-azurerm/internal/timeouts" "github.com/hashicorp/terraform-provider-azurerm/utils" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues" ) var ( @@ -1310,7 +1310,7 @@ func resourceStorageAccountCreate(d *pluginsdk.ResourceData, meta interface{}) e existing, err := client.GetProperties(ctx, id.ResourceGroupName, id.StorageAccountName, "") if err != nil { if !utils.ResponseWasNotFound(existing.Response) { - return fmt.Errorf("checking for presence of existing %s: %s", id, err) + return fmt.Errorf("checking for existing %s: %s", id, err) } } @@ -1585,16 +1585,15 @@ func resourceStorageAccountCreate(d *pluginsdk.ResourceData, meta interface{}) e if !supportLevel.supportQueue { return fmt.Errorf("`queue_properties` aren't supported for account kind %q in sku tier %q", accountKind, accountTier) } - storageClient := meta.(*clients.Client).Storage - account, err := storageClient.FindAccount(ctx, id.StorageAccountName) + accountDetails, err := storageClient.FindAccount(ctx, id.StorageAccountName) if err != nil { return fmt.Errorf("retrieving %s: %+v", id, err) } - if account == nil { + if accountDetails == nil { return fmt.Errorf("unable to locate %q", id) } - queueClient, err := storageClient.QueuesClient(ctx, *account) + queueClient, err := storageClient.QueuesDataPlaneClient(ctx, *accountDetails, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { return fmt.Errorf("building Queues Client: %s", err) } @@ -1604,7 +1603,7 @@ func resourceStorageAccountCreate(d *pluginsdk.ResourceData, meta interface{}) e return fmt.Errorf("expanding `queue_properties`: %+v", err) } - if err = queueClient.UpdateServiceProperties(ctx, id.ResourceGroupName, id.StorageAccountName, queueProperties); err != nil { + if err = queueClient.UpdateServiceProperties(ctx, queueProperties); err != nil { return fmt.Errorf("updating Queue Properties: %+v", err) } } @@ -1641,7 +1640,6 @@ func resourceStorageAccountCreate(d *pluginsdk.ResourceData, meta interface{}) e if !supportLevel.supportStaticWebsite { return fmt.Errorf("`static_website` aren't supported for account kind %q in sku tier %q", accountKind, accountTier) } - storageClient := meta.(*clients.Client).Storage account, err := storageClient.FindAccount(ctx, id.StorageAccountName) if err != nil { @@ -1651,7 +1649,7 @@ func resourceStorageAccountCreate(d *pluginsdk.ResourceData, meta interface{}) e return fmt.Errorf("unable to locate %s", id) } - accountsClient, err := storageClient.AccountsDataPlaneClient(ctx, *account) + accountsClient, err := storageClient.AccountsDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { return fmt.Errorf("building Accounts Data Plane Client: %s", err) } @@ -1957,7 +1955,7 @@ func resourceStorageAccountUpdate(d *pluginsdk.ResourceData, meta interface{}) e return fmt.Errorf("unable to locate %s", *id) } - queueClient, err := storageClient.QueuesClient(ctx, *account) + queueClient, err := storageClient.QueuesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { return fmt.Errorf("building Queues Client: %s", err) } @@ -1967,7 +1965,7 @@ func resourceStorageAccountUpdate(d *pluginsdk.ResourceData, meta interface{}) e return fmt.Errorf("expanding `queue_properties` for %s: %+v", *id, err) } - if err = queueClient.UpdateServiceProperties(ctx, account.ResourceGroup, id.StorageAccountName, queueProperties); err != nil { + if err = queueClient.UpdateServiceProperties(ctx, queueProperties); err != nil { return fmt.Errorf("updating Queue Properties for %s: %+v", *id, err) } } @@ -2012,7 +2010,7 @@ func resourceStorageAccountUpdate(d *pluginsdk.ResourceData, meta interface{}) e return fmt.Errorf("unable to locate %s", *id) } - accountsClient, err := storageClient.AccountsDataPlaneClient(ctx, *account) + accountsClient, err := storageClient.AccountsDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { return fmt.Errorf("building Data Plane client for %s: %+v", *id, err) } @@ -2298,12 +2296,12 @@ func resourceStorageAccountRead(d *pluginsdk.ResourceData, meta interface{}) err } if supportLevel.supportQueue { - queueClient, err := storageClient.QueuesClient(ctx, *account) + queueClient, err := storageClient.QueuesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { return fmt.Errorf("building Queues Client: %s", err) } - queueProps, err := queueClient.GetServiceProperties(ctx, id.ResourceGroupName, id.StorageAccountName) + queueProps, err := queueClient.GetServiceProperties(ctx) if err != nil { return fmt.Errorf("retrieving queue properties for %s: %+v", *id, err) } @@ -2327,13 +2325,7 @@ func resourceStorageAccountRead(d *pluginsdk.ResourceData, meta interface{}) err } if supportLevel.supportStaticWebsite { - storageClient := meta.(*clients.Client).Storage - account, err := storageClient.FindAccount(ctx, id.StorageAccountName) - if err != nil { - return fmt.Errorf("retrieving %s: %+v", *id, err) - } - - accountsClient, err := storageClient.AccountsDataPlaneClient(ctx, *account) + accountsClient, err := storageClient.AccountsDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { return fmt.Errorf("building Accounts Data Plane Client: %s", err) } @@ -3628,18 +3620,16 @@ func flattenedSharePropertiesSMB(input *storage.SmbSetting) []interface{} { } func flattenStaticWebsiteProperties(input accounts.GetServicePropertiesResult) []interface{} { - if storageServiceProps := input.StorageServiceProperties; storageServiceProps != nil { - if staticWebsite := storageServiceProps.StaticWebsite; staticWebsite != nil { - if !staticWebsite.Enabled { - return []interface{}{} - } + if staticWebsite := input.StaticWebsite; staticWebsite != nil { + if !staticWebsite.Enabled { + return []interface{}{} + } - return []interface{}{ - map[string]interface{}{ - "index_document": staticWebsite.IndexDocument, - "error_404_document": staticWebsite.ErrorDocument404Path, - }, - } + return []interface{}{ + map[string]interface{}{ + "index_document": staticWebsite.IndexDocument, + "error_404_document": staticWebsite.ErrorDocument404Path, + }, } } return []interface{}{} diff --git a/internal/services/storage/storage_blob_data_source.go b/internal/services/storage/storage_blob_data_source.go index cbe1c2a1b6557..314284c5b2986 100644 --- a/internal/services/storage/storage_blob_data_source.go +++ b/internal/services/storage/storage_blob_data_source.go @@ -9,11 +9,12 @@ import ( "strings" "time" + "github.com/hashicorp/go-azure-helpers/lang/response" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/internal/timeouts" - "github.com/hashicorp/terraform-provider-azurerm/utils" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs" ) func dataSourceStorageBlob() *pluginsdk.Resource { @@ -82,28 +83,33 @@ func dataSourceStorageBlobRead(d *pluginsdk.ResourceData, meta interface{}) erro account, err := storageClient.FindAccount(ctx, accountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Blob %q (Container %q): %s", accountName, name, containerName, err) + return fmt.Errorf("retrieving Account %q for Blob %q (Container %q): %v", accountName, name, containerName, err) } if account == nil { - return fmt.Errorf("Unable to locate Storage Account %q!", accountName) + return fmt.Errorf("locating Storage Account %q", accountName) } - blobsClient, err := storageClient.BlobsClient(ctx, *account) + blobsClient, err := storageClient.BlobsDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building Blobs Client: %s", err) + return fmt.Errorf("building Blobs Client: %v", err) } - id := blobsClient.GetResourceID(accountName, containerName, name) + accountId, err := accounts.ParseAccountID(accountName, storageClient.StorageDomainSuffix) + if err != nil { + return fmt.Errorf("parsing Account ID: %v", err) + } + + id := blobs.NewBlobID(*accountId, containerName, name) - log.Printf("[INFO] Retrieving Storage Blob %q (Container %q / Account %q).", name, containerName, accountName) + log.Printf("[INFO] Retrieving %s", id) input := blobs.GetPropertiesInput{} - props, err := blobsClient.GetProperties(ctx, accountName, containerName, name, input) + props, err := blobsClient.GetProperties(ctx, containerName, name, input) if err != nil { - if utils.ResponseWasNotFound(props.Response) { - return fmt.Errorf("the Blob %q was not found in Container %q / Account %q", name, containerName, accountName) + if response.WasNotFound(props.HttpResponse) { + return fmt.Errorf("%s was not found", id) } - return fmt.Errorf("retrieving properties for Blob %q (Container %q / Account %q): %s", name, containerName, accountName, err) + return fmt.Errorf("retrieving properties for %s: %v", id, err) } d.Set("name", name) @@ -125,9 +131,9 @@ func dataSourceStorageBlobRead(d *pluginsdk.ResourceData, meta interface{}) erro d.Set("type", strings.TrimSuffix(string(props.BlobType), "Blob")) - d.SetId(id) + d.SetId(id.ID()) - d.Set("url", id) + d.Set("url", id.ID()) if err := d.Set("metadata", FlattenMetaData(props.MetaData)); err != nil { return fmt.Errorf("setting `metadata`: %+v", err) diff --git a/internal/services/storage/storage_blob_resource.go b/internal/services/storage/storage_blob_resource.go index d7e5e837a0129..6176192e5ba7a 100644 --- a/internal/services/storage/storage_blob_resource.go +++ b/internal/services/storage/storage_blob_resource.go @@ -10,15 +10,18 @@ import ( "strings" "time" + "github.com/hashicorp/go-azure-helpers/lang/response" "github.com/hashicorp/terraform-provider-azurerm/helpers/tf" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/helpers" "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/migration" "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/validate" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" "github.com/hashicorp/terraform-provider-azurerm/internal/timeouts" "github.com/hashicorp/terraform-provider-azurerm/utils" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs" ) func resourceStorageBlob() *pluginsdk.Resource { @@ -33,8 +36,8 @@ func resourceStorageBlob() *pluginsdk.Resource { 0: migration.BlobV0ToV1{}, }), - Importer: pluginsdk.ImporterValidatingResourceId(func(id string) error { - _, err := blobs.ParseResourceID(id) + Importer: helpers.ImporterValidatingStorageResourceId(func(id, storageDomainSuffix string) error { + _, err := blobs.ParseBlobID(id, storageDomainSuffix) return err }), @@ -175,28 +178,34 @@ func resourceStorageBlobCreate(d *pluginsdk.ResourceData, meta interface{}) erro account, err := storageClient.FindAccount(ctx, accountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Blob %q (Container %q): %s", accountName, name, containerName, err) + return fmt.Errorf("retrieving Storage Account %q for Blob %q (Container %q): %v", accountName, name, containerName, err) } if account == nil { - return fmt.Errorf("Unable to locate Storage Account %q!", accountName) + return fmt.Errorf("locating Storage Account %q", accountName) } - blobsClient, err := storageClient.BlobsClient(ctx, *account) + blobsClient, err := storageClient.BlobsDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building Blobs Client: %s", err) + return fmt.Errorf("building Blobs Client: %v", err) } - id := blobsClient.GetResourceID(accountName, containerName, name) + accountId := accounts.AccountId{ + AccountName: accountName, + DomainSuffix: storageClient.StorageDomainSuffix, + SubDomainType: accounts.BlobSubDomainType, + } + + id := blobs.NewBlobID(accountId, containerName, name) if d.IsNewResource() { input := blobs.GetPropertiesInput{} - props, err := blobsClient.GetProperties(ctx, accountName, containerName, name, input) + props, err := blobsClient.GetProperties(ctx, containerName, name, input) if err != nil { - if !utils.ResponseWasNotFound(props.Response) { - return fmt.Errorf("checking if Blob %q exists (Container %q / Account %q / Resource Group %q): %s", name, containerName, accountName, account.ResourceGroup, err) + if !response.WasNotFound(props.HttpResponse) { + return fmt.Errorf("checking for existing %s: %v", id, err) } } - if !utils.ResponseWasNotFound(props.Response) { - return tf.ImportAsExistsError("azurerm_storage_blob", id) + if !response.WasNotFound(props.HttpResponse) { + return tf.ImportAsExistsError("azurerm_storage_blob", id.ID()) } } @@ -210,7 +219,7 @@ func resourceStorageBlobCreate(d *pluginsdk.ResourceData, meta interface{}) erro } } - log.Printf("[DEBUG] Creating Blob %q in Container %q within Storage Account %q..", name, containerName, accountName) + log.Printf("[DEBUG] Creating %s..", id) metaDataRaw := d.Get("metadata").(map[string]interface{}) blobInput := BlobUpload{ AccountName: accountName, @@ -229,12 +238,12 @@ func resourceStorageBlobCreate(d *pluginsdk.ResourceData, meta interface{}) erro SourceContent: d.Get("source_content").(string), SourceUri: d.Get("source_uri").(string), } - if err := blobInput.Create(ctx); err != nil { - return fmt.Errorf("creating Blob %q (Container %q / Account %q): %s", name, containerName, accountName, err) + if err = blobInput.Create(ctx); err != nil { + return fmt.Errorf("creating %s: %v", id, err) } - log.Printf("[DEBUG] Created Blob %q in Container %q within Storage Account %q.", name, containerName, accountName) + log.Printf("[DEBUG] Created %s.", id) - d.SetId(id) + d.SetId(id.ID()) return resourceStorageBlobUpdate(d, meta) } @@ -244,69 +253,69 @@ func resourceStorageBlobUpdate(d *pluginsdk.ResourceData, meta interface{}) erro ctx, cancel := timeouts.ForUpdate(meta.(*clients.Client).StopContext, d) defer cancel() - id, err := blobs.ParseResourceID(d.Id()) + id, err := blobs.ParseBlobID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { - return fmt.Errorf("parsing %q: %s", d.Id(), err) + return fmt.Errorf("parsing %q: %v", d.Id(), err) } - account, err := storageClient.FindAccount(ctx, id.AccountName) + account, err := storageClient.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Blob %q (Container %q): %s", id.AccountName, id.BlobName, id.ContainerName, err) + return fmt.Errorf("retrieving Account %q for Blob %q (Container %q): %v", id.AccountId.AccountName, id.BlobName, id.ContainerName, err) } if account == nil { - return fmt.Errorf("Unable to locate Storage Account %q!", id.AccountName) + return fmt.Errorf("locating Storage Account %q", id.AccountId.AccountName) } - blobsClient, err := storageClient.BlobsClient(ctx, *account) + blobsClient, err := storageClient.BlobsDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building Blobs Client: %s", err) + return fmt.Errorf("building Blobs Client: %v", err) } if d.HasChange("content_type") || d.HasChange("cache_control") { - log.Printf("[DEBUG] Updating Properties for Blob %q (Container %q / Account %q)...", id.BlobName, id.ContainerName, id.AccountName) + log.Printf("[DEBUG] Updating Properties for %s...", id) input := blobs.SetPropertiesInput{ ContentType: utils.String(d.Get("content_type").(string)), CacheControl: utils.String(d.Get("cache_control").(string)), } - // `content_md5` is `ForceNew` but must be included in the `SetPropertiesInput` update payload or it will be zeroed on the blob. + // `content_md5` is `ForceNew` but must be included in the `SetPropertiesInput` update payload, or it will be zeroed on the blob. if contentMD5 := d.Get("content_md5").(string); contentMD5 != "" { data, err := convertHexToBase64Encoding(contentMD5) if err != nil { - return fmt.Errorf("in converting hex to base64 encoding for content_md5: %s", err) + return fmt.Errorf("converting hex to base64 encoding for content_md5: %v", err) } input.ContentMD5 = utils.String(data) } - if _, err := blobsClient.SetProperties(ctx, id.AccountName, id.ContainerName, id.BlobName, input); err != nil { - return fmt.Errorf("updating Properties for Blob %q (Container %q / Account %q): %s", id.BlobName, id.ContainerName, id.AccountName, err) + if _, err = blobsClient.SetProperties(ctx, id.ContainerName, id.BlobName, input); err != nil { + return fmt.Errorf("updating Properties for %s: %v", id, err) } - log.Printf("[DEBUG] Updated Properties for Blob %q (Container %q / Account %q).", id.BlobName, id.ContainerName, id.AccountName) + log.Printf("[DEBUG] Updated Properties for %s", id) } if d.HasChange("metadata") { - log.Printf("[DEBUG] Updating MetaData for Blob %q (Container %q / Account %q)...", id.BlobName, id.ContainerName, id.AccountName) + log.Printf("[DEBUG] Updating MetaData for %s...", id) metaDataRaw := d.Get("metadata").(map[string]interface{}) input := blobs.SetMetaDataInput{ MetaData: ExpandMetaData(metaDataRaw), } - if _, err := blobsClient.SetMetaData(ctx, id.AccountName, id.ContainerName, id.BlobName, input); err != nil { - return fmt.Errorf("updating MetaData for Blob %q (Container %q / Account %q): %s", id.BlobName, id.ContainerName, id.AccountName, err) + if _, err = blobsClient.SetMetaData(ctx, id.ContainerName, id.BlobName, input); err != nil { + return fmt.Errorf("updating MetaData for %s: %v", id, err) } - log.Printf("[DEBUG] Updated MetaData for Blob %q (Container %q / Account %q).", id.BlobName, id.ContainerName, id.AccountName) + log.Printf("[DEBUG] Updated MetaData for %s", id) } if d.HasChange("access_tier") { // this is only applicable for Gen2/BlobStorage accounts - log.Printf("[DEBUG] Updating Access Tier for Blob %q (Container %q / Account %q)...", id.BlobName, id.ContainerName, id.AccountName) + log.Printf("[DEBUG] Updating Access Tier for %s...", id) accessTier := blobs.AccessTier(d.Get("access_tier").(string)) - if _, err := blobsClient.SetTier(ctx, id.AccountName, id.ContainerName, id.BlobName, accessTier); err != nil { - return fmt.Errorf("updating Access Tier for Blob %q (Container %q / Account %q): %s", id.BlobName, id.ContainerName, id.AccountName, err) + if _, err := blobsClient.SetTier(ctx, id.ContainerName, id.BlobName, blobs.SetTierInput{Tier: accessTier}); err != nil { + return fmt.Errorf("updating Access Tier for %s: %v", id, err) } - log.Printf("[DEBUG] Updated Access Tier for Blob %q (Container %q / Account %q).", id.BlobName, id.ContainerName, id.AccountName) + log.Printf("[DEBUG] Updated Access Tier for %s", id) } return resourceStorageBlobRead(d, meta) @@ -317,42 +326,42 @@ func resourceStorageBlobRead(d *pluginsdk.ResourceData, meta interface{}) error ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d) defer cancel() - id, err := blobs.ParseResourceID(d.Id()) + id, err := blobs.ParseBlobID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { - return fmt.Errorf("parsing %q: %s", d.Id(), err) + return fmt.Errorf("parsing %q: %v", d.Id(), err) } - account, err := storageClient.FindAccount(ctx, id.AccountName) + account, err := storageClient.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Blob %q (Container %q): %s", id.AccountName, id.BlobName, id.ContainerName, err) + return fmt.Errorf("retrieving Account %q for Blob %q (Container %q): %v", id.AccountId.AccountName, id.BlobName, id.ContainerName, err) } if account == nil { - log.Printf("[DEBUG] Unable to locate Account %q for Blob %q (Container %q) - assuming removed & removing from state!", id.AccountName, id.BlobName, id.ContainerName) + log.Printf("[DEBUG] Unable to locate Account %q for Blob %q (Container %q) - assuming removed & removing from state!", id.AccountId.AccountName, id.BlobName, id.ContainerName) d.SetId("") return nil } - blobsClient, err := storageClient.BlobsClient(ctx, *account) + blobsClient, err := storageClient.BlobsDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building Blobs Client: %s", err) + return fmt.Errorf("building Blobs Client: %v", err) } - log.Printf("[INFO] Retrieving Storage Blob %q (Container %q / Account %q).", id.BlobName, id.ContainerName, id.AccountName) + log.Printf("[INFO] Retrieving %s", id) input := blobs.GetPropertiesInput{} - props, err := blobsClient.GetProperties(ctx, id.AccountName, id.ContainerName, id.BlobName, input) + props, err := blobsClient.GetProperties(ctx, id.ContainerName, id.BlobName, input) if err != nil { - if utils.ResponseWasNotFound(props.Response) { - log.Printf("[INFO] Blob %q was not found in Container %q / Account %q - assuming removed & removing from state...", id.BlobName, id.ContainerName, id.AccountName) + if response.WasNotFound(props.HttpResponse) { + log.Printf("[INFO] Blob %q was not found in Container %q / Account %q - assuming removed & removing from state...", id.BlobName, id.ContainerName, id.AccountId.AccountName) d.SetId("") return nil } - return fmt.Errorf("retrieving properties for Blob %q (Container %q / Account %q): %s", id.BlobName, id.ContainerName, id.AccountName, err) + return fmt.Errorf("retrieving properties for %s: %v", id, err) } d.Set("name", id.BlobName) d.Set("storage_container_name", id.ContainerName) - d.Set("storage_account_name", id.AccountName) + d.Set("storage_account_name", id.AccountId.AccountName) d.Set("access_tier", string(props.AccessTier)) d.Set("content_type", props.ContentType) @@ -363,7 +372,7 @@ func resourceStorageBlobRead(d *pluginsdk.ResourceData, meta interface{}) error if props.ContentMD5 != "" { contentMD5, err = convertBase64ToHexEncoding(props.ContentMD5) if err != nil { - return fmt.Errorf("in converting hex to base64 encoding for content_md5: %s", err) + return fmt.Errorf("converting hex to base64 encoding for content_md5: %v", err) } } d.Set("content_md5", contentMD5) @@ -371,8 +380,8 @@ func resourceStorageBlobRead(d *pluginsdk.ResourceData, meta interface{}) error d.Set("type", strings.TrimSuffix(string(props.BlobType), "Blob")) d.Set("url", d.Id()) - if err := d.Set("metadata", FlattenMetaData(props.MetaData)); err != nil { - return fmt.Errorf("setting `metadata`: %+v", err) + if err = d.Set("metadata", FlattenMetaData(props.MetaData)); err != nil { + return fmt.Errorf("setting `metadata`: %v", err) } // The CopySource is only returned if the blob hasn't been modified (e.g. metadata configured etc) // as such, we need to conditionally set this to ensure it's trackable if possible @@ -388,30 +397,29 @@ func resourceStorageBlobDelete(d *pluginsdk.ResourceData, meta interface{}) erro ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d) defer cancel() - id, err := blobs.ParseResourceID(d.Id()) + id, err := blobs.ParseBlobID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { - return fmt.Errorf("parsing %q: %s", d.Id(), err) + return fmt.Errorf("parsing %q: %v", d.Id(), err) } - account, err := storageClient.FindAccount(ctx, id.AccountName) + account, err := storageClient.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Blob %q (Container %q): %s", id.AccountName, id.BlobName, id.ContainerName, err) + return fmt.Errorf("retrieving Account %q for Blob %q (Container %q): %s", id.AccountId.AccountName, id.BlobName, id.ContainerName, err) } if account == nil { - return fmt.Errorf("Unable to locate Storage Account %q!", id.AccountName) + return fmt.Errorf("locating Storage Account %q", id.AccountId.AccountName) } - blobsClient, err := storageClient.BlobsClient(ctx, *account) + blobsClient, err := storageClient.BlobsDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building Blobs Client: %s", err) + return fmt.Errorf("building Blobs Client: %v", err) } - log.Printf("[INFO] Deleting Blob %q from Container %q / Storage Account %q", id.BlobName, id.ContainerName, id.AccountName) input := blobs.DeleteInput{ DeleteSnapshots: true, } - if _, err := blobsClient.Delete(ctx, id.AccountName, id.ContainerName, id.BlobName, input); err != nil { - return fmt.Errorf("deleting Blob %q (Container %q / Account %q): %s", id.BlobName, id.ContainerName, id.AccountName, err) + if _, err = blobsClient.Delete(ctx, id.ContainerName, id.BlobName, input); err != nil { + return fmt.Errorf("deleting %s: %v", id, err) } return nil diff --git a/internal/services/storage/storage_blob_resource_test.go b/internal/services/storage/storage_blob_resource_test.go index 8f050af524f5d..9a0c6d3b2ba3f 100644 --- a/internal/services/storage/storage_blob_resource_test.go +++ b/internal/services/storage/storage_blob_resource_test.go @@ -10,13 +10,15 @@ import ( "os" "regexp" "testing" + "time" + "github.com/hashicorp/go-azure-helpers/lang/response" "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance" "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/utils" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs" ) type StorageBlobResource struct{} @@ -469,56 +471,62 @@ func TestAccStorageBlob_archive(t *testing.T) { } func (r StorageBlobResource) Exists(ctx context.Context, client *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { - id, err := blobs.ParseResourceID(state.ID) + id, err := blobs.ParseBlobID(state.ID, client.Storage.StorageDomainSuffix) if err != nil { return nil, err } - account, err := client.Storage.FindAccount(ctx, id.AccountName) + account, err := client.Storage.FindAccount(ctx, id.AccountId.AccountName) if err != nil { return nil, err } if account == nil { - return nil, fmt.Errorf("unable to locate Account %q for Blob %q (Container %q)", id.AccountName, id.BlobName, id.ContainerName) + return nil, fmt.Errorf("unable to locate Account %q for Blob %q (Container %q)", id.AccountId.AccountName, id.BlobName, id.ContainerName) } - blobsClient, err := client.Storage.BlobsClient(ctx, *account) + blobsClient, err := client.Storage.BlobsDataPlaneClient(ctx, *account, client.Storage.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { return nil, fmt.Errorf("building Blobs Client: %+v", err) } input := blobs.GetPropertiesInput{} - resp, err := blobsClient.GetProperties(ctx, id.AccountName, id.ContainerName, id.BlobName, input) + resp, err := blobsClient.GetProperties(ctx, id.ContainerName, id.BlobName, input) if err != nil { - if utils.ResponseWasNotFound(resp.Response) { + if response.WasNotFound(resp.HttpResponse) { return utils.Bool(false), nil } - return nil, fmt.Errorf("retrieving Blob %q (Container %q / Account %q): %+v", id.BlobName, id.ContainerName, id.AccountName, err) + return nil, fmt.Errorf("retrieving Blob %q (Container %q / Account %q): %+v", id.BlobName, id.ContainerName, id.AccountId.AccountName, err) } return utils.Bool(true), nil } func (r StorageBlobResource) Destroy(ctx context.Context, client *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { - id, err := blobs.ParseResourceID(state.ID) + id, err := blobs.ParseBlobID(state.ID, client.Storage.StorageDomainSuffix) if err != nil { return nil, err } - account, err := client.Storage.FindAccount(ctx, id.AccountName) + account, err := client.Storage.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return nil, fmt.Errorf("retrievign Account %q for Blob %q (Container %q): %+v", id.AccountName, id.BlobName, id.ContainerName, err) + return nil, fmt.Errorf("retrieving Account %q for Blob %q (Container %q): %+v", id.AccountId.AccountName, id.BlobName, id.ContainerName, err) } - blobsClient, err := client.Storage.BlobsClient(ctx, *account) + blobsClient, err := client.Storage.BlobsDataPlaneClient(ctx, *account, client.Storage.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { return nil, fmt.Errorf("building Blobs Client: %+v", err) } input := blobs.DeleteInput{ DeleteSnapshots: false, } - if _, err := blobsClient.Delete(ctx, id.AccountName, id.ContainerName, id.BlobName, input); err != nil { - return nil, fmt.Errorf("deleting Blob %q (Container %q / Account %q): %+v", id.BlobName, id.ContainerName, id.AccountName, err) + if _, err = blobsClient.Delete(ctx, id.ContainerName, id.BlobName, input); err != nil { + return nil, fmt.Errorf("deleting Blob %q (Container %q / Account %q): %+v", id.BlobName, id.ContainerName, id.AccountId.AccountName, err) } return utils.Bool(true), nil } func (r StorageBlobResource) blobMatchesFile(kind blobs.BlobType, filePath string) func(ctx context.Context, clients *clients.Client, state *pluginsdk.InstanceState) error { return func(ctx context.Context, clients *clients.Client, state *pluginsdk.InstanceState) error { + if _, ok := ctx.Deadline(); !ok { + var cancel context.CancelFunc + ctx, cancel = context.WithDeadline(ctx, time.Now().Add(10*time.Minute)) + defer cancel() + } + name := state.Attributes["name"] containerName := state.Attributes["storage_container_name"] accountName := state.Attributes["storage_account_name"] @@ -531,14 +539,14 @@ func (r StorageBlobResource) blobMatchesFile(kind blobs.BlobType, filePath strin return fmt.Errorf("Unable to locate Storage Account %q!", accountName) } - client, err := clients.Storage.BlobsClient(ctx, *account) + client, err := clients.Storage.BlobsDataPlaneClient(ctx, *account, clients.Storage.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { return fmt.Errorf("building Blobs Client: %s", err) } // first check the type getPropsInput := blobs.GetPropertiesInput{} - props, err := client.GetProperties(ctx, accountName, containerName, name, getPropsInput) + props, err := client.GetProperties(ctx, containerName, name, getPropsInput) if err != nil { return fmt.Errorf("retrieving Properties for Blob %q (Container %q): %s", name, containerName, err) } @@ -549,20 +557,24 @@ func (r StorageBlobResource) blobMatchesFile(kind blobs.BlobType, filePath strin // then compare the content itself getInput := blobs.GetInput{} - actualProps, err := client.Get(ctx, accountName, containerName, name, getInput) + actualProps, err := client.Get(ctx, containerName, name, getInput) if err != nil { return fmt.Errorf("retrieving Blob %q (Container %q): %s", name, containerName, err) } actualContents := actualProps.Contents + if actualContents == nil { + return fmt.Errorf("Bad: Storage Blob %q (storage container: %q) returned nil contents", name, containerName) + } + // local file for comparison expectedContents, err := os.ReadFile(filePath) if err != nil { return err } - if string(actualContents) != string(expectedContents) { + if string(*actualContents) != string(expectedContents) { return fmt.Errorf("Bad: Storage Blob %q (storage container: %q) does not match contents", name, containerName) } diff --git a/internal/services/storage/storage_container_data_source.go b/internal/services/storage/storage_container_data_source.go index dc7a74da8ef0c..a8988bbd8fe1e 100644 --- a/internal/services/storage/storage_container_data_source.go +++ b/internal/services/storage/storage_container_data_source.go @@ -69,34 +69,35 @@ func dataSourceStorageContainerRead(d *pluginsdk.ResourceData, meta interface{}) account, err := storageClient.FindAccount(ctx, accountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Container %q: %s", accountName, containerName, err) + return fmt.Errorf("retrieving Storage Account %q for Container %q: %v", accountName, containerName, err) } if account == nil { - return fmt.Errorf("Unable to locate Account %q for Storage Container %q", accountName, containerName) + return fmt.Errorf("locating Storage Account %q for Container %q", accountName, containerName) } - client, err := storageClient.ContainersClient(ctx, *account) + client, err := storageClient.ContainersDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building Containers Client for Storage Account %q (Resource Group %q): %s", accountName, account.ResourceGroup, err) + return fmt.Errorf("building Containers Client: %v", err) } - id := parse.NewStorageContainerDataPlaneId(accountName, storageClient.Environment.StorageEndpointSuffix, containerName).ID() - d.SetId(id) + id := parse.NewStorageContainerDataPlaneId(accountName, storageClient.AzureEnvironment.StorageEndpointSuffix, containerName) - props, err := client.Get(ctx, account.ResourceGroup, accountName, containerName) + props, err := client.Get(ctx, containerName) if err != nil { - return fmt.Errorf("retrieving Container %q (Account %q / Resource Group %q): %s", containerName, accountName, account.ResourceGroup, err) + return fmt.Errorf("retrieving %s: %v", id, err) } if props == nil { - return fmt.Errorf("Container %q was not found in Account %q / Resource Group %q", containerName, accountName, account.ResourceGroup) + return fmt.Errorf("retrieving %s: result was nil", id) } + d.SetId(id.ID()) + d.Set("name", containerName) d.Set("storage_account_name", accountName) d.Set("container_access_type", flattenStorageContainerAccessLevel(props.AccessLevel)) - if err := d.Set("metadata", FlattenMetaData(props.MetaData)); err != nil { - return fmt.Errorf("setting `metadata`: %+v", err) + if err = d.Set("metadata", FlattenMetaData(props.MetaData)); err != nil { + return fmt.Errorf("setting `metadata`: %v", err) } d.Set("has_immutability_policy", props.HasImmutabilityPolicy) diff --git a/internal/services/storage/storage_container_resource.go b/internal/services/storage/storage_container_resource.go index c4dc99de623e2..7237d42331def 100644 --- a/internal/services/storage/storage_container_resource.go +++ b/internal/services/storage/storage_container_resource.go @@ -11,13 +11,14 @@ import ( "github.com/hashicorp/go-azure-helpers/resourcemanager/commonids" "github.com/hashicorp/terraform-provider-azurerm/helpers/tf" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/helpers" "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/migration" "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/parse" "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/validate" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" "github.com/hashicorp/terraform-provider-azurerm/internal/timeouts" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers" ) func resourceStorageContainer() *pluginsdk.Resource { @@ -27,8 +28,8 @@ func resourceStorageContainer() *pluginsdk.Resource { Delete: resourceStorageContainerDelete, Update: resourceStorageContainerUpdate, - Importer: pluginsdk.ImporterValidatingResourceId(func(id string) error { - _, err := parse.StorageContainerDataPlaneID(id) + Importer: helpers.ImporterValidatingStorageResourceId(func(id, storageDomainSuffix string) error { + _, err := parse.StorageContainerDataPlaneID(id, storageDomainSuffix) return err }), @@ -106,37 +107,39 @@ func resourceStorageContainerCreate(d *pluginsdk.ResourceData, meta interface{}) account, err := storageClient.FindAccount(ctx, accountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Container %q: %s", accountName, containerName, err) + return fmt.Errorf("retrieving Account %q for Container %q: %v", accountName, containerName, err) } if account == nil { - return fmt.Errorf("Unable to locate Storage Account %q!", accountName) + return fmt.Errorf("locating Storage Account %q", accountName) } - client, err := storageClient.ContainersClient(ctx, *account) + client, err := storageClient.ContainersDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building storage client: %+v", err) + return fmt.Errorf("building storage client: %v", err) } - id := parse.NewStorageContainerDataPlaneId(accountName, storageClient.Environment.StorageEndpointSuffix, containerName).ID() - exists, err := client.Exists(ctx, account.ResourceGroup, accountName, containerName) + id := parse.NewStorageContainerDataPlaneId(accountName, storageClient.AzureEnvironment.StorageEndpointSuffix, containerName) + + exists, err := client.Exists(ctx, containerName) if err != nil { - return err + return fmt.Errorf("checking for existing %s: %v", id, err) } if exists != nil && *exists { - return tf.ImportAsExistsError("azurerm_storage_container", id) + return tf.ImportAsExistsError("azurerm_storage_container", id.ID()) } - log.Printf("[INFO] Creating Container %q in Storage Account %q", containerName, accountName) + log.Printf("[INFO] Creating %s", id) input := containers.CreateInput{ AccessLevel: accessLevel, MetaData: metaData, } - if err := client.Create(ctx, account.ResourceGroup, accountName, containerName, input); err != nil { - return fmt.Errorf("failed creating container: %+v", err) + if err = client.Create(ctx, containerName, input); err != nil { + return fmt.Errorf("creating %s: %v", id, err) } - d.SetId(id) + d.SetId(id.ID()) + return resourceStorageContainerRead(d, meta) } @@ -145,45 +148,54 @@ func resourceStorageContainerUpdate(d *pluginsdk.ResourceData, meta interface{}) ctx, cancel := timeouts.ForUpdate(meta.(*clients.Client).StopContext, d) defer cancel() - id, err := parse.StorageContainerDataPlaneID(d.Id()) + id, err := parse.StorageContainerDataPlaneID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { return err } account, err := storageClient.FindAccount(ctx, id.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Container %q: %s", id.AccountName, id.Name, err) + return fmt.Errorf("retrieving Account %q for Container %q: %v", id.AccountName, id.Name, err) } if account == nil { - return fmt.Errorf("Unable to locate Storage Account %q!", id.AccountName) - } - client, err := storageClient.ContainersClient(ctx, *account) - if err != nil { - return fmt.Errorf("building Containers Client for Storage Account %q (Resource Group %q): %s", id.AccountName, account.ResourceGroup, err) + return fmt.Errorf("locating Storage Account %q", id.AccountName) } if d.HasChange("container_access_type") { - log.Printf("[DEBUG] Updating the Access Control for Container %q (Storage Account %q / Resource Group %q)..", id.Name, id.AccountName, account.ResourceGroup) + log.Printf("[DEBUG] Updating Access Level for %s...", id) + + // Updating metadata does not work with AAD authentication, returns a cryptic 404 + client, err := storageClient.ContainersDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingOnlySharedKeyAuth()) + if err != nil { + return fmt.Errorf("building Containers Client: %v", err) + } + accessLevelRaw := d.Get("container_access_type").(string) accessLevel := expandStorageContainerAccessLevel(accessLevelRaw) - if err := client.UpdateAccessLevel(ctx, account.ResourceGroup, id.AccountName, id.Name, accessLevel); err != nil { - return fmt.Errorf("updating the Access Control for Container %q (Storage Account %q / Resource Group %q): %s", id.Name, id.AccountName, account.ResourceGroup, err) + if err = client.UpdateAccessLevel(ctx, id.Name, accessLevel); err != nil { + return fmt.Errorf("updating Access Level for %s: %v", id, err) } - log.Printf("[DEBUG] Updated the Access Control for Container %q (Storage Account %q / Resource Group %q)", id.Name, id.AccountName, account.ResourceGroup) + log.Printf("[DEBUG] Updated Access Level for %s", id) } if d.HasChange("metadata") { - log.Printf("[DEBUG] Updating the MetaData for Container %q (Storage Account %q / Resource Group %q)..", id.Name, id.AccountName, account.ResourceGroup) + log.Printf("[DEBUG] Updating Metadata for %s...", id) + + client, err := storageClient.ContainersDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) + if err != nil { + return fmt.Errorf("building Containers Client: %v", err) + } + metaDataRaw := d.Get("metadata").(map[string]interface{}) metaData := ExpandMetaData(metaDataRaw) - if err := client.UpdateMetaData(ctx, account.ResourceGroup, id.AccountName, id.Name, metaData); err != nil { - return fmt.Errorf("updating the MetaData for Container %q (Storage Account %q / Resource Group %q): %s", id.Name, id.AccountName, account.ResourceGroup, err) + if err = client.UpdateMetaData(ctx, id.Name, metaData); err != nil { + return fmt.Errorf("updating Metadata for %s: %v", id, err) } - log.Printf("[DEBUG] Updated the MetaData for Container %q (Storage Account %q / Resource Group %q)", id.Name, id.AccountName, account.ResourceGroup) + log.Printf("[DEBUG] Updated Metadata for %s", id) } return resourceStorageContainerRead(d, meta) @@ -195,28 +207,29 @@ func resourceStorageContainerRead(d *pluginsdk.ResourceData, meta interface{}) e ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d) defer cancel() - id, err := parse.StorageContainerDataPlaneID(d.Id()) + id, err := parse.StorageContainerDataPlaneID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { return err } account, err := storageClient.FindAccount(ctx, id.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Container %q: %s", id.AccountName, id.Name, err) + return fmt.Errorf("retrieving Account %q for Container %q: %v", id.AccountName, id.Name, err) } if account == nil { log.Printf("[DEBUG] Unable to locate Account %q for Storage Container %q - assuming removed & removing from state", id.AccountName, id.Name) d.SetId("") return nil } - client, err := storageClient.ContainersClient(ctx, *account) + + client, err := storageClient.ContainersDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building Containers Client for Storage Account %q (Resource Group %q): %s", id.AccountName, account.ResourceGroup, err) + return fmt.Errorf("building Containers Client: %v", err) } - props, err := client.Get(ctx, account.ResourceGroup, id.AccountName, id.Name) + props, err := client.Get(ctx, id.Name) if err != nil { - return fmt.Errorf("retrieving Container %q (Account %q / Resource Group %q): %s", id.Name, id.AccountName, account.ResourceGroup, err) + return fmt.Errorf("retrieving %s: %v", id, err) } if props == nil { log.Printf("[DEBUG] Container %q was not found in Account %q / Resource Group %q - assuming removed & removing from state", id.Name, id.AccountName, account.ResourceGroup) @@ -229,8 +242,8 @@ func resourceStorageContainerRead(d *pluginsdk.ResourceData, meta interface{}) e d.Set("container_access_type", flattenStorageContainerAccessLevel(props.AccessLevel)) - if err := d.Set("metadata", FlattenMetaData(props.MetaData)); err != nil { - return fmt.Errorf("setting `metadata`: %+v", err) + if err = d.Set("metadata", FlattenMetaData(props.MetaData)); err != nil { + return fmt.Errorf("setting `metadata`: %v", err) } d.Set("has_immutability_policy", props.HasImmutabilityPolicy) @@ -247,25 +260,26 @@ func resourceStorageContainerDelete(d *pluginsdk.ResourceData, meta interface{}) ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d) defer cancel() - id, err := parse.StorageContainerDataPlaneID(d.Id()) + id, err := parse.StorageContainerDataPlaneID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { return err } account, err := storageClient.FindAccount(ctx, id.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Container %q: %s", id.AccountName, id.Name, err) + return fmt.Errorf("retrieving Account %q for Container %q: %v", id.AccountName, id.Name, err) } if account == nil { - return fmt.Errorf("Unable to locate Storage Account %q!", id.AccountName) + return fmt.Errorf("locating Storage Account %q", id.AccountName) } - client, err := storageClient.ContainersClient(ctx, *account) + + client, err := storageClient.ContainersDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building Containers Client for Storage Account %q (Resource Group %q): %s", id.AccountName, account.ResourceGroup, err) + return fmt.Errorf("building Containers Client: %v", err) } - if err := client.Delete(ctx, account.ResourceGroup, id.AccountName, id.Name); err != nil { - return fmt.Errorf("deleting Container %q (Storage Account %q / Resource Group %q): %s", id.Name, id.AccountName, account.ResourceGroup, err) + if err = client.Delete(ctx, id.Name); err != nil { + return fmt.Errorf("deleting %s: %v", id, err) } return nil diff --git a/internal/services/storage/storage_container_resource_test.go b/internal/services/storage/storage_container_resource_test.go index cf0a8c0ae07b5..759735e4ed865 100644 --- a/internal/services/storage/storage_container_resource_test.go +++ b/internal/services/storage/storage_container_resource_test.go @@ -96,14 +96,14 @@ func TestAccStorageContainer_update(t *testing.T) { data.ResourceTest(t, r, []acceptance.TestStep{ { - Config: r.update(data, "private"), + Config: r.update(data, "private", "yes"), Check: acceptance.ComposeTestCheckFunc( check.That(data.ResourceName).ExistsInAzure(r), check.That(data.ResourceName).Key("container_access_type").HasValue("private"), ), }, { - Config: r.update(data, "container"), + Config: r.update(data, "container", "no"), Check: acceptance.ComposeTestCheckFunc( check.That(data.ResourceName).ExistsInAzure(r), check.That(data.ResourceName).Key("container_access_type").HasValue("container"), @@ -187,7 +187,7 @@ func TestAccStorageContainer_web(t *testing.T) { } func (r StorageContainerResource) Exists(ctx context.Context, client *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { - id, err := parse.StorageContainerDataPlaneID(state.ID) + id, err := parse.StorageContainerDataPlaneID(state.ID, client.Storage.StorageDomainSuffix) if err != nil { return nil, err } @@ -199,11 +199,11 @@ func (r StorageContainerResource) Exists(ctx context.Context, client *clients.Cl return nil, fmt.Errorf("unable to locate Storage Account %q", id.AccountName) } - containersClient, err := client.Storage.ContainersClient(ctx, *account) + containersClient, err := client.Storage.ContainersDataPlaneClient(ctx, *account, client.Storage.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { return nil, fmt.Errorf("building Containers Client: %+v", err) } - prop, err := containersClient.Get(ctx, account.ResourceGroup, id.AccountName, id.Name) + prop, err := containersClient.Get(ctx, id.Name) if err != nil { return nil, fmt.Errorf("retrieving Container %q (Account %q / Resource Group %q): %+v", id.Name, id.AccountName, account.ResourceGroup, err) } @@ -211,7 +211,7 @@ func (r StorageContainerResource) Exists(ctx context.Context, client *clients.Cl } func (r StorageContainerResource) Destroy(ctx context.Context, client *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { - id, err := parse.StorageContainerDataPlaneID(state.ID) + id, err := parse.StorageContainerDataPlaneID(state.ID, client.Storage.StorageDomainSuffix) if err != nil { return nil, err } @@ -222,11 +222,11 @@ func (r StorageContainerResource) Destroy(ctx context.Context, client *clients.C if account == nil { return nil, fmt.Errorf("unable to locate Storage Account %q", id.AccountName) } - containersClient, err := client.Storage.ContainersClient(ctx, *account) + containersClient, err := client.Storage.ContainersDataPlaneClient(ctx, *account, client.Storage.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { return nil, fmt.Errorf("building Containers Client: %+v", err) } - if err := containersClient.Delete(ctx, account.ResourceGroup, id.AccountName, id.Name); err != nil { + if err := containersClient.Delete(ctx, id.Name); err != nil { return nil, fmt.Errorf("deleting Container %q (Account %q / Resource Group %q): %+v", id.Name, id.AccountName, account.ResourceGroup, err) } return utils.Bool(true), nil @@ -290,7 +290,7 @@ resource "azurerm_storage_container" "import" { `, template) } -func (r StorageContainerResource) update(data acceptance.TestData, accessType string) string { +func (r StorageContainerResource) update(data acceptance.TestData, accessType, metadataVal string) string { template := r.template(data) return fmt.Sprintf(` %s @@ -299,8 +299,12 @@ resource "azurerm_storage_container" "test" { name = "vhds" storage_account_name = azurerm_storage_account.test.name container_access_type = "%s" + metadata = { + foo = "bar" + test = "%s" + } } -`, template, accessType) +`, template, accessType, metadataVal) } func (r StorageContainerResource) metaData(data acceptance.TestData) string { diff --git a/internal/services/storage/storage_containers_data_source.go b/internal/services/storage/storage_containers_data_source.go index 40c5ec7ff49a8..dd82a159bc3f9 100644 --- a/internal/services/storage/storage_containers_data_source.go +++ b/internal/services/storage/storage_containers_data_source.go @@ -103,7 +103,7 @@ func (r storageContainersDataSource) Read() sdk.ResourceFunc { return fmt.Errorf("retrieving %s: %+v", id, err) } - plan.Containers = flattenStorageContainersContainers(resp.Items, id.StorageAccountName, metadata.Client.Storage.Environment.StorageEndpointSuffix, plan.NamePrefix) + plan.Containers = flattenStorageContainersContainers(resp.Items, id.StorageAccountName, metadata.Client.Storage.AzureEnvironment.StorageEndpointSuffix, plan.NamePrefix) if err := metadata.Encode(&plan); err != nil { return fmt.Errorf("encoding %s: %+v", id, err) diff --git a/internal/services/storage/storage_data_lake_gen2_filesystem_resource.go b/internal/services/storage/storage_data_lake_gen2_filesystem_resource.go index 4998f22fc693b..ab968ed009c1e 100644 --- a/internal/services/storage/storage_data_lake_gen2_filesystem_resource.go +++ b/internal/services/storage/storage_data_lake_gen2_filesystem_resource.go @@ -10,6 +10,7 @@ import ( "regexp" "time" + "github.com/hashicorp/go-azure-helpers/lang/response" "github.com/hashicorp/go-azure-helpers/resourcemanager/commonids" "github.com/hashicorp/terraform-provider-azurerm/helpers/tf" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" @@ -18,8 +19,9 @@ import ( "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" "github.com/hashicorp/terraform-provider-azurerm/internal/timeouts" "github.com/hashicorp/terraform-provider-azurerm/utils" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths" "github.com/tombuildsstuff/giovanni/storage/accesscontrol" ) @@ -31,22 +33,22 @@ func resourceStorageDataLakeGen2FileSystem() *pluginsdk.Resource { Delete: resourceStorageDataLakeGen2FileSystemDelete, Importer: pluginsdk.ImporterValidatingResourceIdThen(func(id string) error { - _, err := filesystems.ParseResourceID(id) + _, err := filesystems.ParseFileSystemID(id, "") // TODO: actual domain suffix needed here! return err }, func(ctx context.Context, d *pluginsdk.ResourceData, meta interface{}) ([]*pluginsdk.ResourceData, error) { storageClients := meta.(*clients.Client).Storage - id, err := filesystems.ParseResourceID(d.Id()) + id, err := filesystems.ParseFileSystemID(d.Id(), "") // TODO: actual domain suffix needed here! if err != nil { return []*pluginsdk.ResourceData{d}, fmt.Errorf("parsing ID %q for import of Data Lake Gen2 File System: %v", d.Id(), err) } // we then need to look up the Storage Account ID - account, err := storageClients.FindAccount(ctx, id.AccountName) + account, err := storageClients.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return []*pluginsdk.ResourceData{d}, fmt.Errorf("retrieving Account %q for Data Lake Gen2 File System %q: %s", id.AccountName, id.DirectoryName, err) + return []*pluginsdk.ResourceData{d}, fmt.Errorf("retrieving Account %q for Data Lake Gen2 File System %q: %s", id.AccountId.AccountName, id.FileSystemName, err) } if account == nil { - return []*pluginsdk.ResourceData{d}, fmt.Errorf("Unable to locate Storage Account %q!", id.AccountName) + return []*pluginsdk.ResourceData{d}, fmt.Errorf("Unable to locate Storage Account %q!", id.AccountId.AccountName) } d.Set("storage_account_id", account.ID) @@ -127,31 +129,32 @@ func resourceStorageDataLakeGen2FileSystem() *pluginsdk.Resource { } func resourceStorageDataLakeGen2FileSystemCreate(d *pluginsdk.ResourceData, meta interface{}) error { - accountsClient := meta.(*clients.Client).Storage.AccountsClient - client := meta.(*clients.Client).Storage.FileSystemsClient - pathClient := meta.(*clients.Client).Storage.ADLSGen2PathsClient + storageClient := meta.(*clients.Client).Storage + accountsClient := storageClient.AccountsClient + client := storageClient.FileSystemsClient + pathClient := storageClient.ADLSGen2PathsClient ctx, cancel := timeouts.ForCreate(meta.(*clients.Client).StopContext, d) defer cancel() - storageID, err := commonids.ParseStorageAccountID(d.Get("storage_account_id").(string)) + storageId, err := commonids.ParseStorageAccountID(d.Get("storage_account_id").(string)) if err != nil { return err } - aceRaw := d.Get("ace").(*pluginsdk.Set).List() - acl, err := ExpandDataLakeGen2AceList(aceRaw) - if err != nil { - return fmt.Errorf("parsing ace list: %s", err) - } - // confirm the storage account exists, otherwise Data Plane API requests will fail - storageAccount, err := accountsClient.GetProperties(ctx, storageID.ResourceGroupName, storageID.StorageAccountName, "") + storageAccount, err := accountsClient.GetProperties(ctx, storageId.ResourceGroupName, storageId.StorageAccountName, "") if err != nil { if utils.ResponseWasNotFound(storageAccount.Response) { - return fmt.Errorf("%s was not found", storageID) + return fmt.Errorf("%s was not found", storageId) } - return fmt.Errorf("checking for existence of %s: %+v", storageID, err) + return fmt.Errorf("checking for existence of %s: %v", storageId, err) + } + + aceRaw := d.Get("ace").(*pluginsdk.Set).List() + acl, err := ExpandDataLakeGen2AceList(aceRaw) + if err != nil { + return fmt.Errorf("parsing ace list: %v", err) } if acl != nil && (storageAccount.AccountProperties == nil || @@ -164,25 +167,30 @@ func resourceStorageDataLakeGen2FileSystemCreate(d *pluginsdk.ResourceData, meta propertiesRaw := d.Get("properties").(map[string]interface{}) properties := ExpandMetaData(propertiesRaw) - id := client.GetResourceID(storageID.StorageAccountName, fileSystemName) + accountId, err := accounts.ParseAccountID(d.Get("storage_account_id").(string), storageClient.StorageDomainSuffix) + if err != nil { + return fmt.Errorf("parsing Account ID: %v", err) + } + + id := filesystems.NewFileSystemID(*accountId, fileSystemName) - resp, err := client.GetProperties(ctx, storageID.StorageAccountName, fileSystemName) + resp, err := client.GetProperties(ctx, fileSystemName) if err != nil { - if !utils.ResponseWasNotFound(resp.Response) { - return fmt.Errorf("checking for existence of existing File System %q in %s: %+v", fileSystemName, storageID, err) + if !response.WasNotFound(resp.HttpResponse) { + return fmt.Errorf("checking for existence of existing File System %q in %s: %v", fileSystemName, accountId, err) } } - if !utils.ResponseWasNotFound(resp.Response) { - return tf.ImportAsExistsError("azurerm_storage_data_lake_gen2_filesystem", id) + if !response.WasNotFound(resp.HttpResponse) { + return tf.ImportAsExistsError("azurerm_storage_data_lake_gen2_filesystem", id.ID()) } - log.Printf("[INFO] Creating File System %q in %s.", fileSystemName, storageID) + log.Printf("[INFO] Creating %s...", id) input := filesystems.CreateInput{ Properties: properties, } - if _, err := client.Create(ctx, storageID.StorageAccountName, fileSystemName, input); err != nil { - return fmt.Errorf("creating File System %q in %s: %+v", fileSystemName, storageID, err) + if _, err = client.Create(ctx, fileSystemName, input); err != nil { + return fmt.Errorf("creating %s: %v", id, err) } var owner *string @@ -199,7 +207,7 @@ func resourceStorageDataLakeGen2FileSystemCreate(d *pluginsdk.ResourceData, meta if acl != nil || owner != nil || group != nil { var aclString *string if acl != nil { - log.Printf("[INFO] Creating acl %q in File System %q in %s", acl, fileSystemName, storageID) + log.Printf("[INFO] Creating ACL %q for %s", acl, id) v := acl.String() aclString = &v } @@ -208,23 +216,24 @@ func resourceStorageDataLakeGen2FileSystemCreate(d *pluginsdk.ResourceData, meta Owner: owner, Group: group, } - if _, err := pathClient.SetAccessControl(ctx, storageID.StorageAccountName, fileSystemName, "/", accessControlInput); err != nil { - return fmt.Errorf("setting access control for root path in File System %q in %s: %+v", fileSystemName, storageID, err) + if _, err = pathClient.SetAccessControl(ctx, fileSystemName, "/", accessControlInput); err != nil { + return fmt.Errorf("setting access control for root path in File System %q in %s: %v", fileSystemName, accountId, err) } } - d.SetId(id) + d.SetId(id.ID()) return resourceStorageDataLakeGen2FileSystemRead(d, meta) } func resourceStorageDataLakeGen2FileSystemUpdate(d *pluginsdk.ResourceData, meta interface{}) error { - accountsClient := meta.(*clients.Client).Storage.AccountsClient - client := meta.(*clients.Client).Storage.FileSystemsClient - pathClient := meta.(*clients.Client).Storage.ADLSGen2PathsClient + storageClient := meta.(*clients.Client).Storage + accountsClient := storageClient.AccountsClient + client := storageClient.FileSystemsClient + pathClient := storageClient.ADLSGen2PathsClient ctx, cancel := timeouts.ForUpdate(meta.(*clients.Client).StopContext, d) defer cancel() - id, err := filesystems.ParseResourceID(d.Id()) + id, err := filesystems.ParseFileSystemID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { return err } @@ -237,7 +246,7 @@ func resourceStorageDataLakeGen2FileSystemUpdate(d *pluginsdk.ResourceData, meta aceRaw := d.Get("ace").(*pluginsdk.Set).List() acl, err := ExpandDataLakeGen2AceList(aceRaw) if err != nil { - return fmt.Errorf("parsing ace list: %s", err) + return fmt.Errorf("parsing ace list: %v", err) } // confirm the storage account exists, otherwise Data Plane API requests will fail @@ -247,7 +256,7 @@ func resourceStorageDataLakeGen2FileSystemUpdate(d *pluginsdk.ResourceData, meta return fmt.Errorf("%s was not found", storageId) } - return fmt.Errorf("checking for existence of %s: %+v", storageId, err) + return fmt.Errorf("checking for existence of %s: %v", storageId, err) } if acl != nil && (storageAccount.AccountProperties == nil || @@ -259,12 +268,12 @@ func resourceStorageDataLakeGen2FileSystemUpdate(d *pluginsdk.ResourceData, meta propertiesRaw := d.Get("properties").(map[string]interface{}) properties := ExpandMetaData(propertiesRaw) - log.Printf("[INFO] Updating Properties for File System %q in Storage Account %q.", id.DirectoryName, id.AccountName) + log.Printf("[INFO] Updating Properties for %s...", id) input := filesystems.SetPropertiesInput{ Properties: properties, } - if _, err = client.SetProperties(ctx, id.AccountName, id.DirectoryName, input); err != nil { - return fmt.Errorf("updating Properties for File System %q in Storage Account %q: %s", id.DirectoryName, id.AccountName, err) + if _, err = client.SetProperties(ctx, id.FileSystemName, input); err != nil { + return fmt.Errorf("updating Properties for %s: %v", id, err) } var owner *string @@ -281,7 +290,7 @@ func resourceStorageDataLakeGen2FileSystemUpdate(d *pluginsdk.ResourceData, meta if acl != nil || owner != nil || group != nil { var aclString *string if acl != nil { - log.Printf("[INFO] Creating acl %q in File System %q in Storage Account %q.", acl, id.DirectoryName, id.AccountName) + log.Printf("[INFO] Creating ACL %q for %s...", acl, id) v := acl.String() aclString = &v } @@ -290,8 +299,8 @@ func resourceStorageDataLakeGen2FileSystemUpdate(d *pluginsdk.ResourceData, meta Owner: owner, Group: group, } - if _, err := pathClient.SetAccessControl(ctx, id.AccountName, id.DirectoryName, "/", accessControlInput); err != nil { - return fmt.Errorf("setting access control for root path in File System %q in Storage Account %q: %s", id.DirectoryName, id.AccountName, err) + if _, err = pathClient.SetAccessControl(ctx, id.FileSystemName, "/", accessControlInput); err != nil { + return fmt.Errorf("setting access control for root path in File System %q in Storage Account %q: %v", id.FileSystemName, id.AccountId.AccountName, err) } } @@ -299,49 +308,50 @@ func resourceStorageDataLakeGen2FileSystemUpdate(d *pluginsdk.ResourceData, meta } func resourceStorageDataLakeGen2FileSystemRead(d *pluginsdk.ResourceData, meta interface{}) error { - accountsClient := meta.(*clients.Client).Storage.AccountsClient - client := meta.(*clients.Client).Storage.FileSystemsClient - pathClient := meta.(*clients.Client).Storage.ADLSGen2PathsClient + storageClient := meta.(*clients.Client).Storage + accountsClient := storageClient.AccountsClient + client := storageClient.FileSystemsClient + pathClient := storageClient.ADLSGen2PathsClient ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d) defer cancel() - id, err := filesystems.ParseResourceID(d.Id()) + id, err := filesystems.ParseFileSystemID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { return err } - storageID, err := commonids.ParseStorageAccountID(d.Get("storage_account_id").(string)) + storageId, err := commonids.ParseStorageAccountID(d.Get("storage_account_id").(string)) if err != nil { return err } // confirm the storage account exists, otherwise Data Plane API requests will fail - storageAccount, err := accountsClient.GetProperties(ctx, storageID.ResourceGroupName, storageID.StorageAccountName, "") + storageAccount, err := accountsClient.GetProperties(ctx, storageId.ResourceGroupName, storageId.StorageAccountName, "") if err != nil { if utils.ResponseWasNotFound(storageAccount.Response) { - log.Printf("[INFO] Storage Account %q does not exist removing from state...", id.AccountName) + log.Printf("[INFO] Storage Account %q does not exist removing from state...", id.AccountId.AccountName) d.SetId("") return nil } - return fmt.Errorf("checking for existence of %s for File System %q: %+v", storageID, id.DirectoryName, err) + return fmt.Errorf("checking for existence of %s for File System %q: %+v", storageId, id.FileSystemName, err) } - resp, err := client.GetProperties(ctx, id.AccountName, id.DirectoryName) + resp, err := client.GetProperties(ctx, id.FileSystemName) if err != nil { - if utils.ResponseWasNotFound(resp.Response) { - log.Printf("[INFO] File System %q does not exist in Storage Account %q - removing from state...", id.DirectoryName, id.AccountName) + if response.WasNotFound(resp.HttpResponse) { + log.Printf("[INFO] File System %q does not exist in Storage Account %q - removing from state...", id.FileSystemName, id.AccountId.AccountName) d.SetId("") return nil } - return fmt.Errorf("retrieving File System %q in Storage Account %q: %+v", id.DirectoryName, id.AccountName, err) + return fmt.Errorf("retrieving %s: %v", id, err) } - d.Set("name", id.DirectoryName) + d.Set("name", id.FileSystemName) - if err := d.Set("properties", resp.Properties); err != nil { - return fmt.Errorf("setting `properties`: %+v", err) + if err = d.Set("properties", resp.Properties); err != nil { + return fmt.Errorf("setting `properties`: %v", err) } var ace []interface{} @@ -351,7 +361,7 @@ func resourceStorageDataLakeGen2FileSystemRead(d *pluginsdk.ResourceData, meta i *storageAccount.AccountProperties.IsHnsEnabled { // The above `getStatus` API request doesn't return the ACLs // Have to make a `getAccessControl` request, but that doesn't return all fields either! - pathResponse, err := pathClient.GetProperties(ctx, id.AccountName, id.DirectoryName, "/", paths.GetPropertiesActionGetAccessControl) + pathResponse, err := pathClient.GetProperties(ctx, id.FileSystemName, "/", paths.GetPropertiesInput{Action: paths.GetPropertiesActionGetAccessControl}) if err == nil { acl, err := accesscontrol.ParseACL(pathResponse.ACL) if err != nil { @@ -370,19 +380,20 @@ func resourceStorageDataLakeGen2FileSystemRead(d *pluginsdk.ResourceData, meta i } func resourceStorageDataLakeGen2FileSystemDelete(d *pluginsdk.ResourceData, meta interface{}) error { - client := meta.(*clients.Client).Storage.FileSystemsClient + storageClient := meta.(*clients.Client).Storage + client := storageClient.FileSystemsClient ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d) defer cancel() - id, err := filesystems.ParseResourceID(d.Id()) + id, err := filesystems.ParseFileSystemID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { return err } - resp, err := client.Delete(ctx, id.AccountName, id.DirectoryName) + resp, err := client.Delete(ctx, id.FileSystemName) if err != nil { - if !utils.ResponseWasNotFound(resp) { - return fmt.Errorf("deleting File System %q in Storage Account %q: %+v", id.DirectoryName, id.AccountName, err) + if !response.WasNotFound(resp.HttpResponse) { + return fmt.Errorf("deleting %s: %v", id, err) } } diff --git a/internal/services/storage/storage_data_lake_gen2_filesystem_resource_test.go b/internal/services/storage/storage_data_lake_gen2_filesystem_resource_test.go index 8399d2b0d212e..e0a874bf4e064 100644 --- a/internal/services/storage/storage_data_lake_gen2_filesystem_resource_test.go +++ b/internal/services/storage/storage_data_lake_gen2_filesystem_resource_test.go @@ -8,12 +8,13 @@ import ( "fmt" "testing" + "github.com/hashicorp/go-azure-helpers/lang/response" "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance" "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/utils" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems" ) type StorageDataLakeGen2FileSystemResource struct{} @@ -147,27 +148,27 @@ func TestAccStorageDataLakeGen2FileSystem_withSuperUsers(t *testing.T) { } func (r StorageDataLakeGen2FileSystemResource) Exists(ctx context.Context, client *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { - id, err := filesystems.ParseResourceID(state.ID) + id, err := filesystems.ParseFileSystemID(state.ID, client.Storage.StorageDomainSuffix) if err != nil { return nil, err } - resp, err := client.Storage.FileSystemsClient.GetProperties(ctx, id.AccountName, id.DirectoryName) + resp, err := client.Storage.FileSystemsClient.GetProperties(ctx, id.FileSystemName) if err != nil { - if utils.ResponseWasNotFound(resp.Response) { + if response.WasNotFound(resp.HttpResponse) { return utils.Bool(false), nil } - return nil, fmt.Errorf("retrieving File System %q (Account %q): %+v", id.DirectoryName, id.AccountName, err) + return nil, fmt.Errorf("retrieving File System %q (Account %q): %+v", id.FileSystemName, id.AccountId.AccountName, err) } return utils.Bool(true), nil } func (r StorageDataLakeGen2FileSystemResource) Destroy(ctx context.Context, client *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { - id, err := filesystems.ParseResourceID(state.ID) + id, err := filesystems.ParseFileSystemID(state.ID, client.Storage.StorageDomainSuffix) if err != nil { return nil, err } - if _, err := client.Storage.FileSystemsClient.Delete(ctx, id.AccountName, id.DirectoryName); err != nil { - return nil, fmt.Errorf("deleting File System %q (Account %q): %+v", id.DirectoryName, id.AccountName, err) + if _, err := client.Storage.FileSystemsClient.Delete(ctx, id.FileSystemName); err != nil { + return nil, fmt.Errorf("deleting File System %q (Account %q): %+v", id.FileSystemName, id.AccountId.AccountName, err) } return utils.Bool(true), nil } diff --git a/internal/services/storage/storage_data_lake_gen2_path_resource.go b/internal/services/storage/storage_data_lake_gen2_path_resource.go index 8457260a94c61..ec53442498d5e 100644 --- a/internal/services/storage/storage_data_lake_gen2_path_resource.go +++ b/internal/services/storage/storage_data_lake_gen2_path_resource.go @@ -9,6 +9,7 @@ import ( "log" "time" + "github.com/hashicorp/go-azure-helpers/lang/response" "github.com/hashicorp/go-azure-helpers/resourcemanager/commonids" "github.com/hashicorp/terraform-provider-azurerm/helpers/tf" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" @@ -17,7 +18,8 @@ import ( "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" "github.com/hashicorp/terraform-provider-azurerm/internal/timeouts" "github.com/hashicorp/terraform-provider-azurerm/utils" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths" "github.com/tombuildsstuff/giovanni/storage/accesscontrol" ) @@ -29,27 +31,27 @@ func resourceStorageDataLakeGen2Path() *pluginsdk.Resource { Delete: resourceStorageDataLakeGen2PathDelete, Importer: pluginsdk.ImporterValidatingResourceIdThen(func(id string) error { - _, err := paths.ParseResourceID(id) + _, err := paths.ParsePathID(id, "") // TODO: actual domain suffix needed here! return err }, func(ctx context.Context, d *pluginsdk.ResourceData, meta interface{}) ([]*pluginsdk.ResourceData, error) { storageClients := meta.(*clients.Client).Storage - id, err := paths.ParseResourceID(d.Id()) + id, err := paths.ParsePathID(d.Id(), "") // TODO: actual domain suffix needed here! if err != nil { return []*pluginsdk.ResourceData{d}, fmt.Errorf("parsing ID %q for import of Data Lake Gen2 Path: %v", d.Id(), err) } // we then need to look up the Storage Account ID - account, err := storageClients.FindAccount(ctx, id.AccountName) + account, err := storageClients.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return []*pluginsdk.ResourceData{d}, fmt.Errorf("retrieving Account %q for Data Lake Gen2 Path %q in File System %q: %s", id.AccountName, id.Path, id.FileSystemName, err) + return []*pluginsdk.ResourceData{d}, fmt.Errorf("retrieving Account %q for Data Lake Gen2 Path %q in File System %q: %s", id.AccountId.AccountName, id.Path, id.FileSystemName, err) } if account == nil { - return []*pluginsdk.ResourceData{d}, fmt.Errorf("Unable to locate Storage Account %q!", id.AccountName) + return []*pluginsdk.ResourceData{d}, fmt.Errorf("Unable to locate Storage Account %q!", id.AccountId.AccountName) } - if _, err = storageClients.FileSystemsClient.GetProperties(ctx, id.AccountName, id.FileSystemName); err != nil { - return []*pluginsdk.ResourceData{d}, fmt.Errorf("retrieving File System %q for Data Lake Gen 2 Path %q in Account %q: %s", id.FileSystemName, id.Path, id.AccountName, err) + if _, err = storageClients.FileSystemsClient.GetProperties(ctx, id.FileSystemName); err != nil { + return []*pluginsdk.ResourceData{d}, fmt.Errorf("retrieving File System %q for Data Lake Gen 2 Path %q in Account %q: %s", id.FileSystemName, id.Path, id.AccountId.AccountName, err) } d.Set("storage_account_id", account.ID) @@ -142,38 +144,44 @@ func resourceStorageDataLakeGen2Path() *pluginsdk.Resource { } func resourceStorageDataLakeGen2PathCreate(d *pluginsdk.ResourceData, meta interface{}) error { - accountsClient := meta.(*clients.Client).Storage.AccountsClient - client := meta.(*clients.Client).Storage.ADLSGen2PathsClient + storageClient := meta.(*clients.Client).Storage + accountsClient := storageClient.AccountsClient + client := storageClient.ADLSGen2PathsClient ctx, cancel := timeouts.ForCreate(meta.(*clients.Client).StopContext, d) defer cancel() - storageID, err := commonids.ParseStorageAccountID(d.Get("storage_account_id").(string)) + storageId, err := commonids.ParseStorageAccountID(d.Get("storage_account_id").(string)) if err != nil { return err } // confirm the storage account exists, otherwise Data Plane API requests will fail - storageAccount, err := accountsClient.GetProperties(ctx, storageID.ResourceGroupName, storageID.StorageAccountName, "") + storageAccount, err := accountsClient.GetProperties(ctx, storageId.ResourceGroupName, storageId.StorageAccountName, "") if err != nil { if utils.ResponseWasNotFound(storageAccount.Response) { - return fmt.Errorf("%s was not found", storageID) + return fmt.Errorf("%s was not found", storageId) } - return fmt.Errorf("checking for existence of %s: %+v", storageID, err) + return fmt.Errorf("checking for existence of %s: %v", storageId, err) } fileSystemName := d.Get("filesystem_name").(string) path := d.Get("path").(string) - id := client.GetResourceID(storageID.StorageAccountName, fileSystemName, path) - resp, err := client.GetProperties(ctx, storageID.StorageAccountName, fileSystemName, path, paths.GetPropertiesActionGetStatus) + accountId, err := accounts.ParseAccountID(d.Get("storage_account_id").(string), storageClient.StorageDomainSuffix) if err != nil { - if !utils.ResponseWasNotFound(resp.Response) { - return fmt.Errorf("checking for existence of existing Path %q in File System %q in %s: %+v", path, fileSystemName, storageID, err) + return fmt.Errorf("parsing Account ID: %v", err) + } + + id := paths.NewPathID(*accountId, fileSystemName, path) + resp, err := client.GetProperties(ctx, fileSystemName, path, paths.GetPropertiesInput{Action: paths.GetPropertiesActionGetStatus}) + if err != nil { + if !response.WasNotFound(resp.HttpResponse) { + return fmt.Errorf("checking for existence of existing Path %q in File System %q in %s: %v", path, fileSystemName, storageId, err) } } - if !utils.ResponseWasNotFound(resp.Response) { - return tf.ImportAsExistsError("azurerm_storage_data_lake_gen2_path", id) + if !response.WasNotFound(resp.HttpResponse) { + return tf.ImportAsExistsError("azurerm_storage_data_lake_gen2_path", id.ID()) } resourceString := d.Get("resource").(string) @@ -182,12 +190,12 @@ func resourceStorageDataLakeGen2PathCreate(d *pluginsdk.ResourceData, meta inter case "directory": resource = paths.PathResourceDirectory default: - return fmt.Errorf("Unhandled resource type %q", resourceString) + return fmt.Errorf("unhandled resource type %q", resourceString) } aceRaw := d.Get("ace").(*pluginsdk.Set).List() acl, err := ExpandDataLakeGen2AceList(aceRaw) if err != nil { - return fmt.Errorf("parsing ace list: %s", err) + return fmt.Errorf("parsing ace list: %v", err) } var owner *string @@ -201,13 +209,13 @@ func resourceStorageDataLakeGen2PathCreate(d *pluginsdk.ResourceData, meta inter group = &sv } - log.Printf("[INFO] Creating Path %q in File System %q in %s.", path, fileSystemName, storageID) + log.Printf("[INFO] Creating %s...", id) input := paths.CreateInput{ Resource: resource, } - if _, err := client.Create(ctx, storageID.StorageAccountName, fileSystemName, path, input); err != nil { - return fmt.Errorf("creating Path %q in File System %q in %s: %+v", path, fileSystemName, storageID.StorageAccountName, err) + if _, err = client.Create(ctx, fileSystemName, path, input); err != nil { + return fmt.Errorf("creating %s: %v", id, err) } if acl != nil || owner != nil || group != nil { @@ -221,27 +229,28 @@ func resourceStorageDataLakeGen2PathCreate(d *pluginsdk.ResourceData, meta inter Owner: owner, Group: group, } - if _, err := client.SetAccessControl(ctx, storageID.StorageAccountName, fileSystemName, path, accessControlInput); err != nil { - return fmt.Errorf("setting access control for Path %q in File System %q in %s: %+v", path, fileSystemName, storageID, err) + if _, err = client.SetAccessControl(ctx, fileSystemName, path, accessControlInput); err != nil { + return fmt.Errorf("setting access control for %s: %+v", id, err) } } - d.SetId(id) + d.SetId(id.ID()) return resourceStorageDataLakeGen2PathRead(d, meta) } func resourceStorageDataLakeGen2PathUpdate(d *pluginsdk.ResourceData, meta interface{}) error { - accountsClient := meta.(*clients.Client).Storage.AccountsClient - client := meta.(*clients.Client).Storage.ADLSGen2PathsClient + storageClient := meta.(*clients.Client).Storage + accountsClient := storageClient.AccountsClient + client := storageClient.ADLSGen2PathsClient ctx, cancel := timeouts.ForUpdate(meta.(*clients.Client).StopContext, d) defer cancel() - id, err := paths.ParseResourceID(d.Id()) + id, err := paths.ParsePathID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { return err } - storageID, err := commonids.ParseStorageAccountID(d.Get("storage_account_id").(string)) + storageId, err := commonids.ParseStorageAccountID(d.Get("storage_account_id").(string)) if err != nil { return err } @@ -251,7 +260,7 @@ func resourceStorageDataLakeGen2PathUpdate(d *pluginsdk.ResourceData, meta inter aceRaw := d.Get("ace").(*pluginsdk.Set).List() acl, err := ExpandDataLakeGen2AceList(aceRaw) if err != nil { - return fmt.Errorf("parsing ace list: %s", err) + return fmt.Errorf("parsing ace list: %v", err) } var owner *string @@ -266,13 +275,13 @@ func resourceStorageDataLakeGen2PathUpdate(d *pluginsdk.ResourceData, meta inter } // confirm the storage account exists, otherwise Data Plane API requests will fail - storageAccount, err := accountsClient.GetProperties(ctx, storageID.ResourceGroupName, storageID.StorageAccountName, "") + storageAccount, err := accountsClient.GetProperties(ctx, storageId.ResourceGroupName, storageId.StorageAccountName, "") if err != nil { if utils.ResponseWasNotFound(storageAccount.Response) { - return fmt.Errorf("%s was not found", storageID) + return fmt.Errorf("%s was not found", storageId) } - return fmt.Errorf("checking for existence of %s: %+v", storageID, err) + return fmt.Errorf("checking for existence of %s: %v", storageId, err) } if acl != nil || owner != nil || group != nil { @@ -286,8 +295,8 @@ func resourceStorageDataLakeGen2PathUpdate(d *pluginsdk.ResourceData, meta inter Owner: owner, Group: group, } - if _, err := client.SetAccessControl(ctx, id.AccountName, id.FileSystemName, path, accessControlInput); err != nil { - return fmt.Errorf("setting access control for Path %q in File System %q in Storage Account %q: %s", path, id.FileSystemName, id.AccountName, err) + if _, err = client.SetAccessControl(ctx, id.FileSystemName, path, accessControlInput); err != nil { + return fmt.Errorf("setting access control for %s: %s", id, err) } } @@ -295,24 +304,25 @@ func resourceStorageDataLakeGen2PathUpdate(d *pluginsdk.ResourceData, meta inter } func resourceStorageDataLakeGen2PathRead(d *pluginsdk.ResourceData, meta interface{}) error { - client := meta.(*clients.Client).Storage.ADLSGen2PathsClient + storageClient := meta.(*clients.Client).Storage + client := storageClient.ADLSGen2PathsClient ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d) defer cancel() - id, err := paths.ParseResourceID(d.Id()) + id, err := paths.ParsePathID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { return err } - resp, err := client.GetProperties(ctx, id.AccountName, id.FileSystemName, id.Path, paths.GetPropertiesActionGetStatus) + resp, err := client.GetProperties(ctx, id.FileSystemName, id.Path, paths.GetPropertiesInput{Action: paths.GetPropertiesActionGetStatus}) if err != nil { - if utils.ResponseWasNotFound(resp.Response) { - log.Printf("[INFO] Path %q does not exist in File System %q in Storage Account %q - removing from state...", id.Path, id.FileSystemName, id.AccountName) + if response.WasNotFound(resp.HttpResponse) { + log.Printf("[INFO] Path %q does not exist in File System %q in Storage Account %q - removing from state...", id.Path, id.FileSystemName, id.AccountId.AccountName) d.SetId("") return nil } - return fmt.Errorf("retrieving Path %q in File System %q in Storage Account %q: %+v", id.Path, id.FileSystemName, id.AccountName, err) + return fmt.Errorf("retrieving %s: %v", id, err) } d.Set("path", id.Path) @@ -322,20 +332,20 @@ func resourceStorageDataLakeGen2PathRead(d *pluginsdk.ResourceData, meta interfa // The above `getStatus` API request doesn't return the ACLs // Have to make a `getAccessControl` request, but that doesn't return all fields either! - resp, err = client.GetProperties(ctx, id.AccountName, id.FileSystemName, id.Path, paths.GetPropertiesActionGetAccessControl) + resp, err = client.GetProperties(ctx, id.FileSystemName, id.Path, paths.GetPropertiesInput{Action: paths.GetPropertiesActionGetAccessControl}) if err != nil { - if utils.ResponseWasNotFound(resp.Response) { - log.Printf("[INFO] Path %q does not exist in File System %q in Storage Account %q - removing from state...", id.Path, id.FileSystemName, id.AccountName) + if response.WasNotFound(resp.HttpResponse) { + log.Printf("[INFO] Path %q does not exist in File System %q in Storage Account %q - removing from state...", id.Path, id.FileSystemName, id.AccountId.AccountName) d.SetId("") return nil } - return fmt.Errorf("retrieving ACLs for Path %q in File System %q in Storage Account %q: %+v", id.Path, id.FileSystemName, id.AccountName, err) + return fmt.Errorf("retrieving ACLs for %s: %v", id, err) } acl, err := accesscontrol.ParseACL(resp.ACL) if err != nil { - return fmt.Errorf("parsing response ACL %q: %s", resp.ACL, err) + return fmt.Errorf("parsing response ACL %q: %v", resp.ACL, err) } d.Set("ace", FlattenDataLakeGen2AceList(d, acl)) @@ -343,19 +353,20 @@ func resourceStorageDataLakeGen2PathRead(d *pluginsdk.ResourceData, meta interfa } func resourceStorageDataLakeGen2PathDelete(d *pluginsdk.ResourceData, meta interface{}) error { - client := meta.(*clients.Client).Storage.ADLSGen2PathsClient + storageClient := meta.(*clients.Client).Storage + client := storageClient.ADLSGen2PathsClient ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d) defer cancel() - id, err := paths.ParseResourceID(d.Id()) + id, err := paths.ParsePathID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { return err } - resp, err := client.Delete(ctx, id.AccountName, id.FileSystemName, id.Path) + resp, err := client.Delete(ctx, id.FileSystemName, id.Path) if err != nil { - if !utils.ResponseWasNotFound(resp) { - return fmt.Errorf("deleting Path %q in File System %q in Storage Account %q: %+v", id.Path, id.FileSystemName, id.AccountName, err) + if !response.WasNotFound(resp.HttpResponse) { + return fmt.Errorf("deleting %s: %v", id, err) } } diff --git a/internal/services/storage/storage_data_lake_gen2_path_resource_test.go b/internal/services/storage/storage_data_lake_gen2_path_resource_test.go index b38158910a930..fa18850a3ad01 100644 --- a/internal/services/storage/storage_data_lake_gen2_path_resource_test.go +++ b/internal/services/storage/storage_data_lake_gen2_path_resource_test.go @@ -8,12 +8,13 @@ import ( "fmt" "testing" + "github.com/hashicorp/go-azure-helpers/lang/response" "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance" "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/utils" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths" ) type StorageDataLakeGen2PathResource struct{} @@ -131,16 +132,16 @@ func TestAccStorageDataLakeGen2Path_withSuperUsers(t *testing.T) { } func (r StorageDataLakeGen2PathResource) Exists(ctx context.Context, client *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { - id, err := paths.ParseResourceID(state.ID) + id, err := paths.ParsePathID(state.ID, client.Storage.StorageDomainSuffix) if err != nil { return nil, err } - resp, err := client.Storage.ADLSGen2PathsClient.GetProperties(ctx, id.AccountName, id.FileSystemName, id.Path, paths.GetPropertiesActionGetStatus) + resp, err := client.Storage.ADLSGen2PathsClient.GetProperties(ctx, id.FileSystemName, id.Path, paths.GetPropertiesInput{Action: paths.GetPropertiesActionGetStatus}) if err != nil { - if utils.ResponseWasNotFound(resp.Response) { + if response.WasNotFound(resp.HttpResponse) { return utils.Bool(false), nil } - return nil, fmt.Errorf("retrieving Path %q (File System %q / Account %q): %+v", id.Path, id.FileSystemName, id.AccountName, err) + return nil, fmt.Errorf("retrieving Path %q (File System %q / Account %q): %+v", id.Path, id.FileSystemName, id.AccountId.AccountName, err) } return utils.Bool(true), nil } diff --git a/internal/services/storage/storage_queue_resource.go b/internal/services/storage/storage_queue_resource.go index 31b776bd0f1d8..fc0dda42d90da 100644 --- a/internal/services/storage/storage_queue_resource.go +++ b/internal/services/storage/storage_queue_resource.go @@ -10,6 +10,7 @@ import ( "github.com/hashicorp/terraform-provider-azurerm/helpers/tf" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/helpers" "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/migration" "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/parse" "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/validate" @@ -24,8 +25,8 @@ func resourceStorageQueue() *pluginsdk.Resource { Update: resourceStorageQueueUpdate, Delete: resourceStorageQueueDelete, - Importer: pluginsdk.ImporterValidatingResourceId(func(id string) error { - _, err := parse.StorageQueueDataPlaneID(id) + Importer: helpers.ImporterValidatingStorageResourceId(func(id, storageDomainSuffix string) error { + _, err := parse.StorageQueueDataPlaneID(id, storageDomainSuffix) return err }), @@ -79,32 +80,33 @@ func resourceStorageQueueCreate(d *pluginsdk.ResourceData, meta interface{}) err account, err := storageClient.FindAccount(ctx, accountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Queue %q: %s", accountName, queueName, err) + return fmt.Errorf("retrieving Account %q for Queue %q: %v", accountName, queueName, err) } if account == nil { - return fmt.Errorf("unable to locate Storage Account %q", accountName) + return fmt.Errorf("locating Storage Account %q", accountName) } - client, err := storageClient.QueuesClient(ctx, *account) + client, err := storageClient.QueuesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building Queues Client: %s", err) + return fmt.Errorf("building Queues Client: %v", err) } - resourceId := parse.NewStorageQueueDataPlaneId(accountName, storageClient.Environment.StorageEndpointSuffix, queueName).ID() + id := parse.NewStorageQueueDataPlaneId(accountName, storageClient.AzureEnvironment.StorageEndpointSuffix, queueName).ID() - exists, err := client.Exists(ctx, account.ResourceGroup, accountName, queueName) + exists, err := client.Exists(ctx, queueName) if err != nil { - return fmt.Errorf("checking for presence of existing Queue %q (Storage Account %q): %s", queueName, accountName, err) + return fmt.Errorf("checking for existing %s: %v", id, err) } if exists != nil && *exists { - return tf.ImportAsExistsError("azurerm_storage_queue", resourceId) + return tf.ImportAsExistsError("azurerm_storage_queue", id) } - if err := client.Create(ctx, account.ResourceGroup, accountName, queueName, metaData); err != nil { - return fmt.Errorf("creating Queue %q (Account %q): %+v", queueName, accountName, err) + if err = client.Create(ctx, queueName, metaData); err != nil { + return fmt.Errorf("creating %s: %+v", id, err) } - d.SetId(resourceId) + d.SetId(id) + return resourceStorageQueueRead(d, meta) } @@ -113,7 +115,7 @@ func resourceStorageQueueUpdate(d *pluginsdk.ResourceData, meta interface{}) err ctx, cancel := timeouts.ForUpdate(meta.(*clients.Client).StopContext, d) defer cancel() - id, err := parse.StorageQueueDataPlaneID(d.Id()) + id, err := parse.StorageQueueDataPlaneID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { return err } @@ -123,19 +125,19 @@ func resourceStorageQueueUpdate(d *pluginsdk.ResourceData, meta interface{}) err account, err := storageClient.FindAccount(ctx, id.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Queue %q: %s", id.AccountName, id.Name, err) + return fmt.Errorf("retrieving Account %q for Queue %q: %v", id.AccountName, id.Name, err) } if account == nil { - return fmt.Errorf("unable to locate Storage Account %q!", id.AccountName) + return fmt.Errorf("locating Storage Account %q", id.AccountName) } - client, err := storageClient.QueuesClient(ctx, *account) + client, err := storageClient.QueuesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building Queues Client: %s", err) + return fmt.Errorf("building Queues Client: %v", err) } - if err := client.UpdateMetaData(ctx, account.ResourceGroup, id.AccountName, id.Name, metaData); err != nil { - return fmt.Errorf("updating MetaData for Queue %q (Storage Account %q): %s", id.Name, id.AccountName, err) + if err = client.UpdateMetaData(ctx, id.Name, metaData); err != nil { + return fmt.Errorf("updating MetaData for %s: %v", id, err) } return resourceStorageQueueRead(d, meta) @@ -147,14 +149,14 @@ func resourceStorageQueueRead(d *pluginsdk.ResourceData, meta interface{}) error ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d) defer cancel() - id, err := parse.StorageQueueDataPlaneID(d.Id()) + id, err := parse.StorageQueueDataPlaneID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { return err } account, err := storageClient.FindAccount(ctx, id.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Queue %q: %s", id.AccountName, id.Name, err) + return fmt.Errorf("retrieving Account %q for Queue %q: %v", id.AccountName, id.Name, err) } if account == nil { log.Printf("[WARN] Unable to determine Resource Group for Storage Queue %q (Account %s) - assuming removed & removing from state", id.Name, id.AccountName) @@ -162,14 +164,14 @@ func resourceStorageQueueRead(d *pluginsdk.ResourceData, meta interface{}) error return nil } - client, err := storageClient.QueuesClient(ctx, *account) + client, err := storageClient.QueuesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building Queues Client: %s", err) + return fmt.Errorf("building Queues Client: %v", err) } - queue, err := client.Get(ctx, account.ResourceGroup, id.AccountName, id.Name) + queue, err := client.Get(ctx, id.Name) if err != nil { - return fmt.Errorf("retrieving Queue %q (Account %q): %+v", id.AccountName, id.Name, err) + return fmt.Errorf("retrieving %s: %v", id, err) } if queue == nil { log.Printf("[INFO] Storage Queue %q no longer exists, removing from state...", id.Name) @@ -195,7 +197,7 @@ func resourceStorageQueueDelete(d *pluginsdk.ResourceData, meta interface{}) err ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d) defer cancel() - id, err := parse.StorageQueueDataPlaneID(d.Id()) + id, err := parse.StorageQueueDataPlaneID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { return err } @@ -210,13 +212,13 @@ func resourceStorageQueueDelete(d *pluginsdk.ResourceData, meta interface{}) err return nil } - client, err := storageClient.QueuesClient(ctx, *account) + client, err := storageClient.QueuesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building Queues Client: %s", err) + return fmt.Errorf("building Queues Client: %v", err) } - if err := client.Delete(ctx, account.ResourceGroup, id.AccountName, id.Name); err != nil { - return fmt.Errorf("deleting Storage Queue %q (Account %q): %s", id.Name, id.AccountName, err) + if err = client.Delete(ctx, id.Name); err != nil { + return fmt.Errorf("deleting %s: %v", id, err) } return nil diff --git a/internal/services/storage/storage_queue_resource_test.go b/internal/services/storage/storage_queue_resource_test.go index 178637af8368e..7653ec20fe4fc 100644 --- a/internal/services/storage/storage_queue_resource_test.go +++ b/internal/services/storage/storage_queue_resource_test.go @@ -86,7 +86,7 @@ func TestAccStorageQueue_metaData(t *testing.T) { } func (r StorageQueueResource) Exists(ctx context.Context, client *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { - id, err := parse.StorageQueueDataPlaneID(state.ID) + id, err := parse.StorageQueueDataPlaneID(state.ID, client.Storage.StorageDomainSuffix) if err != nil { return nil, err } @@ -97,11 +97,11 @@ func (r StorageQueueResource) Exists(ctx context.Context, client *clients.Client if account == nil { return nil, fmt.Errorf("unable to determine Resource Group for Storage Queue %q (Account %q)", id.Name, id.AccountName) } - queuesClient, err := client.Storage.QueuesClient(ctx, *account) + queuesClient, err := client.Storage.QueuesDataPlaneClient(ctx, *account, client.Storage.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { return nil, fmt.Errorf("building Queues Client: %+v", err) } - queue, err := queuesClient.Get(ctx, account.ResourceGroup, id.AccountName, id.Name) + queue, err := queuesClient.Get(ctx, id.Name) if err != nil { return nil, fmt.Errorf("retrieving Queue %q (Account %q): %+v", id.Name, id.AccountName, err) } diff --git a/internal/services/storage/storage_share_data_source.go b/internal/services/storage/storage_share_data_source.go index 76f0fc0d026b8..68f537b50cc78 100644 --- a/internal/services/storage/storage_share_data_source.go +++ b/internal/services/storage/storage_share_data_source.go @@ -90,36 +90,38 @@ func dataSourceStorageShareRead(d *pluginsdk.ResourceData, meta interface{}) err account, err := storageClient.FindAccount(ctx, accountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Share %q: %s", accountName, shareName, err) + return fmt.Errorf("retrieving Storage Account %q for Share %q: %s", accountName, shareName, err) } if account == nil { - return fmt.Errorf("unable to locate Account %q for Share %q", accountName, shareName) + return fmt.Errorf("locating Storage Account %q for Share %q", accountName, shareName) } - client, err := storageClient.FileSharesClient(ctx, *account) + // The files API does not support bearer tokens (@manicminer, 2024-02-15) + client, err := storageClient.FileSharesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingOnlySharedKeyAuth()) if err != nil { - return fmt.Errorf("building FileShares Client for Storage Account %q (Resource Group %q): %s", accountName, account.ResourceGroup, err) + return fmt.Errorf("building FileShares Client: %v", err) } - id := parse.NewStorageShareDataPlaneId(accountName, storageClient.Environment.StorageEndpointSuffix, shareName).ID() - props, err := client.Get(ctx, account.ResourceGroup, accountName, shareName) + id := parse.NewStorageShareDataPlaneId(accountName, storageClient.AzureEnvironment.StorageEndpointSuffix, shareName).ID() + + props, err := client.Get(ctx, shareName) if err != nil { - return fmt.Errorf("retrieving Share %q (Account %q / Resource Group %q): %s", shareName, accountName, account.ResourceGroup, err) + return fmt.Errorf("retrieving %s: %v", id, err) } if props == nil { - return fmt.Errorf("share %q was not found in Account %q / Resource Group %q", shareName, accountName, account.ResourceGroup) + return fmt.Errorf("%s was not found", id) } d.SetId(id) d.Set("name", shareName) d.Set("storage_account_name", accountName) d.Set("quota", props.QuotaGB) - if err := d.Set("acl", flattenStorageShareACLs(props.ACLs)); err != nil { - return fmt.Errorf("setting `acl`: %+v", err) + if err = d.Set("acl", flattenStorageShareACLs(props.ACLs)); err != nil { + return fmt.Errorf("setting `acl`: %v", err) } - if err := d.Set("metadata", FlattenMetaData(props.MetaData)); err != nil { - return fmt.Errorf("setting `metadata`: %+v", err) + if err = d.Set("metadata", FlattenMetaData(props.MetaData)); err != nil { + return fmt.Errorf("setting `metadata`: %v", err) } resourceManagerId := parse.NewStorageShareResourceManagerID(storageClient.SubscriptionId, account.ResourceGroup, accountName, "default", shareName) diff --git a/internal/services/storage/storage_share_directory_resource.go b/internal/services/storage/storage_share_directory_resource.go index 67f91fe221340..57060624bc32e 100644 --- a/internal/services/storage/storage_share_directory_resource.go +++ b/internal/services/storage/storage_share_directory_resource.go @@ -10,14 +10,18 @@ import ( "strconv" "time" + "github.com/hashicorp/go-azure-helpers/lang/pointer" + "github.com/hashicorp/go-azure-helpers/lang/response" "github.com/hashicorp/terraform-provider-azurerm/helpers/tf" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/helpers" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/parse" "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/validate" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" "github.com/hashicorp/terraform-provider-azurerm/internal/timeouts" - "github.com/hashicorp/terraform-provider-azurerm/utils" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories" ) func resourceStorageShareDirectory() *pluginsdk.Resource { @@ -27,8 +31,8 @@ func resourceStorageShareDirectory() *pluginsdk.Resource { Update: resourceStorageShareDirectoryUpdate, Delete: resourceStorageShareDirectoryDelete, - Importer: pluginsdk.ImporterValidatingResourceId(func(id string) error { - _, err := directories.ParseResourceID(id) + Importer: helpers.ImporterValidatingStorageResourceId(func(id, storageDomainSuffix string) error { + _, err := directories.ParseDirectoryID(id, storageDomainSuffix) return err }), @@ -46,17 +50,33 @@ func resourceStorageShareDirectory() *pluginsdk.Resource { ForceNew: true, ValidateFunc: validate.StorageShareDirectoryName, }, + + "storage_share_id": { + Type: pluginsdk.TypeString, + Optional: true, // TODO: make required and forcenew in v4.0 + Computed: true, // TODO: remove computed in v4.0 + ConflictsWith: []string{"share_name", "storage_account_name"}, + ValidateFunc: validation.IsURLWithPath, // note: storage domain suffix cannot be determined at validation time, so just make sure it's a well-formed URL + }, + "share_name": { - Type: pluginsdk.TypeString, - Required: true, - ForceNew: true, - ValidateFunc: validation.StringIsNotEmpty, + Type: pluginsdk.TypeString, + Optional: true, + Computed: true, + Deprecated: "the `share_name` and `storage_account_name` properties have been superseded by the `storage_share_id` property and will be removed in version 4.0 of the AzureRM provider", + ConflictsWith: []string{"storage_share_id"}, + RequiredWith: []string{"storage_account_name"}, + ValidateFunc: validation.StringIsNotEmpty, }, + "storage_account_name": { - Type: pluginsdk.TypeString, - Required: true, - ForceNew: true, - ValidateFunc: validation.StringIsNotEmpty, + Type: pluginsdk.TypeString, + Optional: true, + Computed: true, + Deprecated: "the `share_name` and `storage_account_name` properties have been superseded by the `storage_share_id` property and will be removed in version 4.0 of the AzureRM provider", + ConflictsWith: []string{"storage_share_id"}, + RequiredWith: []string{"share_name"}, + ValidateFunc: validation.StringIsNotEmpty, }, "metadata": MetaDataSchema(), @@ -69,62 +89,80 @@ func resourceStorageShareDirectoryCreate(d *pluginsdk.ResourceData, meta interfa defer cancel() storageClient := meta.(*clients.Client).Storage - accountName := d.Get("storage_account_name").(string) - shareName := d.Get("share_name").(string) directoryName := d.Get("name").(string) - metaDataRaw := d.Get("metadata").(map[string]interface{}) metaData := ExpandMetaData(metaDataRaw) - account, err := storageClient.FindAccount(ctx, accountName) + var storageShareId *parse.StorageShareDataPlaneId + var err error + if v, ok := d.GetOk("storage_share_id"); ok && v.(string) != "" { + storageShareId, err = parse.StorageShareDataPlaneID(v.(string), storageClient.StorageDomainSuffix) + if err != nil { + return err + } + } else { + // TODO: this is needed until `share_name` / `storage_account_name` are removed in favor of `storage_account_id` + storageShareId = pointer.To(parse.NewStorageShareDataPlaneId(d.Get("storage_account_name").(string), storageClient.StorageDomainSuffix, d.Get("share_name").(string))) + } + + if storageShareId == nil { + return fmt.Errorf("determining storage share ID") + } + + account, err := storageClient.FindAccount(ctx, storageShareId.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Directory %q (Share %q): %s", accountName, directoryName, shareName, err) + return fmt.Errorf("retrieving Account %q for Directory %q (Share %q): %v", storageShareId.AccountName, directoryName, storageShareId.Name, err) } if account == nil { - return fmt.Errorf("Unable to locate Storage Account %q!", accountName) + return fmt.Errorf("locating Storage Account %q", storageShareId.AccountName) } - client, err := storageClient.FileShareDirectoriesClient(ctx, *account) + accountId, err := accounts.ParseAccountID(storageShareId.ID(), storageClient.StorageDomainSuffix) if err != nil { - return fmt.Errorf("building File Share Directories Client: %s", err) + return fmt.Errorf("parsing Account ID: %v", err) } - existing, err := client.Get(ctx, accountName, shareName, directoryName) + id := directories.NewDirectoryID(*accountId, storageShareId.Name, directoryName) + + client, err := storageClient.FileShareDirectoriesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - if !utils.ResponseWasNotFound(existing.Response) { - return fmt.Errorf("checking for presence of existing Directory %q (File Share %q / Storage Account %q / Resource Group %q): %s", directoryName, shareName, accountName, account.ResourceGroup, err) + return fmt.Errorf("building File Share Directories Client: %v", err) + } + + existing, err := client.Get(ctx, storageShareId.Name, directoryName) + if err != nil { + if !response.WasNotFound(existing.HttpResponse) { + return fmt.Errorf("checking for existing %s: %s", id, err) } } - if !utils.ResponseWasNotFound(existing.Response) { - id := client.GetResourceID(accountName, shareName, directoryName) - return tf.ImportAsExistsError("azurerm_storage_share_directory", id) + if !response.WasNotFound(existing.HttpResponse) { + return tf.ImportAsExistsError("azurerm_storage_share_directory", id.ID()) } input := directories.CreateDirectoryInput{ MetaData: metaData, } - if _, err := client.Create(ctx, accountName, shareName, directoryName, input); err != nil { - return fmt.Errorf("creating Directory %q (File Share %q / Account %q): %+v", directoryName, shareName, accountName, err) + if _, err = client.Create(ctx, storageShareId.Name, directoryName, input); err != nil { + return fmt.Errorf("creating %s: %v", id, err) } // Storage Share Directories are eventually consistent - log.Printf("[DEBUG] Waiting for Directory %q (File Share %q / Account %q) to become available", directoryName, shareName, accountName) + log.Printf("[DEBUG] Waiting for %s to become available", id) stateConf := &pluginsdk.StateChangeConf{ Pending: []string{"404"}, Target: []string{"200"}, - Refresh: storageShareDirectoryRefreshFunc(ctx, client, accountName, shareName, directoryName), + Refresh: storageShareDirectoryRefreshFunc(ctx, client, id), MinTimeout: 10 * time.Second, ContinuousTargetOccurence: 5, Timeout: d.Timeout(pluginsdk.TimeoutCreate), } - if _, err := stateConf.WaitForStateContext(ctx); err != nil { - return fmt.Errorf("waiting for Directory %q (File Share %q / Account %q) to become available: %s", directoryName, shareName, accountName, err) + if _, err = stateConf.WaitForStateContext(ctx); err != nil { + return fmt.Errorf("waiting for %s to become available: %v", id, err) } - resourceID := client.GetResourceID(accountName, shareName, directoryName) - d.SetId(resourceID) + d.SetId(id.ID()) return resourceStorageShareDirectoryRead(d, meta) } @@ -134,7 +172,7 @@ func resourceStorageShareDirectoryUpdate(d *pluginsdk.ResourceData, meta interfa defer cancel() storageClient := meta.(*clients.Client).Storage - id, err := directories.ParseResourceID(d.Id()) + id, err := directories.ParseDirectoryID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { return err } @@ -142,21 +180,21 @@ func resourceStorageShareDirectoryUpdate(d *pluginsdk.ResourceData, meta interfa metaDataRaw := d.Get("metadata").(map[string]interface{}) metaData := ExpandMetaData(metaDataRaw) - account, err := storageClient.FindAccount(ctx, id.AccountName) + account, err := storageClient.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Directory %q (Share %q): %s", id.AccountName, id.DirectoryName, id.ShareName, err) + return fmt.Errorf("retrieving Account %q for Directory %q (Share %q): %v", id.AccountId.AccountName, id.DirectoryPath, id.ShareName, err) } if account == nil { - return fmt.Errorf("Unable to locate Storage Account %q!", id.AccountName) + return fmt.Errorf("locating Storage Account: %q", id.AccountId.AccountName) } - client, err := storageClient.FileShareDirectoriesClient(ctx, *account) + client, err := storageClient.FileShareDirectoriesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building File Share Client: %s", err) + return fmt.Errorf("building File Share Client: %v", err) } - if _, err := client.SetMetaData(ctx, id.AccountName, id.ShareName, id.DirectoryName, metaData); err != nil { - return fmt.Errorf("updating MetaData for Directory %q (File Share %q / Account %q): %+v", id.DirectoryName, id.ShareName, id.AccountName, err) + if _, err = client.SetMetaData(ctx, id.ShareName, id.DirectoryPath, directories.SetMetaDataInput{MetaData: metaData}); err != nil { + return fmt.Errorf("updating Metadata for %s: %v", id, err) } return resourceStorageShareDirectoryRead(d, meta) @@ -167,37 +205,40 @@ func resourceStorageShareDirectoryRead(d *pluginsdk.ResourceData, meta interface defer cancel() storageClient := meta.(*clients.Client).Storage - id, err := directories.ParseResourceID(d.Id()) + id, err := directories.ParseDirectoryID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { return err } - account, err := storageClient.FindAccount(ctx, id.AccountName) + account, err := storageClient.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Directory %q (Share %q): %s", id.AccountName, id.DirectoryName, id.ShareName, err) + return fmt.Errorf("retrieving Account %q for Directory %q (Share %q): %v", id.AccountId.AccountName, id.DirectoryPath, id.ShareName, err) } if account == nil { - log.Printf("[WARN] Unable to determine Resource Group for Storage Share Directory %q (Share %s, Account %s) - assuming removed & removing from state", id.DirectoryName, id.ShareName, id.AccountName) + log.Printf("[WARN] Unable to determine Resource Group for Storage Share Directory %q (Share %s, Account %s) - assuming removed & removing from state", id.DirectoryPath, id.ShareName, id.AccountId.AccountName) d.SetId("") return nil } - client, err := storageClient.FileShareDirectoriesClient(ctx, *account) + storageShareId := parse.NewStorageShareDataPlaneId(id.AccountId.AccountName, storageClient.StorageDomainSuffix, id.ShareName) + + client, err := storageClient.FileShareDirectoriesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building File Share Client for Storage Account %q (Resource Group %q): %s", id.AccountName, account.ResourceGroup, err) + return fmt.Errorf("building File Share Client: %v", err) } - props, err := client.Get(ctx, id.AccountName, id.ShareName, id.DirectoryName) + props, err := client.Get(ctx, id.ShareName, id.DirectoryPath) if err != nil { - return fmt.Errorf("retrieving Storage Share %q (File Share %q / Account %q / Resource Group %q): %s", id.DirectoryName, id.ShareName, id.AccountName, account.ResourceGroup, err) + return fmt.Errorf("retrieving %s: %v", id, err) } - d.Set("name", id.DirectoryName) + d.Set("name", id.DirectoryPath) + d.Set("storage_share_id", storageShareId.ID()) d.Set("share_name", id.ShareName) - d.Set("storage_account_name", id.AccountName) + d.Set("storage_account_name", id.AccountId.AccountName) - if err := d.Set("metadata", FlattenMetaData(props.MetaData)); err != nil { - return fmt.Errorf("setting `metadata`: %s", err) + if err = d.Set("metadata", FlattenMetaData(props.MetaData)); err != nil { + return fmt.Errorf("setting `metadata`: %v", err) } return nil @@ -208,38 +249,38 @@ func resourceStorageShareDirectoryDelete(d *pluginsdk.ResourceData, meta interfa defer cancel() storageClient := meta.(*clients.Client).Storage - id, err := directories.ParseResourceID(d.Id()) + id, err := directories.ParseDirectoryID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { return err } - account, err := storageClient.FindAccount(ctx, id.AccountName) + account, err := storageClient.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Directory %q (Share %q): %s", id.AccountName, id.DirectoryName, id.ShareName, err) + return fmt.Errorf("retrieving Account %q for Directory %q (Share %q): %v", id.AccountId.AccountName, id.DirectoryPath, id.ShareName, err) } if account == nil { - return fmt.Errorf("Unable to locate Storage Account %q!", id.AccountName) + return fmt.Errorf("locating Storage Account %q", id.AccountId.AccountName) } - client, err := storageClient.FileShareDirectoriesClient(ctx, *account) + client, err := storageClient.FileShareDirectoriesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building File Share Client for Storage Account %q (Resource Group %q): %s", id.AccountName, account.ResourceGroup, err) + return fmt.Errorf("building File Share Client: %v", err) } - if _, err := client.Delete(ctx, id.AccountName, id.ShareName, id.DirectoryName); err != nil { - return fmt.Errorf("deleting Storage Share %q (File Share %q / Account %q / Resource Group %q): %s", id.DirectoryName, id.ShareName, id.AccountName, account.ResourceGroup, err) + if _, err = client.Delete(ctx, id.ShareName, id.DirectoryPath); err != nil { + return fmt.Errorf("deleting %s: %v", id, err) } return nil } -func storageShareDirectoryRefreshFunc(ctx context.Context, client *directories.Client, accountName, shareName, directoryName string) pluginsdk.StateRefreshFunc { +func storageShareDirectoryRefreshFunc(ctx context.Context, client *directories.Client, id directories.DirectoryId) pluginsdk.StateRefreshFunc { return func() (interface{}, string, error) { - res, err := client.Get(ctx, accountName, shareName, directoryName) + res, err := client.Get(ctx, id.ShareName, id.DirectoryPath) if err != nil { - return nil, strconv.Itoa(res.StatusCode), fmt.Errorf("retrieving Directory %q (File Share %q / Account %q): %s", directoryName, shareName, accountName, err) + return nil, strconv.Itoa(res.HttpResponse.StatusCode), fmt.Errorf("retrieving %s: %v", id, err) } - return res, strconv.Itoa(res.StatusCode), nil + return res, strconv.Itoa(res.HttpResponse.StatusCode), nil } } diff --git a/internal/services/storage/storage_share_directory_resource_test.go b/internal/services/storage/storage_share_directory_resource_test.go index f68cfde672fce..d57862d10920d 100644 --- a/internal/services/storage/storage_share_directory_resource_test.go +++ b/internal/services/storage/storage_share_directory_resource_test.go @@ -8,12 +8,13 @@ import ( "fmt" "testing" + "github.com/hashicorp/go-azure-helpers/lang/response" "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance" "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/utils" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories" ) type StorageShareDirectoryResource struct{} @@ -33,6 +34,52 @@ func TestAccStorageShareDirectory_basic(t *testing.T) { }) } +func TestAccStorageShareDirectory_migrateStorageShareId(t *testing.T) { + // TODO: remove test in v4.0 + data := acceptance.BuildTestData(t, "azurerm_storage_share_directory", "test") + r := StorageShareDirectoryResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.basicDeprecated(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + { + Config: r.basic(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + { + Config: r.basicDeprecated(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }) +} + +func TestAccStorageShareDirectory_basicDeprecated(t *testing.T) { + // TODO: remove test in v4.0 + data := acceptance.BuildTestData(t, "azurerm_storage_share_directory", "test") + r := StorageShareDirectoryResource{} + + data.ResourceTest(t, r, []acceptance.TestStep{ + { + Config: r.basicDeprecated(data), + Check: acceptance.ComposeTestCheckFunc( + check.That(data.ResourceName).ExistsInAzure(r), + ), + }, + data.ImportStep(), + }) +} + func TestAccStorageShareDirectory_uppercase(t *testing.T) { data := acceptance.BuildTestData(t, "azurerm_storage_share_directory", "test") r := StorageShareDirectoryResource{} @@ -119,27 +166,27 @@ func TestAccStorageShareDirectory_nested(t *testing.T) { } func (r StorageShareDirectoryResource) Exists(ctx context.Context, client *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { - id, err := directories.ParseResourceID(state.ID) + id, err := directories.ParseDirectoryID(state.ID, client.Storage.StorageDomainSuffix) if err != nil { return nil, err } - account, err := client.Storage.FindAccount(ctx, id.AccountName) + account, err := client.Storage.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return nil, fmt.Errorf("retrieving Account %q for Directory %q (Share %q): %s", id.AccountName, id.DirectoryName, id.ShareName, err) + return nil, fmt.Errorf("retrieving Account %q for Directory %q (Share %q): %s", id.AccountId.AccountName, id.DirectoryPath, id.ShareName, err) } if account == nil { - return nil, fmt.Errorf("unable to determine Resource Group for Storage Share Directory %q (Share %q / Account %q)", id.DirectoryName, id.ShareName, id.AccountName) + return nil, fmt.Errorf("unable to determine Resource Group for Storage Share Directory %q (Share %q / Account %q)", id.DirectoryPath, id.ShareName, id.AccountId.AccountName) } - dirClient, err := client.Storage.FileShareDirectoriesClient(ctx, *account) + dirClient, err := client.Storage.FileShareDirectoriesDataPlaneClient(ctx, *account, client.Storage.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return nil, fmt.Errorf("building File Share client for Storage Account %q (Resource Group %q): %+v", id.AccountName, account.ResourceGroup, err) + return nil, fmt.Errorf("building File Share client for Storage Account %q (Resource Group %q): %+v", id.AccountId.AccountName, account.ResourceGroup, err) } - resp, err := dirClient.Get(ctx, id.AccountName, id.ShareName, id.DirectoryName) + resp, err := dirClient.Get(ctx, id.ShareName, id.DirectoryPath) if err != nil { - if utils.ResponseWasNotFound(resp.Response) { + if response.WasNotFound(resp.HttpResponse) { return utils.Bool(false), nil } - return nil, fmt.Errorf("retrieving Storage Share %q (File Share %q / Account %q / Resource Group %q): %s", id.DirectoryName, id.ShareName, id.AccountName, account.ResourceGroup, err) + return nil, fmt.Errorf("retrieving Storage Share %q (File Share %q / Account %q / Resource Group %q): %s", id.DirectoryPath, id.ShareName, id.AccountId.AccountName, account.ResourceGroup, err) } return utils.Bool(true), nil } @@ -149,6 +196,18 @@ func (r StorageShareDirectoryResource) basic(data acceptance.TestData) string { return fmt.Sprintf(` %s +resource "azurerm_storage_share_directory" "test" { + name = "dir" + storage_share_id = azurerm_storage_share.test.id +} +`, template) +} + +func (r StorageShareDirectoryResource) basicDeprecated(data acceptance.TestData) string { + template := r.template(data) + return fmt.Sprintf(` +%s + resource "azurerm_storage_share_directory" "test" { name = "dir" share_name = azurerm_storage_share.test.name @@ -163,9 +222,8 @@ func (r StorageShareDirectoryResource) uppercase(data acceptance.TestData) strin %s resource "azurerm_storage_share_directory" "test" { - name = "UpperCaseCharacterS" - share_name = azurerm_storage_share.test.name - storage_account_name = azurerm_storage_account.test.name + name = "UpperCaseCharacterS" + storage_share_id = azurerm_storage_share.test.id } `, template) } @@ -176,9 +234,8 @@ func (r StorageShareDirectoryResource) requiresImport(data acceptance.TestData) %s resource "azurerm_storage_share_directory" "import" { - name = azurerm_storage_share_directory.test.name - share_name = azurerm_storage_share_directory.test.share_name - storage_account_name = azurerm_storage_share_directory.test.storage_account_name + name = azurerm_storage_share_directory.test.name + storage_share_id = azurerm_storage_share.test.id } `, template) } @@ -189,9 +246,8 @@ func (r StorageShareDirectoryResource) complete(data acceptance.TestData) string %s resource "azurerm_storage_share_directory" "test" { - name = "dir" - share_name = azurerm_storage_share.test.name - storage_account_name = azurerm_storage_account.test.name + name = "dir" + storage_share_id = azurerm_storage_share.test.id metadata = { hello = "world" @@ -206,9 +262,8 @@ func (r StorageShareDirectoryResource) updated(data acceptance.TestData) string %s resource "azurerm_storage_share_directory" "test" { - name = "dir" - share_name = azurerm_storage_share.test.name - storage_account_name = azurerm_storage_account.test.name + name = "dir" + storage_share_id = azurerm_storage_share.test.id metadata = { hello = "world" @@ -224,27 +279,23 @@ func (r StorageShareDirectoryResource) nested(data acceptance.TestData) string { %s resource "azurerm_storage_share_directory" "parent" { - name = "123--parent-dir" - share_name = azurerm_storage_share.test.name - storage_account_name = azurerm_storage_account.test.name + name = "123--parent-dir" + storage_share_id = azurerm_storage_share.test.id } resource "azurerm_storage_share_directory" "child_one" { - name = "${azurerm_storage_share_directory.parent.name}/child1" - share_name = azurerm_storage_share.test.name - storage_account_name = azurerm_storage_account.test.name + name = "${azurerm_storage_share_directory.parent.name}/child1" + storage_share_id = azurerm_storage_share.test.id } resource "azurerm_storage_share_directory" "child_two" { - name = "${azurerm_storage_share_directory.child_one.name}/childtwo--123" - share_name = azurerm_storage_share.test.name - storage_account_name = azurerm_storage_account.test.name + name = "${azurerm_storage_share_directory.child_one.name}/childtwo--123" + storage_share_id = azurerm_storage_share.test.id } resource "azurerm_storage_share_directory" "multiple_child_one" { - name = "${azurerm_storage_share_directory.parent.name}/c" - share_name = azurerm_storage_share.test.name - storage_account_name = azurerm_storage_account.test.name + name = "${azurerm_storage_share_directory.parent.name}/c" + storage_share_id = azurerm_storage_share.test.id } `, template) } diff --git a/internal/services/storage/storage_share_file_resource.go b/internal/services/storage/storage_share_file_resource.go index 48b4cf882332d..a0d766f8df86d 100644 --- a/internal/services/storage/storage_share_file_resource.go +++ b/internal/services/storage/storage_share_file_resource.go @@ -9,15 +9,18 @@ import ( "os" "time" + "github.com/hashicorp/go-azure-helpers/lang/response" "github.com/hashicorp/terraform-provider-azurerm/helpers/tf" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/helpers" "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/parse" storageValidate "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/validate" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" "github.com/hashicorp/terraform-provider-azurerm/internal/timeouts" "github.com/hashicorp/terraform-provider-azurerm/utils" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files" ) func resourceStorageShareFile() *pluginsdk.Resource { @@ -27,8 +30,8 @@ func resourceStorageShareFile() *pluginsdk.Resource { Update: resourceStorageShareFileUpdate, Delete: resourceStorageShareFileDelete, - Importer: pluginsdk.ImporterValidatingResourceId(func(id string) error { - _, err := files.ParseResourceID(id) + Importer: helpers.ImporterValidatingStorageResourceId(func(id, storageDomainSuffix string) error { + _, err := files.ParseFileID(id, storageDomainSuffix) return err }), @@ -45,12 +48,14 @@ func resourceStorageShareFile() *pluginsdk.Resource { Required: true, ForceNew: true, }, + "storage_share_id": { Type: pluginsdk.TypeString, Required: true, ForceNew: true, - ValidateFunc: storageValidate.StorageShareID, + ValidateFunc: validation.IsURLWithPath, // note: storage domain suffix cannot be determined at validation time, so just make sure it's a well-formed URL }, + "path": { Type: pluginsdk.TypeString, ForceNew: true, @@ -106,7 +111,7 @@ func resourceStorageShareFileCreate(d *pluginsdk.ResourceData, meta interface{}) defer cancel() storageClient := meta.(*clients.Client).Storage - storageShareID, err := parse.StorageShareDataPlaneID(d.Get("storage_share_id").(string)) + storageShareId, err := parse.StorageShareDataPlaneID(d.Get("storage_share_id").(string), storageClient.StorageDomainSuffix) if err != nil { return err } @@ -114,42 +119,48 @@ func resourceStorageShareFileCreate(d *pluginsdk.ResourceData, meta interface{}) fileName := d.Get("name").(string) path := d.Get("path").(string) - account, err := storageClient.FindAccount(ctx, storageShareID.AccountName) + account, err := storageClient.FindAccount(ctx, storageShareId.AccountName) if err != nil { - return fmt.Errorf("eretrieving Account %q for File %q (Share %q): %s", storageShareID.AccountName, fileName, storageShareID.Name, err) + return fmt.Errorf("retrieving Account %q for File %q (Share %q): %v", storageShareId.AccountName, fileName, storageShareId.Name, err) } if account == nil { - return fmt.Errorf("unable to locate Storage Account %q!", storageShareID.AccountName) + return fmt.Errorf("locating Storage Account %q", storageShareId.AccountName) } - fileSharesClient, err := storageClient.FileSharesClient(ctx, *account) + accountId, err := accounts.ParseAccountID(storageShareId.ID(), storageClient.StorageDomainSuffix) if err != nil { - return fmt.Errorf("building File Share Directories Client: %s", err) + return fmt.Errorf("parsing Account ID: %v", err) } - share, err := fileSharesClient.Get(ctx, account.ResourceGroup, storageShareID.AccountName, storageShareID.Name) + id := files.NewFileID(*accountId, storageShareId.Name, path, fileName) + + fileSharesClient, err := storageClient.FileSharesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("retrieving Share %q for File %q: %s", storageShareID.Name, fileName, err) + return fmt.Errorf("building File Share Directories Client: %v", err) + } + + share, err := fileSharesClient.Get(ctx, storageShareId.Name) + if err != nil { + return fmt.Errorf("retrieving Share %q for File %q: %v", storageShareId.Name, fileName, err) } if share == nil { - return fmt.Errorf("unable to locate Storage Share %q", storageShareID.Name) + return fmt.Errorf("unable to locate Storage Share %q", storageShareId.Name) } - client, err := storageClient.FileShareFilesClient(ctx, *account) + client, err := storageClient.FileShareFilesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { return fmt.Errorf("building File Share Directories Client: %s", err) } - existing, err := client.GetProperties(ctx, storageShareID.AccountName, storageShareID.Name, path, fileName) + existing, err := client.GetProperties(ctx, storageShareId.Name, path, fileName) if err != nil { - if !utils.ResponseWasNotFound(existing.Response) { - return fmt.Errorf("checking for presence of existing File %q (File Share %q / Storage Account %q / Resource Group %q): %s", fileName, storageShareID.Name, storageShareID.AccountName, account.ResourceGroup, err) + if !response.WasNotFound(existing.HttpResponse) { + return fmt.Errorf("checking for existing %s: %v", id, err) } } - if !utils.ResponseWasNotFound(existing.Response) { - id := client.GetResourceID(storageShareID.AccountName, storageShareID.Name, path, fileName) - return tf.ImportAsExistsError("azurerm_storage_share_file", id) + if !response.WasNotFound(existing.HttpResponse) { + return tf.ImportAsExistsError("azurerm_storage_share_file", id.ID()) } input := files.CreateInput{ @@ -167,33 +178,32 @@ func resourceStorageShareFileCreate(d *pluginsdk.ResourceData, meta interface{}) if v, ok := d.GetOk("source"); ok { file, err = os.Open(v.(string)) if err != nil { - return fmt.Errorf("opening file : %s", err) + return fmt.Errorf("opening file: %s", err) } info, err := file.Stat() if err != nil { - return fmt.Errorf("'stat'-ing File %q (File Share %q / Account %q): %+v", fileName, storageShareID.Name, storageShareID.AccountName, err) + return fmt.Errorf("'stat'-ing File %q (File Share %q / Account %q): %v", fileName, storageShareId.Name, storageShareId.AccountName, err) } if info.Size() == 0 { - return fmt.Errorf("file %q (File Share %q / Account %q) is empty", fileName, storageShareID.Name, storageShareID.AccountName) + return fmt.Errorf("file %q (File Share %q / Account %q) is empty", fileName, storageShareId.Name, storageShareId.AccountName) } input.ContentLength = info.Size() } - if _, err := client.Create(ctx, storageShareID.AccountName, storageShareID.Name, path, fileName, input); err != nil { - return fmt.Errorf("creating File %q (File Share %q / Account %q): %+v", fileName, storageShareID.Name, storageShareID.AccountName, err) + if _, err = client.Create(ctx, storageShareId.Name, path, fileName, input); err != nil { + return fmt.Errorf("creating File %q (File Share %q / Account %q): %v", fileName, storageShareId.Name, storageShareId.AccountName, err) } if file != nil { - if err := client.PutFile(ctx, storageShareID.AccountName, storageShareID.Name, path, fileName, file, 4); err != nil { - return fmt.Errorf("uploading File: %q (File Share %q / Account %q): %+v", fileName, storageShareID.Name, storageShareID.AccountName, err) + if err = client.PutFile(ctx, storageShareId.Name, path, fileName, file, 4); err != nil { + return fmt.Errorf("uploading File: %q (File Share %q / Account %q): %v", fileName, storageShareId.Name, storageShareId.AccountName, err) } } - resourceID := client.GetResourceID(storageShareID.AccountName, storageShareID.Name, path, fileName) - d.SetId(resourceID) + d.SetId(id.ID()) return resourceStorageShareFileRead(d, meta) } @@ -203,41 +213,41 @@ func resourceStorageShareFileUpdate(d *pluginsdk.ResourceData, meta interface{}) defer cancel() storageClient := meta.(*clients.Client).Storage - id, err := files.ParseResourceID(d.Id()) + id, err := files.ParseFileID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { return err } - account, err := storageClient.FindAccount(ctx, id.AccountName) + account, err := storageClient.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for File %q (Share %q): %s", id.AccountName, id.FileName, id.ShareName, err) + return fmt.Errorf("retrieving Account %q for %s: %v", id.AccountId.AccountName, id, err) } if account == nil { - return fmt.Errorf("unable to locate Storage Account %q!", id.AccountName) + return fmt.Errorf("locating Storage Account %q", id.AccountId.AccountName) } - fileSharesClient, err := storageClient.FileSharesClient(ctx, *account) + fileSharesClient, err := storageClient.FileSharesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building File Share Directories Client: %s", err) + return fmt.Errorf("building File Share Directories Client: %v", err) } - share, err := fileSharesClient.Get(ctx, account.ResourceGroup, id.AccountName, id.ShareName) + share, err := fileSharesClient.Get(ctx, id.ShareName) if err != nil { - return fmt.Errorf("retrieving Share %q for File %q: %s", id.ShareName, id.FileName, err) + return fmt.Errorf("retrieving %s: %v", id, err) } if share == nil { return fmt.Errorf("unable to locate Storage Share %q", id.ShareName) } - client, err := storageClient.FileShareFilesClient(ctx, *account) + client, err := storageClient.FileShareFilesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building File Share Files Client: %s", err) + return fmt.Errorf("building File Share Files Client: %v", err) } - existing, err := client.GetProperties(ctx, id.AccountName, id.ShareName, id.DirectoryName, id.FileName) + existing, err := client.GetProperties(ctx, id.ShareName, id.DirectoryPath, id.FileName) if err != nil { - if !utils.ResponseWasNotFound(existing.Response) { - return fmt.Errorf("checking for presence of existing File %q (File Share %q / Storage Account %q / Resource Group %q): %s", id.FileName, id.ShareName, id.AccountName, account.ResourceGroup, err) + if !response.WasNotFound(existing.HttpResponse) { + return fmt.Errorf("checking for presence of existing %s: %v", id, err) } } @@ -254,8 +264,8 @@ func resourceStorageShareFileUpdate(d *pluginsdk.ResourceData, meta interface{}) input.ContentMD5 = utils.String(v.(string)) } - if _, err := client.SetProperties(ctx, id.AccountName, id.ShareName, id.DirectoryName, id.FileName, input); err != nil { - return fmt.Errorf("creating File %q (File Share %q / Account %q): %+v", id.FileName, id.ShareName, id.AccountName, err) + if _, err = client.SetProperties(ctx, id.ShareName, id.DirectoryPath, id.FileName, input); err != nil { + return fmt.Errorf("creating %s: %v", id, err) } } @@ -267,53 +277,53 @@ func resourceStorageShareFileRead(d *pluginsdk.ResourceData, meta interface{}) e defer cancel() storageClient := meta.(*clients.Client).Storage - id, err := files.ParseResourceID(d.Id()) + id, err := files.ParseFileID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { return err } - account, err := storageClient.FindAccount(ctx, id.AccountName) + account, err := storageClient.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for File %q (Share %q): %s", id.AccountName, id.FileName, id.ShareName, err) + return fmt.Errorf("retrieving Account %q for File %q (Share %q): %s", id.AccountId.AccountName, id.FileName, id.ShareName, err) } if account == nil { - log.Printf("[WARN] Unable to determine Storage Account for Storage Share File %q (Share %s, Account %s) - assuming removed & removing from state", id.FileName, id.ShareName, id.AccountName) + log.Printf("[WARN] Unable to determine Storage Account for %s - assuming removed & removing from state", id) d.SetId("") return nil } - fileSharesClient, err := storageClient.FileSharesClient(ctx, *account) + fileSharesClient, err := storageClient.FileSharesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { return fmt.Errorf("building File Share Directories Client: %s", err) } - share, err := fileSharesClient.Get(ctx, account.ResourceGroup, id.AccountName, id.ShareName) + share, err := fileSharesClient.Get(ctx, id.ShareName) if err != nil { return fmt.Errorf("retrieving Share %q for File %q: %s", id.ShareName, id.FileName, err) } if share == nil { - log.Printf("[WARN] Unable to determine Storage Share for Storage Share File %q (Share %s, Account %s) - assuming removed & removing from state", id.FileName, id.ShareName, id.AccountName) + log.Printf("[WARN] Unable to determine Storage Share for %s - assuming removed & removing from state", id) d.SetId("") return nil } - client, err := storageClient.FileShareFilesClient(ctx, *account) + client, err := storageClient.FileShareFilesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building File Share Client for Storage Account %q (Resource Group %q): %s", id.AccountName, account.ResourceGroup, err) + return fmt.Errorf("building File Share Client for Storage Account %s: %s", id.AccountId, err) } - props, err := client.GetProperties(ctx, id.AccountName, id.ShareName, id.DirectoryName, id.FileName) + props, err := client.GetProperties(ctx, id.ShareName, id.DirectoryPath, id.FileName) if err != nil { - log.Printf("Retrieving Storage File Share file %q (Directory %q / File Share %q / Account %q / Resource Group %q): %s", id.FileName, id.DirectoryName, id.ShareName, id.AccountName, account.ResourceGroup, err) + log.Printf("retrieving %s: %s", id, err) d.SetId("") return nil } d.Set("name", id.FileName) - d.Set("path", id.DirectoryName) - d.Set("storage_share_id", parse.NewStorageShareDataPlaneId(id.AccountName, storageClient.Environment.StorageEndpointSuffix, id.ShareName).ID()) + d.Set("path", id.DirectoryPath) + d.Set("storage_share_id", parse.NewStorageShareDataPlaneId(id.AccountId.AccountName, storageClient.AzureEnvironment.StorageEndpointSuffix, id.ShareName).ID()) - if err := d.Set("metadata", FlattenMetaData(props.MetaData)); err != nil { + if err = d.Set("metadata", FlattenMetaData(props.MetaData)); err != nil { return fmt.Errorf("setting `metadata`: %s", err) } d.Set("content_type", props.ContentType) @@ -335,26 +345,26 @@ func resourceStorageShareFileDelete(d *pluginsdk.ResourceData, meta interface{}) defer cancel() storageClient := meta.(*clients.Client).Storage - id, err := files.ParseResourceID(d.Id()) + id, err := files.ParseFileID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { return err } - account, err := storageClient.FindAccount(ctx, id.AccountName) + account, err := storageClient.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for File %q (Share %q): %s", id.AccountName, id.FileName, id.ShareName, err) + return fmt.Errorf("retrieving Account %q for File %q (Share %q): %v", id.AccountId.AccountName, id.FileName, id.ShareName, err) } if account == nil { - return fmt.Errorf("unable to locate Storage Account %q", id.AccountName) + return fmt.Errorf("locating Storage Account %q", id.AccountId.AccountName) } - client, err := storageClient.FileShareFilesClient(ctx, *account) + client, err := storageClient.FileShareFilesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building File Share File Client for Storage Account %q (Resource Group %q): %s", id.AccountName, account.ResourceGroup, err) + return fmt.Errorf("building File Share File Client for Storage Account %q (Resource Group %q): %v", id.AccountId.AccountName, account.ResourceGroup, err) } - if _, err := client.Delete(ctx, id.AccountName, id.ShareName, id.DirectoryName, id.FileName); err != nil { - return fmt.Errorf("deleting Storage Share File %q (File Share %q / Account %q / Resource Group %q): %s", id.FileName, id.ShareName, id.AccountName, account.ResourceGroup, err) + if _, err = client.Delete(ctx, id.ShareName, id.DirectoryPath, id.FileName); err != nil { + return fmt.Errorf("deleting %s: %v", id, err) } return nil diff --git a/internal/services/storage/storage_share_file_resource_test.go b/internal/services/storage/storage_share_file_resource_test.go index 2a2b5b0b3d643..e488f909e9be8 100644 --- a/internal/services/storage/storage_share_file_resource_test.go +++ b/internal/services/storage/storage_share_file_resource_test.go @@ -10,12 +10,13 @@ import ( "regexp" "testing" + "github.com/hashicorp/go-azure-helpers/lang/response" "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance" "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/utils" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files" ) type StorageShareFileResource struct{} @@ -137,28 +138,28 @@ func TestAccAzureRMStorageShareFile_withEmptyFile(t *testing.T) { } func (StorageShareFileResource) Exists(ctx context.Context, clients *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { - id, err := files.ParseResourceID(state.ID) + id, err := files.ParseFileID(state.ID, clients.Storage.StorageDomainSuffix) if err != nil { return nil, err } - account, err := clients.Storage.FindAccount(ctx, id.AccountName) + account, err := clients.Storage.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return nil, fmt.Errorf("retrieving Account %q for File %q (Share %q): %s", id.AccountName, id.FileName, id.ShareName, err) + return nil, fmt.Errorf("retrieving Account %q for File %q (Share %q): %s", id.AccountId.AccountName, id.FileName, id.ShareName, err) } if account == nil { return utils.Bool(false), nil } - client, err := clients.Storage.FileShareFilesClient(ctx, *account) + client, err := clients.Storage.FileShareFilesDataPlaneClient(ctx, *account, clients.Storage.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { return nil, fmt.Errorf("building File Share Files Client: %s", err) } - resp, err := client.GetProperties(ctx, id.AccountName, id.ShareName, id.DirectoryName, id.FileName) + resp, err := client.GetProperties(ctx, id.ShareName, id.DirectoryPath, id.FileName) if err != nil { - if !utils.ResponseWasNotFound(resp.Response) { - return nil, fmt.Errorf("checking for presence of existing File %q (File Share %q / Storage Account %q / Resource Group %q): %s", id.FileName, id.ShareName, id.AccountName, account.ResourceGroup, err) + if !response.WasNotFound(resp.HttpResponse) { + return nil, fmt.Errorf("checking for presence of existing File %q (File Share %q / Storage Account %q / Resource Group %q): %s", id.FileName, id.ShareName, id.AccountId.AccountName, account.ResourceGroup, err) } } diff --git a/internal/services/storage/storage_share_resource.go b/internal/services/storage/storage_share_resource.go index 42c4f458f3419..86b934d172df9 100644 --- a/internal/services/storage/storage_share_resource.go +++ b/internal/services/storage/storage_share_resource.go @@ -11,13 +11,14 @@ import ( "github.com/Azure/azure-sdk-for-go/services/storage/mgmt/2021-09-01/storage" // nolint: staticcheck "github.com/hashicorp/terraform-provider-azurerm/helpers/tf" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/helpers" "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/migration" "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/parse" "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/validate" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" "github.com/hashicorp/terraform-provider-azurerm/internal/timeouts" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares" ) func resourceStorageShare() *pluginsdk.Resource { @@ -27,8 +28,8 @@ func resourceStorageShare() *pluginsdk.Resource { Update: resourceStorageShareUpdate, Delete: resourceStorageShareDelete, - Importer: pluginsdk.ImporterValidatingResourceId(func(id string) error { - _, err := parse.StorageShareDataPlaneID(id) + Importer: helpers.ImporterValidatingStorageResourceId(func(id, storageDomainSuffix string) error { + _, err := parse.StorageShareDataPlaneID(id, storageDomainSuffix) return err }), @@ -158,12 +159,14 @@ func resourceStorageShareCreate(d *pluginsdk.ResourceData, meta interface{}) err account, err := storageClient.FindAccount(ctx, accountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Share %q: %s", accountName, shareName, err) + return fmt.Errorf("retrieving Account %q for Share %q: %v", accountName, shareName, err) } if account == nil { - return fmt.Errorf("Unable to locate Storage Account %q!", accountName) + return fmt.Errorf("locating Storage Account %q", accountName) } + id := parse.NewStorageShareDataPlaneId(accountName, storageClient.StorageDomainSuffix, shareName) + protocol := shares.ShareProtocol(d.Get("enabled_protocol").(string)) if protocol == shares.NFS { // Only FileStorage (whose sku tier is Premium only) storage account is able to have NFS file shares. @@ -173,19 +176,18 @@ func resourceStorageShareCreate(d *pluginsdk.ResourceData, meta interface{}) err } } - client, err := storageClient.FileSharesClient(ctx, *account) + // The files API does not support bearer tokens (@manicminer, 2024-02-15) + client, err := storageClient.FileSharesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingOnlySharedKeyAuth()) if err != nil { - return fmt.Errorf("building File Share Client: %s", err) + return fmt.Errorf("building File Share Client: %v", err) } - id := parse.NewStorageShareDataPlaneId(accountName, storageClient.Environment.StorageEndpointSuffix, shareName).ID() - - exists, err := client.Exists(ctx, account.ResourceGroup, accountName, shareName) + exists, err := client.Exists(ctx, shareName) if err != nil { - return fmt.Errorf("checking for existence of existing Storage Share %q (Account %q / Resource Group %q): %+v", shareName, accountName, account.ResourceGroup, err) + return fmt.Errorf("checking for existing %s: %v", id, err) } if exists != nil && *exists { - return tf.ImportAsExistsError("azurerm_storage_share", id) + return tf.ImportAsExistsError("azurerm_storage_share", id.ID()) } log.Printf("[INFO] Creating Share %q in Storage Account %q", shareName, accountName) @@ -200,13 +202,14 @@ func resourceStorageShareCreate(d *pluginsdk.ResourceData, meta interface{}) err input.AccessTier = &tier } - if err := client.Create(ctx, account.ResourceGroup, accountName, shareName, input); err != nil { - return fmt.Errorf("creating Share %q (Account %q / Resource Group %q): %+v", shareName, accountName, account.ResourceGroup, err) + if err = client.Create(ctx, shareName, input); err != nil { + return fmt.Errorf("creating %s: %v", id, err) } - d.SetId(id) - if err := client.UpdateACLs(ctx, account.ResourceGroup, accountName, shareName, acls); err != nil { - return fmt.Errorf("setting ACL's for Share %q (Account %q / Resource Group %q): %+v", shareName, accountName, account.ResourceGroup, err) + d.SetId(id.ID()) + + if err = client.UpdateACLs(ctx, shareName, shares.SetAclInput{SignedIdentifiers: acls}); err != nil { + return fmt.Errorf("setting ACLs for %s: %v", id, err) } return resourceStorageShareRead(d, meta) @@ -217,14 +220,14 @@ func resourceStorageShareRead(d *pluginsdk.ResourceData, meta interface{}) error defer cancel() storageClient := meta.(*clients.Client).Storage - id, err := parse.StorageShareDataPlaneID(d.Id()) + id, err := parse.StorageShareDataPlaneID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { return err } account, err := storageClient.FindAccount(ctx, id.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Share %q: %s", id.AccountName, id.Name, err) + return fmt.Errorf("retrieving Account %q for Share %q: %v", id.AccountName, id.Name, err) } if account == nil { log.Printf("[WARN] Unable to determine Account %q for Storage Share %q - assuming removed & removing from state", id.AccountName, id.Name) @@ -232,12 +235,13 @@ func resourceStorageShareRead(d *pluginsdk.ResourceData, meta interface{}) error return nil } - client, err := storageClient.FileSharesClient(ctx, *account) + // The files API does not support bearer tokens (@manicminer, 2024-02-15) + client, err := storageClient.FileSharesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingOnlySharedKeyAuth()) if err != nil { - return fmt.Errorf("building File Share Client for Storage Account %q (Resource Group %q): %s", id.AccountName, account.ResourceGroup, err) + return fmt.Errorf("building File Share Client for Storage Account %q (Resource Group %q): %v", id.AccountName, account.ResourceGroup, err) } - props, err := client.Get(ctx, account.ResourceGroup, id.AccountName, id.Name) + props, err := client.Get(ctx, id.Name) if err != nil { return err } @@ -278,70 +282,71 @@ func resourceStorageShareUpdate(d *pluginsdk.ResourceData, meta interface{}) err defer cancel() storageClient := meta.(*clients.Client).Storage - id, err := parse.StorageShareDataPlaneID(d.Id()) + id, err := parse.StorageShareDataPlaneID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { return err } account, err := storageClient.FindAccount(ctx, id.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Share %q: %s", id.AccountName, id.Name, err) + return fmt.Errorf("retrieving Account %q for Share %q: %v", id.AccountName, id.Name, err) } if account == nil { - return fmt.Errorf("Unable to locate Storage Account %q!", id.AccountName) + return fmt.Errorf("locating Storage Account %q", id.AccountName) } - client, err := storageClient.FileSharesClient(ctx, *account) + // The files API does not support bearer tokens (@manicminer, 2024-02-15) + client, err := storageClient.FileSharesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingOnlySharedKeyAuth()) if err != nil { - return fmt.Errorf("building File Share Client for Storage Account %q (Resource Group %q): %s", id.AccountName, account.ResourceGroup, err) + return fmt.Errorf("building File Share Client for Storage Account %q (Resource Group %q): %v", id.AccountName, account.ResourceGroup, err) } if d.HasChange("quota") { - log.Printf("[DEBUG] Updating the Quota for File Share %q (Storage Account %q)", id.Name, id.AccountName) + log.Printf("[DEBUG] Updating the Quota for %s", id) quota := d.Get("quota").(int) - if err := client.UpdateQuota(ctx, account.ResourceGroup, id.AccountName, id.Name, quota); err != nil { - return fmt.Errorf("updating Quota for File Share %q (Storage Account %q): %s", id.Name, id.AccountName, err) + if err = client.UpdateQuota(ctx, id.Name, quota); err != nil { + return fmt.Errorf("updating Quota for %s: %v", id, err) } - log.Printf("[DEBUG] Updated the Quota for File Share %q (Storage Account %q)", id.Name, id.AccountName) + log.Printf("[DEBUG] Updated the Quota for %s", id) } if d.HasChange("metadata") { - log.Printf("[DEBUG] Updating the MetaData for File Share %q (Storage Account %q)", id.Name, id.AccountName) + log.Printf("[DEBUG] Updating the MetaData for %s", id) metaDataRaw := d.Get("metadata").(map[string]interface{}) metaData := ExpandMetaData(metaDataRaw) - if err := client.UpdateMetaData(ctx, account.ResourceGroup, id.AccountName, id.Name, metaData); err != nil { - return fmt.Errorf("updating MetaData for File Share %q (Storage Account %q): %s", id.Name, id.AccountName, err) + if err = client.UpdateMetaData(ctx, id.Name, metaData); err != nil { + return fmt.Errorf("updating MetaData for %s: %v", id, err) } - log.Printf("[DEBUG] Updated the MetaData for File Share %q (Storage Account %q)", id.Name, id.AccountName) + log.Printf("[DEBUG] Updated the MetaData for %s", id) } if d.HasChange("acl") { - log.Printf("[DEBUG] Updating the ACL's for File Share %q (Storage Account %q)", id.Name, id.AccountName) + log.Printf("[DEBUG] Updating the ACLs for %s", id) aclsRaw := d.Get("acl").(*pluginsdk.Set).List() acls := expandStorageShareACLs(aclsRaw) - if err := client.UpdateACLs(ctx, account.ResourceGroup, id.AccountName, id.Name, acls); err != nil { - return fmt.Errorf("updating ACL's for File Share %q (Storage Account %q): %s", id.Name, id.AccountName, err) + if err = client.UpdateACLs(ctx, id.Name, shares.SetAclInput{SignedIdentifiers: acls}); err != nil { + return fmt.Errorf("updating ACLs for %s: %v", id, err) } - log.Printf("[DEBUG] Updated the ACL's for File Share %q (Storage Account %q)", id.Name, id.AccountName) + log.Printf("[DEBUG] Updated ACLs for %s", id) } if d.HasChange("access_tier") { - log.Printf("[DEBUG] Updating the Access Tier for File Share %q (Storage Account %q)", id.Name, id.AccountName) + log.Printf("[DEBUG] Updating Access Tier for %s", id) tier := shares.AccessTier(d.Get("access_tier").(string)) - if err := client.UpdateTier(ctx, account.ResourceGroup, id.AccountName, id.Name, tier); err != nil { - return fmt.Errorf("updating Access Tier for File Share %q (Storage Account %q): %s", id.Name, id.AccountName, err) + if err = client.UpdateTier(ctx, id.Name, tier); err != nil { + return fmt.Errorf("updating Access Tier for %s: %v", id, err) } - log.Printf("[DEBUG] Updated the Access Tier for File Share %q (Storage Account %q)", id.Name, id.AccountName) + log.Printf("[DEBUG] Updated Access Tier for %s", id) } return resourceStorageShareRead(d, meta) @@ -352,26 +357,27 @@ func resourceStorageShareDelete(d *pluginsdk.ResourceData, meta interface{}) err defer cancel() storageClient := meta.(*clients.Client).Storage - id, err := parse.StorageShareDataPlaneID(d.Id()) + id, err := parse.StorageShareDataPlaneID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { return err } account, err := storageClient.FindAccount(ctx, id.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Share %q: %s", id.AccountName, id.Name, err) + return fmt.Errorf("retrieving Account %q for Share %q: %v", id.AccountName, id.Name, err) } if account == nil { - return fmt.Errorf("unable to locate Storage Account %q!", id.AccountName) + return fmt.Errorf("locating Storage Account %q", id.AccountName) } - client, err := storageClient.FileSharesClient(ctx, *account) + // The files API does not support bearer tokens (@manicminer, 2024-02-15) + client, err := storageClient.FileSharesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingOnlySharedKeyAuth()) if err != nil { - return fmt.Errorf("building File Share Client for Storage Account %q (Resource Group %q): %s", id.AccountName, account.ResourceGroup, err) + return fmt.Errorf("building File Share Client for Storage Account %q (Resource Group %q): %v", id.AccountName, account.ResourceGroup, err) } - if err := client.Delete(ctx, account.ResourceGroup, id.AccountName, id.Name); err != nil { - return fmt.Errorf("deleting File Share %q (Storage Account %q / Resource Group %q): %s", id.Name, id.AccountName, account.ResourceGroup, err) + if err = client.Delete(ctx, id.Name); err != nil { + return fmt.Errorf("deleting %s: %v", id, err) } return nil diff --git a/internal/services/storage/storage_share_resource_test.go b/internal/services/storage/storage_share_resource_test.go index aec5733e28d29..f9ae4c88cdf17 100644 --- a/internal/services/storage/storage_share_resource_test.go +++ b/internal/services/storage/storage_share_resource_test.go @@ -271,7 +271,7 @@ func TestAccStorageShare_protocolUpdate(t *testing.T) { } func (r StorageShareResource) Exists(ctx context.Context, client *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { - id, err := parse.StorageShareDataPlaneID(state.ID) + id, err := parse.StorageShareDataPlaneID(state.ID, client.Storage.StorageDomainSuffix) if err != nil { return nil, err } @@ -284,12 +284,12 @@ func (r StorageShareResource) Exists(ctx context.Context, client *clients.Client return nil, fmt.Errorf("unable to determine Account %q for Storage Share %q", id.AccountName, id.Name) } - sharesClient, err := client.Storage.FileSharesClient(ctx, *account) + sharesClient, err := client.Storage.FileSharesDataPlaneClient(ctx, *account, client.Storage.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { return nil, fmt.Errorf("building File Share Client for Storage Account %q (Resource Group %q): %+v", id.AccountName, account.ResourceGroup, err) } - props, err := sharesClient.Get(ctx, account.ResourceGroup, id.AccountName, id.Name) + props, err := sharesClient.Get(ctx, id.Name) if err != nil { return nil, fmt.Errorf("retrieving File Share %q (Account %q / Resource Group %q): %+v", id.Name, id.AccountName, account.ResourceGroup, err) } @@ -297,7 +297,7 @@ func (r StorageShareResource) Exists(ctx context.Context, client *clients.Client } func (r StorageShareResource) Destroy(ctx context.Context, client *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { - id, err := parse.StorageShareDataPlaneID(state.ID) + id, err := parse.StorageShareDataPlaneID(state.ID, client.Storage.StorageDomainSuffix) if err != nil { return nil, err } @@ -310,11 +310,11 @@ func (r StorageShareResource) Destroy(ctx context.Context, client *clients.Clien return nil, fmt.Errorf("unable to determine Account %q for Storage Share %q", id.AccountName, id.Name) } - sharesClient, err := client.Storage.FileSharesClient(ctx, *account) + sharesClient, err := client.Storage.FileSharesDataPlaneClient(ctx, *account, client.Storage.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { return nil, fmt.Errorf("building File Share Client for Storage Account %q (Resource Group %q): %+v", id.AccountName, account.ResourceGroup, err) } - if err := sharesClient.Delete(ctx, account.ResourceGroup, id.AccountName, id.Name); err != nil { + if err := sharesClient.Delete(ctx, id.Name); err != nil { return nil, fmt.Errorf("deleting File Share %q (Account %q / Resource Group %q): %+v", id.Name, id.AccountName, account.ResourceGroup, err) } return utils.Bool(true), nil @@ -537,6 +537,7 @@ func (r StorageShareResource) accessTierStandard(data acceptance.TestData, tier return fmt.Sprintf(` provider "azurerm" { features {} + storage_use_azuread = true } resource "azurerm_resource_group" "test" { diff --git a/internal/services/storage/storage_table_entity_data_source.go b/internal/services/storage/storage_table_entity_data_source.go index 8cda4c4950f05..75ca7869a1233 100644 --- a/internal/services/storage/storage_table_entity_data_source.go +++ b/internal/services/storage/storage_table_entity_data_source.go @@ -12,7 +12,8 @@ import ( "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" "github.com/hashicorp/terraform-provider-azurerm/internal/timeouts" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities" ) func dataSourceStorageTableEntity() *pluginsdk.Resource { @@ -64,25 +65,30 @@ func dataSourceStorageTableEntityRead(d *pluginsdk.ResourceData, meta interface{ defer cancel() storageClient := meta.(*clients.Client).Storage - storageAccountName := d.Get("storage_account_name").(string) + accountName := d.Get("storage_account_name").(string) tableName := d.Get("table_name").(string) partitionKey := d.Get("partition_key").(string) rowKey := d.Get("row_key").(string) - account, err := storageClient.FindAccount(ctx, storageAccountName) + account, err := storageClient.FindAccount(ctx, accountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Table %q: %s", storageAccountName, tableName, err) + return fmt.Errorf("retrieving Account %q for Table %q: %v", accountName, tableName, err) } if account == nil { - return fmt.Errorf("the parent Storage Account %s was not found", storageAccountName) + return fmt.Errorf("the parent Storage Account %s was not found", accountName) } - client, err := storageClient.TableEntityClient(ctx, *account) + client, err := storageClient.TableEntityDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building Table Entity Client for Storage Account %q (Resource Group %q): %s", storageAccountName, account.ResourceGroup, err) + return fmt.Errorf("building Table Entity Client for Storage Account %q (Resource Group %q): %v", accountName, account.ResourceGroup, err) } - id := client.GetResourceID(storageAccountName, tableName, partitionKey, rowKey) + accountId, err := accounts.ParseAccountID(accountName, storageClient.StorageDomainSuffix) + if err != nil { + return fmt.Errorf("parsing Account ID: %v", err) + } + + id := entities.NewEntityID(*accountId, tableName, partitionKey, rowKey) input := entities.GetEntityInput{ PartitionKey: partitionKey, @@ -90,19 +96,21 @@ func dataSourceStorageTableEntityRead(d *pluginsdk.ResourceData, meta interface{ MetaDataLevel: entities.NoMetaData, } - result, err := client.Get(ctx, storageAccountName, tableName, input) + result, err := client.Get(ctx, tableName, input) if err != nil { - return fmt.Errorf("retrieving Entity (Partition Key %q / Row Key %q) (Table %q / Storage Account %q / Resource Group %q): %s", partitionKey, rowKey, tableName, storageAccountName, account.ResourceGroup, err) + return fmt.Errorf("retrieving %s: %v", id, err) } - d.Set("storage_account_name", storageAccountName) + d.Set("storage_account_name", accountName) d.Set("table_name", tableName) d.Set("partition_key", partitionKey) d.Set("row_key", rowKey) - if err := d.Set("entity", flattenEntity(result.Entity)); err != nil { - return fmt.Errorf("setting `entity` for Entity (Partition Key %q / Row Key %q) (Table %q / Storage Account %q / Resource Group %q): %s", partitionKey, rowKey, tableName, storageAccountName, account.ResourceGroup, err) + + if err = d.Set("entity", flattenEntity(result.Entity)); err != nil { + return fmt.Errorf("setting `entity` for %s: %v", id, err) } - d.SetId(id) + + d.SetId(id.ID()) return nil } diff --git a/internal/services/storage/storage_table_entity_resource.go b/internal/services/storage/storage_table_entity_resource.go index ae5d8e3345776..97a7a85c8f5e8 100644 --- a/internal/services/storage/storage_table_entity_resource.go +++ b/internal/services/storage/storage_table_entity_resource.go @@ -9,14 +9,16 @@ import ( "strings" "time" + "github.com/hashicorp/go-azure-helpers/lang/response" "github.com/hashicorp/terraform-provider-azurerm/helpers/tf" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/helpers" "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/validate" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" "github.com/hashicorp/terraform-provider-azurerm/internal/timeouts" - "github.com/hashicorp/terraform-provider-azurerm/utils" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities" ) func resourceStorageTableEntity() *pluginsdk.Resource { @@ -26,8 +28,8 @@ func resourceStorageTableEntity() *pluginsdk.Resource { Update: resourceStorageTableEntityCreateUpdate, Delete: resourceStorageTableEntityDelete, - Importer: pluginsdk.ImporterValidatingResourceId(func(id string) error { - _, err := entities.ParseResourceID(id) + Importer: helpers.ImporterValidatingStorageResourceId(func(id, storageDomainSuffix string) error { + _, err := entities.ParseEntityID(id, storageDomainSuffix) return err }), @@ -87,21 +89,28 @@ func resourceStorageTableEntityCreateUpdate(d *pluginsdk.ResourceData, meta inte account, err := storageClient.FindAccount(ctx, accountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Table %q: %s", accountName, tableName, err) + return fmt.Errorf("retrieving Account %q for Table %q: %v", accountName, tableName, err) } if account == nil { if d.IsNewResource() { - return fmt.Errorf("Unable to locate Account %q for Storage Table %q", accountName, tableName) + return fmt.Errorf("locating Storage Account %q for Table %q", accountName, tableName) } else { - log.Printf("[DEBUG] Unable to locate Account %q for Storage Table %q - assuming removed & removing from state", accountName, tableName) + log.Printf("[DEBUG] Unable to locate Storage Account %q for Table %q - assuming removed & removing from state", accountName, tableName) d.SetId("") return nil } } - client, err := storageClient.TableEntityClient(ctx, *account) + accountId, err := accounts.ParseAccountID(accountName, storageClient.StorageDomainSuffix) if err != nil { - return fmt.Errorf("building Entity Client: %s", err) + return fmt.Errorf("parsing Account ID: %s", err) + } + + id := entities.NewEntityID(*accountId, tableName, partitionKey, rowKey) + + client, err := storageClient.TableEntityDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) + if err != nil { + return fmt.Errorf("building Entity Client: %v", err) } if d.IsNewResource() { @@ -110,16 +119,15 @@ func resourceStorageTableEntityCreateUpdate(d *pluginsdk.ResourceData, meta inte RowKey: rowKey, MetaDataLevel: entities.NoMetaData, } - existing, err := client.Get(ctx, accountName, tableName, input) + existing, err := client.Get(ctx, tableName, input) if err != nil { - if !utils.ResponseWasNotFound(existing.Response) { - return fmt.Errorf("checking for presence of existing Entity (Partition Key %q / Row Key %q) (Table %q / Storage Account %q / Resource Group %q): %s", partitionKey, rowKey, tableName, accountName, account.ResourceGroup, err) + if !response.WasNotFound(existing.HttpResponse) { + return fmt.Errorf("checking for existing %s: %v", id, err) } } - if !utils.ResponseWasNotFound(existing.Response) { - id := client.GetResourceID(accountName, tableName, partitionKey, rowKey) - return tf.ImportAsExistsError("azurerm_storage_table_entity", id) + if !response.WasNotFound(existing.HttpResponse) { + return tf.ImportAsExistsError("azurerm_storage_table_entity", id.ID()) } } @@ -129,12 +137,11 @@ func resourceStorageTableEntityCreateUpdate(d *pluginsdk.ResourceData, meta inte Entity: entity, } - if _, err := client.InsertOrMerge(ctx, accountName, tableName, input); err != nil { - return fmt.Errorf("creating Entity (Partition Key %q / Row Key %q) (Table %q / Storage Account %q / Resource Group %q): %+v", partitionKey, rowKey, tableName, accountName, account.ResourceGroup, err) + if _, err = client.InsertOrMerge(ctx, tableName, input); err != nil { + return fmt.Errorf("creating %s: %v", id, err) } - resourceID := client.GetResourceID(accountName, tableName, partitionKey, rowKey) - d.SetId(resourceID) + d.SetId(id.ID()) return resourceStorageTableEntityRead(d, meta) } @@ -144,24 +151,24 @@ func resourceStorageTableEntityRead(d *pluginsdk.ResourceData, meta interface{}) defer cancel() storageClient := meta.(*clients.Client).Storage - id, err := entities.ParseResourceID(d.Id()) + id, err := entities.ParseEntityID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { return err } - account, err := storageClient.FindAccount(ctx, id.AccountName) + account, err := storageClient.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Table %q: %s", id.AccountName, id.TableName, err) + return fmt.Errorf("retrieving Account %q for Table %q: %s", id.AccountId.AccountName, id.TableName, err) } if account == nil { - log.Printf("[WARN] Unable to determine Resource Group for Storage Table %q (Account %s) - assuming removed & removing from state", id.TableName, id.AccountName) + log.Printf("[WARN] Unable to determine Resource Group for Storage Table %q (Account %s) - assuming removed & removing from state", id.TableName, id.AccountId.AccountName) d.SetId("") return nil } - client, err := storageClient.TableEntityClient(ctx, *account) + client, err := storageClient.TableEntityDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building Table Entity Client for Storage Account %q (Resource Group %q): %s", id.AccountName, account.ResourceGroup, err) + return fmt.Errorf("building Table Entity Client for Storage Account %q (Resource Group %q): %s", id.AccountId.AccountName, account.ResourceGroup, err) } input := entities.GetEntityInput{ @@ -170,17 +177,18 @@ func resourceStorageTableEntityRead(d *pluginsdk.ResourceData, meta interface{}) MetaDataLevel: entities.FullMetaData, } - result, err := client.Get(ctx, id.AccountName, id.TableName, input) + result, err := client.Get(ctx, id.TableName, input) if err != nil { - return fmt.Errorf("retrieving Entity (Partition Key %q / Row Key %q) (Table %q / Storage Account %q / Resource Group %q): %s", id.PartitionKey, id.RowKey, id.TableName, id.AccountName, account.ResourceGroup, err) + return fmt.Errorf("retrieving %s: %v", id, err) } - d.Set("storage_account_name", id.AccountName) + d.Set("storage_account_name", id.AccountId.AccountName) d.Set("table_name", id.TableName) d.Set("partition_key", id.PartitionKey) d.Set("row_key", id.RowKey) - if err := d.Set("entity", flattenEntity(result.Entity)); err != nil { - return fmt.Errorf("setting `entity` for Entity (Partition Key %q / Row Key %q) (Table %q / Storage Account %q / Resource Group %q): %s", id.PartitionKey, id.RowKey, id.TableName, id.AccountName, account.ResourceGroup, err) + + if err = d.Set("entity", flattenEntity(result.Entity)); err != nil { + return fmt.Errorf("setting `entity` for %s: %v", id, err) } return nil @@ -191,22 +199,22 @@ func resourceStorageTableEntityDelete(d *pluginsdk.ResourceData, meta interface{ defer cancel() storageClient := meta.(*clients.Client).Storage - id, err := entities.ParseResourceID(d.Id()) + id, err := entities.ParseEntityID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { return err } - account, err := storageClient.FindAccount(ctx, id.AccountName) + account, err := storageClient.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Table %q: %s", id.AccountName, id.TableName, err) + return fmt.Errorf("retrieving Storage Account %q for Table %q: %s", id.AccountId.AccountName, id.TableName, err) } if account == nil { - return fmt.Errorf("Storage Account %q was not found!", id.AccountName) + return fmt.Errorf("locating Storage Account %q", id.AccountId.AccountName) } - client, err := storageClient.TableEntityClient(ctx, *account) + client, err := storageClient.TableEntityDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building Entity Client for Storage Account %q (Resource Group %q): %s", id.AccountName, account.ResourceGroup, err) + return fmt.Errorf("building Entity Client for Storage Account %q (Resource Group %q): %s", id.AccountId.AccountName, account.ResourceGroup, err) } input := entities.DeleteEntityInput{ @@ -214,8 +222,8 @@ func resourceStorageTableEntityDelete(d *pluginsdk.ResourceData, meta interface{ RowKey: id.RowKey, } - if _, err := client.Delete(ctx, id.AccountName, id.TableName, input); err != nil { - return fmt.Errorf("deleting Entity (Partition Key %q / Row Key %q) (Table %q / Storage Account %q / Resource Group %q): %s", id.PartitionKey, id.RowKey, id.TableName, id.AccountName, account.ResourceGroup, err) + if _, err = client.Delete(ctx, id.TableName, input); err != nil { + return fmt.Errorf("deleting %s: %v", id, err) } return nil diff --git a/internal/services/storage/storage_table_entity_resource_test.go b/internal/services/storage/storage_table_entity_resource_test.go index c2edacd39f652..c62f8565dd124 100644 --- a/internal/services/storage/storage_table_entity_resource_test.go +++ b/internal/services/storage/storage_table_entity_resource_test.go @@ -8,12 +8,13 @@ import ( "fmt" "testing" + "github.com/hashicorp/go-azure-helpers/lang/response" "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance" "github.com/hashicorp/terraform-provider-azurerm/internal/acceptance/check" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/utils" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities" ) type StorageTableEntityResource struct{} @@ -116,19 +117,19 @@ func TestAccTableEntity_update_typed(t *testing.T) { } func (r StorageTableEntityResource) Exists(ctx context.Context, client *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { - id, err := entities.ParseResourceID(state.ID) + id, err := entities.ParseEntityID(state.ID, client.Storage.StorageDomainSuffix) if err != nil { return nil, err } - account, err := client.Storage.FindAccount(ctx, id.AccountName) + account, err := client.Storage.FindAccount(ctx, id.AccountId.AccountName) if err != nil { - return nil, fmt.Errorf("retrieving Account %q for Table %q: %+v", id.AccountName, id.TableName, err) + return nil, fmt.Errorf("retrieving Account %q for Table %q: %+v", id.AccountId.AccountName, id.TableName, err) } if account == nil { - return nil, fmt.Errorf("storage Account %q was not found", id.AccountName) + return nil, fmt.Errorf("storage Account %q was not found", id.AccountId.AccountName) } - entitiesClient, err := client.Storage.TableEntityClient(ctx, *account) + entitiesClient, err := client.Storage.TableEntityDataPlaneClient(ctx, *account, client.Storage.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { return nil, fmt.Errorf("building Table Entity Client: %+v", err) } @@ -138,12 +139,12 @@ func (r StorageTableEntityResource) Exists(ctx context.Context, client *clients. RowKey: id.RowKey, MetaDataLevel: entities.NoMetaData, } - resp, err := entitiesClient.Get(ctx, id.AccountName, id.TableName, input) + resp, err := entitiesClient.Get(ctx, id.TableName, input) if err != nil { - if utils.ResponseWasNotFound(resp.Response) { + if response.WasNotFound(resp.HttpResponse) { return utils.Bool(false), nil } - return nil, fmt.Errorf("retrieving Entity (Partition Key %q / Row Key %q) (Table %q / Storage Account %q / Resource Group %q): %+v", id.PartitionKey, id.RowKey, id.TableName, id.AccountName, account.ResourceGroup, err) + return nil, fmt.Errorf("retrieving Entity (Partition Key %q / Row Key %q) (Table %q / Storage Account %q / Resource Group %q): %+v", id.PartitionKey, id.RowKey, id.TableName, id.AccountId.AccountName, account.ResourceGroup, err) } return utils.Bool(true), nil } diff --git a/internal/services/storage/storage_table_resource.go b/internal/services/storage/storage_table_resource.go index 21581f05798c7..1773867840e43 100644 --- a/internal/services/storage/storage_table_resource.go +++ b/internal/services/storage/storage_table_resource.go @@ -10,13 +10,14 @@ import ( "github.com/hashicorp/terraform-provider-azurerm/helpers/tf" "github.com/hashicorp/terraform-provider-azurerm/internal/clients" + "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/helpers" "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/migration" "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/parse" "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/validate" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" "github.com/hashicorp/terraform-provider-azurerm/internal/tf/validation" "github.com/hashicorp/terraform-provider-azurerm/internal/timeouts" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables" ) func resourceStorageTable() *pluginsdk.Resource { @@ -26,8 +27,8 @@ func resourceStorageTable() *pluginsdk.Resource { Delete: resourceStorageTableDelete, Update: resourceStorageTableUpdate, - Importer: pluginsdk.ImporterValidatingResourceId(func(id string) error { - _, err := parse.StorageTableDataPlaneID(id) + Importer: helpers.ImporterValidatingStorageResourceId(func(id, storageDomainSuffix string) error { + _, err := parse.StorageTableDataPlaneID(id, storageDomainSuffix) return err }), @@ -114,32 +115,32 @@ func resourceStorageTableCreate(d *pluginsdk.ResourceData, meta interface{}) err return fmt.Errorf("retrieving Account %q for Table %q: %s", accountName, tableName, err) } if account == nil { - return fmt.Errorf("unable to locate Storage Account %q!", accountName) + return fmt.Errorf("locating Storage Account %q", accountName) } - client, err := storageClient.TablesClient(ctx, *account) + client, err := storageClient.TablesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { return fmt.Errorf("building Table Client: %s", err) } - id := parse.NewStorageTableDataPlaneId(accountName, storageClient.Environment.StorageEndpointSuffix, tableName).ID() + id := parse.NewStorageTableDataPlaneId(accountName, storageClient.AzureEnvironment.StorageEndpointSuffix, tableName) - exists, err := client.Exists(ctx, account.ResourceGroup, accountName, tableName) + exists, err := client.Exists(ctx, tableName) if err != nil { - return fmt.Errorf("checking for existence of existing Storage Table %q (Account %q / Resource Group %q): %+v", tableName, accountName, account.ResourceGroup, err) + return fmt.Errorf("checking for existing %s: %v", id, err) } if exists != nil && *exists { - return tf.ImportAsExistsError("azurerm_storage_table", id) + return tf.ImportAsExistsError("azurerm_storage_table", id.ID()) } - log.Printf("[DEBUG] Creating Table %q in Storage Account %q.", tableName, accountName) - if err := client.Create(ctx, account.ResourceGroup, accountName, tableName); err != nil { - return fmt.Errorf("creating Table %q within Storage Account %q: %s", tableName, accountName, err) + if err = client.Create(ctx, tableName); err != nil { + return fmt.Errorf("creating %s: %v", id, err) } - d.SetId(id) - if err := client.UpdateACLs(ctx, account.ResourceGroup, accountName, tableName, acls); err != nil { - return fmt.Errorf("setting ACL's for Storage Table %q (Account %q / Resource Group %q): %+v", tableName, accountName, account.ResourceGroup, err) + d.SetId(id.ID()) + + if err = client.UpdateACLs(ctx, tableName, acls); err != nil { + return fmt.Errorf("setting ACLs for %s: %v", id, err) } return resourceStorageTableRead(d, meta) @@ -150,14 +151,14 @@ func resourceStorageTableRead(d *pluginsdk.ResourceData, meta interface{}) error ctx, cancel := timeouts.ForRead(meta.(*clients.Client).StopContext, d) defer cancel() - id, err := parse.StorageTableDataPlaneID(d.Id()) + id, err := parse.StorageTableDataPlaneID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { return err } account, err := storageClient.FindAccount(ctx, id.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Table %q: %s", id.AccountName, id.Name, err) + return fmt.Errorf("retrieving Storage Account %q for Table %q: %v", id.AccountName, id.Name, err) } if account == nil { log.Printf("Unable to determine Resource Group for Storage Storage Table %q (Account %s) - assuming removed & removing from state", id.Name, id.AccountName) @@ -165,31 +166,31 @@ func resourceStorageTableRead(d *pluginsdk.ResourceData, meta interface{}) error return nil } - client, err := storageClient.TablesClient(ctx, *account) + client, err := storageClient.TablesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building Table Client: %s", err) + return fmt.Errorf("building Tables Client: %v", err) } - exists, err := client.Exists(ctx, account.ResourceGroup, id.AccountName, id.Name) + exists, err := client.Exists(ctx, id.Name) if err != nil { - return fmt.Errorf("retrieving Table %q (Storage Account %q / Resource Group %q): %s", id.Name, id.AccountName, account.ResourceGroup, err) + return fmt.Errorf("retrieving %s: %v", id, err) } if exists == nil || !*exists { - log.Printf("[DEBUG] Storage Account %q not found, removing table %q from state", id.AccountName, id.Name) + log.Printf("[DEBUG] %s not found, removing from state", id) d.SetId("") return nil } - acls, err := client.GetACLs(ctx, account.ResourceGroup, id.AccountName, id.Name) + acls, err := client.GetACLs(ctx, id.Name) if err != nil { - return fmt.Errorf("retrieving ACL's %q in Storage Account %q: %s", id.Name, id.AccountName, err) + return fmt.Errorf("retrieving ACLs for %s: %v", id, err) } d.Set("name", id.Name) d.Set("storage_account_name", id.AccountName) - if err := d.Set("acl", flattenStorageTableACLs(acls)); err != nil { - return fmt.Errorf("flattening `acl`: %+v", err) + if err = d.Set("acl", flattenStorageTableACLs(acls)); err != nil { + return fmt.Errorf("setting `acl`: %v", err) } return nil @@ -200,27 +201,26 @@ func resourceStorageTableDelete(d *pluginsdk.ResourceData, meta interface{}) err ctx, cancel := timeouts.ForDelete(meta.(*clients.Client).StopContext, d) defer cancel() - id, err := parse.StorageTableDataPlaneID(d.Id()) + id, err := parse.StorageTableDataPlaneID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { return err } account, err := storageClient.FindAccount(ctx, id.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Table %q: %s", id.AccountName, id.Name, err) + return fmt.Errorf("retrieving Storage Account %q for Table %q: %v", id.AccountName, id.Name, err) } if account == nil { - return fmt.Errorf("Unable to locate Storage Account %q!", id.AccountName) + return fmt.Errorf("locating Storage Account %q", id.AccountName) } - client, err := storageClient.TablesClient(ctx, *account) + client, err := storageClient.TablesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building Table Client: %s", err) + return fmt.Errorf("building Tables Client: %v", err) } - log.Printf("[INFO] Deleting Table %q in Storage Account %q", id.Name, id.AccountName) - if err := client.Delete(ctx, account.ResourceGroup, id.AccountName, id.Name); err != nil { - return fmt.Errorf("deleting Table %q from Storage Account %q: %s", id.Name, id.AccountName, err) + if err = client.Delete(ctx, id.Name); err != nil { + return fmt.Errorf("deleting %s: %v", id, err) } return nil @@ -231,35 +231,35 @@ func resourceStorageTableUpdate(d *pluginsdk.ResourceData, meta interface{}) err ctx, cancel := timeouts.ForUpdate(meta.(*clients.Client).StopContext, d) defer cancel() - id, err := parse.StorageTableDataPlaneID(d.Id()) + id, err := parse.StorageTableDataPlaneID(d.Id(), storageClient.StorageDomainSuffix) if err != nil { return err } account, err := storageClient.FindAccount(ctx, id.AccountName) if err != nil { - return fmt.Errorf("retrieving Account %q for Table %q: %s", id.AccountName, id.Name, err) + return fmt.Errorf("retrieving Storage Account %q for Table %q: %v", id.AccountName, id.Name, err) } if account == nil { - return fmt.Errorf("unable to locate Storage Account %q!", id.AccountName) + return fmt.Errorf("locating Storage Account %q", id.AccountName) } - client, err := storageClient.TablesClient(ctx, *account) + client, err := storageClient.TablesDataPlaneClient(ctx, *account, storageClient.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { - return fmt.Errorf("building Table Client: %s", err) + return fmt.Errorf("building Table Client: %v", err) } if d.HasChange("acl") { - log.Printf("[DEBUG] Updating the ACL's for Storage Table %q (Storage Account %q)", id.Name, id.AccountName) + log.Printf("[DEBUG] Updating ACLs for %s", id) aclsRaw := d.Get("acl").(*pluginsdk.Set).List() acls := expandStorageTableACLs(aclsRaw) - if err := client.UpdateACLs(ctx, account.ResourceGroup, id.AccountName, id.Name, acls); err != nil { - return fmt.Errorf("updating ACL's for Table %q (Storage Account %q): %s", id.Name, id.AccountName, err) + if err = client.UpdateACLs(ctx, id.Name, acls); err != nil { + return fmt.Errorf("updating ACLs for %s: %v", id, err) } - log.Printf("[DEBUG] Updated the ACL's for Storage Table %q (Storage Account %q)", id.Name, id.AccountName) + log.Printf("[DEBUG] Updated ACLs for %s", id) } return resourceStorageTableRead(d, meta) diff --git a/internal/services/storage/storage_table_resource_test.go b/internal/services/storage/storage_table_resource_test.go index 683ac23e02870..b30f6dc68fe93 100644 --- a/internal/services/storage/storage_table_resource_test.go +++ b/internal/services/storage/storage_table_resource_test.go @@ -83,7 +83,7 @@ func TestAccStorageTable_acl(t *testing.T) { } func (r StorageTableResource) Exists(ctx context.Context, client *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { - id, err := parse.StorageTableDataPlaneID(state.ID) + id, err := parse.StorageTableDataPlaneID(state.ID, client.Storage.StorageDomainSuffix) if err != nil { return nil, err } @@ -94,16 +94,16 @@ func (r StorageTableResource) Exists(ctx context.Context, client *clients.Client if account == nil { return nil, fmt.Errorf("unable to determine Resource Group for Storage Storage Table %q (Account %q)", id.Name, id.AccountName) } - tablesClient, err := client.Storage.TablesClient(ctx, *account) + tablesClient, err := client.Storage.TablesDataPlaneClient(ctx, *account, client.Storage.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { return nil, fmt.Errorf("building Table Client: %+v", err) } - return tablesClient.Exists(ctx, account.ResourceGroup, id.AccountName, id.Name) + return tablesClient.Exists(ctx, id.Name) } func (r StorageTableResource) Destroy(ctx context.Context, client *clients.Client, state *pluginsdk.InstanceState) (*bool, error) { - id, err := parse.StorageTableDataPlaneID(state.ID) + id, err := parse.StorageTableDataPlaneID(state.ID, client.Storage.StorageDomainSuffix) if err != nil { return nil, err } @@ -114,19 +114,19 @@ func (r StorageTableResource) Destroy(ctx context.Context, client *clients.Clien if account == nil { return nil, fmt.Errorf("unable to determine Resource Group for Storage Storage Table %q (Account %q)", id.Name, id.AccountName) } - tablesClient, err := client.Storage.TablesClient(ctx, *account) + tablesClient, err := client.Storage.TablesDataPlaneClient(ctx, *account, client.Storage.DataPlaneOperationSupportingAnyAuthMethod()) if err != nil { return nil, fmt.Errorf("building Table Client: %+v", err) } - exists, err := tablesClient.Exists(ctx, account.ResourceGroup, id.AccountName, id.Name) + exists, err := tablesClient.Exists(ctx, id.Name) if err != nil { return nil, fmt.Errorf("retrieving Table %q (Account %q): %+v", id.Name, id.AccountName, err) } if exists == nil || !*exists { return nil, fmt.Errorf("table %q doesn't exist in Account %q so it can't be deleted", id.Name, id.AccountName) } - if err := tablesClient.Delete(ctx, account.ResourceGroup, id.AccountName, id.Name); err != nil { + if err := tablesClient.Delete(ctx, id.Name); err != nil { return nil, fmt.Errorf("deleting Table %q (Account %q): %+v", id.Name, id.AccountName, err) } return utils.Bool(true), nil diff --git a/internal/services/storage/validate/storage_blob_properties_default_service_version.go b/internal/services/storage/validate/storage_blob_properties_default_service_version.go index f6f3e8611411d..6852d4bf11772 100644 --- a/internal/services/storage/validate/storage_blob_properties_default_service_version.go +++ b/internal/services/storage/validate/storage_blob_properties_default_service_version.go @@ -39,7 +39,7 @@ func BlobPropertiesDefaultServiceVersion(i interface{}, k string) (warnings []st "2020-02-10", "2020-04-08", "2020-06-12", - "2020-08-04", + "2023-11-03", "2020-10-02", "2020-12-06", "2021-02-12", diff --git a/internal/services/storage/validate/storage_container.go b/internal/services/storage/validate/storage_container.go index 365e785a34953..e8bb586d8ab71 100644 --- a/internal/services/storage/validate/storage_container.go +++ b/internal/services/storage/validate/storage_container.go @@ -8,6 +8,7 @@ import ( "regexp" "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/parse" + "github.com/hashicorp/terraform-provider-azurerm/internal/tf/pluginsdk" ) func StorageContainerName(v interface{}, k string) (warnings []string, errors []error) { @@ -29,16 +30,18 @@ func StorageContainerName(v interface{}, k string) (warnings []string, errors [] return warnings, errors } -func StorageContainerDataPlaneID(input interface{}, key string) (warnings []string, errors []error) { - v, ok := input.(string) - if !ok { - errors = append(errors, fmt.Errorf("expected %q to be a string", key)) - return - } +func StorageContainerDataPlaneIDForDomainSuffix(domainSuffix string) pluginsdk.SchemaValidateFunc { + return func(input interface{}, key string) (warnings []string, errors []error) { + v, ok := input.(string) + if !ok { + errors = append(errors, fmt.Errorf("expected %q to be a string", key)) + return + } - if _, err := parse.StorageContainerDataPlaneID(v); err != nil { - errors = append(errors, err) - } + if _, err := parse.StorageContainerDataPlaneID(v, domainSuffix); err != nil { + errors = append(errors, err) + } - return + return + } } diff --git a/internal/services/storage/validate/storage_share_name.go b/internal/services/storage/validate/storage_share_name.go index b79e4ee93606f..d9a2a03dcf44e 100644 --- a/internal/services/storage/validate/storage_share_name.go +++ b/internal/services/storage/validate/storage_share_name.go @@ -6,8 +6,6 @@ package validate import ( "fmt" "regexp" - - "github.com/hashicorp/terraform-provider-azurerm/internal/services/storage/parse" ) func StorageShareName(v interface{}, k string) (warnings []string, errors []error) { @@ -33,18 +31,3 @@ func StorageShareName(v interface{}, k string) (warnings []string, errors []erro } return warnings, errors } - -func StorageShareID(i interface{}, k string) (warnings []string, errors []error) { - v, ok := i.(string) - if !ok { - errors = append(errors, fmt.Errorf("expected type of %q to be string", k)) - return - } - - if _, err := parse.StorageShareDataPlaneID(v); err != nil { - errors = append(errors, fmt.Errorf("Can not parse %q as a resource id: %v", k, err)) - return - } - - return warnings, errors -} diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/snapshot_get_properties.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/snapshot_get_properties.go deleted file mode 100644 index 57a02f34e819d..0000000000000 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/snapshot_get_properties.go +++ /dev/null @@ -1,160 +0,0 @@ -package blobs - -import ( - "context" - "fmt" - "net/http" - "strconv" - "strings" - - "github.com/hashicorp/go-azure-sdk/sdk/client" - "github.com/hashicorp/go-azure-sdk/sdk/odata" - "github.com/tombuildsstuff/giovanni/storage/internal/metadata" -) - -type GetSnapshotPropertiesInput struct { - // The ID of the Lease - // This must be specified if a Lease is present on the Blob, else a 403 is returned - LeaseID *string - - // The ID of the Snapshot which should be retrieved - SnapshotID string -} - -// GetSnapshotProperties returns all user-defined metadata, standard HTTP properties, and system properties for -// the specified snapshot of a blob -func (c Client) GetSnapshotProperties(ctx context.Context, containerName, blobName string, input GetSnapshotPropertiesInput) (resp GetPropertiesResponse, err error) { - - if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") - } - - if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") - } - - if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") - } - - if input.SnapshotID == "" { - return resp, fmt.Errorf("`input.SnapshotID` cannot be an empty string") - } - - opts := client.RequestOptions{ - ExpectedStatusCodes: []int{ - http.StatusOK, - }, - HttpMethod: http.MethodHead, - OptionsObject: snapshotGetPropertiesOptions{ - input: input, - }, - Path: fmt.Sprintf("/%s/%s", containerName, blobName), - } - - req, err := c.Client.NewRequest(ctx, opts) - if err != nil { - err = fmt.Errorf("building request: %+v", err) - return - } - - resp.HttpResponse, err = req.Execute(ctx) - if err != nil { - err = fmt.Errorf("executing request: %+v", err) - return - } - - if resp.HttpResponse != nil { - if resp.HttpResponse.Header != nil { - resp.AccessTier = AccessTier(resp.HttpResponse.Header.Get("x-ms-access-tier")) - resp.AccessTierChangeTime = resp.HttpResponse.Header.Get("x-ms-access-tier-change-time") - resp.ArchiveStatus = ArchiveStatus(resp.HttpResponse.Header.Get("x-ms-archive-status")) - resp.BlobCommittedBlockCount = resp.HttpResponse.Header.Get("x-ms-blob-committed-block-count") - resp.BlobSequenceNumber = resp.HttpResponse.Header.Get("x-ms-blob-sequence-number") - resp.BlobType = BlobType(resp.HttpResponse.Header.Get("x-ms-blob-type")) - resp.CacheControl = resp.HttpResponse.Header.Get("Cache-Control") - resp.ContentDisposition = resp.HttpResponse.Header.Get("Content-Disposition") - resp.ContentEncoding = resp.HttpResponse.Header.Get("Content-Encoding") - resp.ContentLanguage = resp.HttpResponse.Header.Get("Content-Language") - resp.ContentMD5 = resp.HttpResponse.Header.Get("Content-MD5") - resp.ContentType = resp.HttpResponse.Header.Get("Content-Type") - resp.CopyCompletionTime = resp.HttpResponse.Header.Get("x-ms-copy-completion-time") - resp.CopyDestinationSnapshot = resp.HttpResponse.Header.Get("x-ms-copy-destination-snapshot") - resp.CopyID = resp.HttpResponse.Header.Get("x-ms-copy-id") - resp.CopyProgress = resp.HttpResponse.Header.Get("x-ms-copy-progress") - resp.CopySource = resp.HttpResponse.Header.Get("x-ms-copy-source") - resp.CopyStatus = CopyStatus(resp.HttpResponse.Header.Get("x-ms-copy-status")) - resp.CopyStatusDescription = resp.HttpResponse.Header.Get("x-ms-copy-status-description") - resp.CreationTime = resp.HttpResponse.Header.Get("x-ms-creation-time") - resp.ETag = resp.HttpResponse.Header.Get("Etag") - resp.LastModified = resp.HttpResponse.Header.Get("Last-Modified") - resp.LeaseDuration = LeaseDuration(resp.HttpResponse.Header.Get("x-ms-lease-duration")) - resp.LeaseState = LeaseState(resp.HttpResponse.Header.Get("x-ms-lease-state")) - resp.LeaseStatus = LeaseStatus(resp.HttpResponse.Header.Get("x-ms-lease-status")) - resp.MetaData = metadata.ParseFromHeaders(resp.HttpResponse.Header) - - if v := resp.HttpResponse.Header.Get("x-ms-access-tier-inferred"); v != "" { - b, innerErr := strconv.ParseBool(v) - if innerErr != nil { - err = fmt.Errorf("error parsing %q as a bool: %s", v, innerErr) - return - } - - resp.AccessTierInferred = b - } - - if v := resp.HttpResponse.Header.Get("Content-Length"); v != "" { - i, innerErr := strconv.Atoi(v) - if innerErr != nil { - err = fmt.Errorf("error parsing %q as an integer: %s", v, innerErr) - } - - resp.ContentLength = int64(i) - } - - if v := resp.HttpResponse.Header.Get("x-ms-incremental-copy"); v != "" { - b, innerErr := strconv.ParseBool(v) - if innerErr != nil { - err = fmt.Errorf("error parsing %q as a bool: %s", v, innerErr) - return - } - - resp.IncrementalCopy = b - } - - if v := resp.HttpResponse.Header.Get("x-ms-server-encrypted"); v != "" { - b, innerErr := strconv.ParseBool(v) - if innerErr != nil { - err = fmt.Errorf("error parsing %q as a bool: %s", v, innerErr) - return - } - - resp.ServerEncrypted = b - } - } - } - - return -} - -type snapshotGetPropertiesOptions struct { - input GetSnapshotPropertiesInput -} - -func (s snapshotGetPropertiesOptions) ToHeaders() *client.Headers { - headers := &client.Headers{} - if s.input.LeaseID != nil { - headers.Append("x-ms-lease-id", *s.input.LeaseID) - } - return headers -} - -func (s snapshotGetPropertiesOptions) ToOData() *odata.Query { - return nil -} - -func (s snapshotGetPropertiesOptions) ToQuery() *client.QueryParams { - out := &client.QueryParams{} - out.Append("snapshot", s.input.SnapshotID) - return out -} diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/create.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/create.go deleted file mode 100644 index 1acbae869d911..0000000000000 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/create.go +++ /dev/null @@ -1,88 +0,0 @@ -package containers - -import ( - "context" - "fmt" - "net/http" - - "github.com/hashicorp/go-azure-sdk/sdk/client" - "github.com/hashicorp/go-azure-sdk/sdk/odata" - "github.com/tombuildsstuff/giovanni/storage/internal/metadata" -) - -type CreateInput struct { - // Specifies whether data in the container may be accessed publicly and the level of access - AccessLevel AccessLevel - - // A name-value pair to associate with the container as metadata. - MetaData map[string]string -} - -type CreateResponse struct { - HttpResponse *client.Response - Error *ErrorResponse `xml:"Error"` -} - -// Create creates a new container under the specified account. -// If the container with the same name already exists, the operation fails. -func (c Client) Create(ctx context.Context, containerName string, input CreateInput) (resp CreateResponse, err error) { - if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") - } - if err := metadata.Validate(input.MetaData); err != nil { - return resp, fmt.Errorf("`input.MetaData` is not valid: %+v", err) - } - - opts := client.RequestOptions{ - ContentType: "application/xml; charset=utf-8", - ExpectedStatusCodes: []int{ - http.StatusCreated, - }, - HttpMethod: http.MethodPut, - OptionsObject: createOptions{ - accessLevel: input.AccessLevel, - metaData: input.MetaData, - }, - Path: fmt.Sprintf("/%s", containerName), - } - req, err := c.Client.NewRequest(ctx, opts) - if err != nil { - err = fmt.Errorf("building request: %+v", err) - return - } - resp.HttpResponse, err = req.Execute(ctx) - if err != nil { - err = fmt.Errorf("executing request: %+v", err) - return - } - - return -} - -var _ client.Options = createOptions{} - -type createOptions struct { - accessLevel AccessLevel - metaData map[string]string -} - -func (o createOptions) ToHeaders() *client.Headers { - headers := containerOptions{ - metaData: o.metaData, - }.ToHeaders() - - // If this header is not included in the request, container data is private to the account owner. - if o.accessLevel != Private { - headers.Append("x-ms-blob-public-access", string(o.accessLevel)) - } - - return headers -} - -func (createOptions) ToOData() *odata.Query { - return nil -} - -func (createOptions) ToQuery() *client.QueryParams { - return containerOptions{}.ToQuery() -} diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/properties_get.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/properties_get.go deleted file mode 100644 index 6a21f77849406..0000000000000 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/properties_get.go +++ /dev/null @@ -1,105 +0,0 @@ -package files - -import ( - "context" - "fmt" - "net/http" - "strconv" - "strings" - - "github.com/hashicorp/go-azure-sdk/sdk/client" - "github.com/tombuildsstuff/giovanni/storage/internal/metadata" -) - -type GetResponse struct { - HttpResponse *client.Response - - CacheControl string - ContentDisposition string - ContentEncoding string - ContentLanguage string - ContentLength *int64 - ContentMD5 string - ContentType string - CopyID string - CopyStatus string - CopySource string - CopyProgress string - CopyStatusDescription string - CopyCompletionTime string - Encrypted bool - - MetaData map[string]string -} - -// GetProperties returns the Properties for the specified file -func (c Client) GetProperties(ctx context.Context, shareName, path, fileName string) (resp GetResponse, err error) { - if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") - } - - if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") - } - - if fileName == "" { - return resp, fmt.Errorf("`fileName` cannot be an empty string") - } - - if path != "" { - path = fmt.Sprintf("/%s/", path) - } - - opts := client.RequestOptions{ - ContentType: "application/xml; charset=utf-8", - ExpectedStatusCodes: []int{ - http.StatusOK, - }, - HttpMethod: http.MethodHead, - OptionsObject: nil, - Path: fmt.Sprintf("%s/%s%s", shareName, path, fileName), - } - - req, err := c.Client.NewRequest(ctx, opts) - if err != nil { - err = fmt.Errorf("building request: %+v", err) - return - } - - resp.HttpResponse, err = req.Execute(ctx) - if err != nil { - err = fmt.Errorf("executing request: %+v", err) - return - } - - if resp.HttpResponse != nil { - if resp.HttpResponse.Header != nil { - resp.CacheControl = resp.HttpResponse.Header.Get("Cache-Control") - resp.ContentDisposition = resp.HttpResponse.Header.Get("Content-Disposition") - resp.ContentEncoding = resp.HttpResponse.Header.Get("Content-Encoding") - resp.ContentLanguage = resp.HttpResponse.Header.Get("Content-Language") - resp.ContentMD5 = resp.HttpResponse.Header.Get("Content-MD5") - resp.ContentType = resp.HttpResponse.Header.Get("Content-Type") - resp.CopyID = resp.HttpResponse.Header.Get("x-ms-copy-id") - resp.CopyProgress = resp.HttpResponse.Header.Get("x-ms-copy-progress") - resp.CopySource = resp.HttpResponse.Header.Get("x-ms-copy-source") - resp.CopyStatus = resp.HttpResponse.Header.Get("x-ms-copy-status") - resp.CopyStatusDescription = resp.HttpResponse.Header.Get("x-ms-copy-status-description") - resp.CopyCompletionTime = resp.HttpResponse.Header.Get("x-ms-copy-completion-time") - resp.Encrypted = strings.EqualFold(resp.HttpResponse.Header.Get("x-ms-server-encrypted"), "true") - resp.MetaData = metadata.ParseFromHeaders(resp.HttpResponse.Header) - - contentLengthRaw := resp.HttpResponse.Header.Get("Content-Length") - if contentLengthRaw != "" { - contentLength, err := strconv.Atoi(contentLengthRaw) - if err != nil { - return resp, fmt.Errorf("error parsing %q for Content-Length as an integer: %s", contentLengthRaw, err) - } - contentLengthI64 := int64(contentLength) - resp.ContentLength = &contentLengthI64 - } - } - } - - return -} diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts/README.md b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts/README.md new file mode 100644 index 0000000000000..01fdc3f22ded5 --- /dev/null +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts/README.md @@ -0,0 +1,56 @@ +## Blob Storage Account SDK for API version 2023-11-03 + +This package allows you to interact with the Accounts Blob Storage API + +### Supported Authorizers + +* Azure Active Directory + +### Example Usage + +```go +package main + +import ( + "context" + "fmt" + "time" + + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts" +) + +func Example() error { + accountName := "storageaccount1" + + // e.g. https://github.com/tombuildsstuff/giovanni/blob/76f5f686c99ecdcc3fa533a0330d0e1aacb1c327/example/azuread-auth/main.go#L54 + client, err := buildClient() + if err != nil { + return fmt.Errorf("error building client: %s", err) + } + + ctx := context.TODO() + + input := StorageServiceProperties{ + StaticWebsite: &StaticWebsite{ + Enabled: true, + IndexDocument: index, + ErrorDocument404Path: errorDocument, + }, + } + + _, err = client.SetServiceProperties(ctx, accountName, input) + if err != nil { + return fmt.Errorf("error setting properties: %s", err) + } + + time.Sleep(2 * time.Second) + + _, err = accountsClient.GetServiceProperties(ctx, accountName) + if err != nil { + return fmt.Errorf("error getting properties: %s", err) + } + + return nil +} + +``` \ No newline at end of file diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts/client.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts/client.go new file mode 100644 index 0000000000000..df5fa1d722ea2 --- /dev/null +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts/client.go @@ -0,0 +1,22 @@ +package accounts + +import ( + "fmt" + + "github.com/hashicorp/go-azure-sdk/sdk/client/dataplane/storage" +) + +// Client is the base client for Blob Storage Blobs. +type Client struct { + Client *storage.Client +} + +func NewWithBaseUri(baseUri string) (*Client, error) { + baseClient, err := storage.NewStorageClient(baseUri, componentName, apiVersion) + if err != nil { + return nil, fmt.Errorf("building base client: %+v", err) + } + return &Client{ + Client: baseClient, + }, nil +} diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts/get_service_properties.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts/get_service_properties.go new file mode 100644 index 0000000000000..fce040b887a2a --- /dev/null +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts/get_service_properties.go @@ -0,0 +1,54 @@ +package accounts + +import ( + "context" + "fmt" + "net/http" + + "github.com/hashicorp/go-azure-sdk/sdk/client" +) + +type GetServicePropertiesResult struct { + StorageServiceProperties + HttpResponse *http.Response +} + +func (c Client) GetServiceProperties(ctx context.Context, accountName string) (result GetServicePropertiesResult, err error) { + if accountName == "" { + return result, fmt.Errorf("`accountName` cannot be an empty string") + } + + opts := client.RequestOptions{ + ContentType: "text/xml", + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodGet, + OptionsObject: servicePropertiesOptions{}, + Path: "/", + } + + req, err := c.Client.NewRequest(ctx, opts) + if err != nil { + err = fmt.Errorf("building request: %+v", err) + return + } + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + err = resp.Unmarshal(&result) + if err != nil { + err = fmt.Errorf("unmarshalling response: %+v", err) + return + } + } + if err != nil { + err = fmt.Errorf("executing request: %+v", err) + return + } + + return +} diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts/models.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts/models.go new file mode 100644 index 0000000000000..c36d45ecb8c54 --- /dev/null +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts/models.go @@ -0,0 +1,74 @@ +package accounts + +type StorageServiceProperties struct { + // Cors - Specifies CORS rules for the Blob service. You can include up to five CorsRule elements in the request. If no CorsRule elements are included in the request body, all CORS rules will be deleted, and CORS will be disabled for the Blob service. + Cors *CorsRules `xml:"Cors,omitempty"` + // DefaultServiceVersion - DefaultServiceVersion indicates the default version to use for requests to the Blob service if an incoming request’s version is not specified. Possible values include version 2008-10-27 and all more recent versions. + DefaultServiceVersion *string `xml:"DefaultServiceVersion,omitempty"` + // DeleteRetentionPolicy - The blob service properties for soft delete. + DeleteRetentionPolicy *DeleteRetentionPolicy `xml:"DeleteRetentionPolicy,omitempty"` + // Logging - The blob service properties for logging access + Logging *Logging `xml:"Logging,omitempty"` + // HourMetrics - The blob service properties for hour metrics + HourMetrics *MetricsConfig `xml:"HourMetrics,omitempty"` + // HourMetrics - The blob service properties for minute metrics + MinuteMetrics *MetricsConfig `xml:"MinuteMetrics,omitempty"` + // StaticWebsite - Optional + StaticWebsite *StaticWebsite `xml:"StaticWebsite,omitempty"` +} + +// StaticWebsite sets the static website support properties on the Blob service. +type StaticWebsite struct { + // Enabled - Required. Indicates whether static website support is enabled for the given account. + Enabled bool `xml:"Enabled"` + // IndexDocument - Optional. The webpage that Azure Storage serves for requests to the root of a website or any subfolder. For example, index.html. The value is case-sensitive. + IndexDocument string `xml:"IndexDocument,omitempty"` + // ErrorDocument404Path - Optional. The absolute path to a webpage that Azure Storage serves for requests that do not correspond to an existing file. For example, error/404.html. Only a single custom 404 page is supported in each static website. The value is case-sensitive. + ErrorDocument404Path string `xml:"ErrorDocument404Path,omitempty"` +} + +// CorsRules sets the CORS rules. You can include up to five CorsRule elements in the request. +type CorsRules struct { + // CorsRules - The List of CORS rules. You can include up to five CorsRule elements in the request. + CorsRules []CorsRule `xml:"CorsRules,omitempty"` +} + +// DeleteRetentionPolicy the blob service properties for soft delete. +type DeleteRetentionPolicy struct { + // Enabled - Indicates whether DeleteRetentionPolicy is enabled for the Blob service. + Enabled bool `xml:"Enabled,omitempty"` + // Days - Indicates the number of days that the deleted blob should be retained. The minimum specified value can be 1 and the maximum value can be 365. + Days int32 `xml:"Days,omitempty"` +} + +// CorsRule specifies a CORS rule for the Blob service. +type CorsRule struct { + // AllowedOrigins - Required if CorsRule element is present. A list of origin domains that will be allowed via CORS, or "" to allow all domains + AllowedOrigins []string `xml:"AllowedOrigins,omitempty"` + // AllowedMethods - Required if CorsRule element is present. A list of HTTP methods that are allowed to be executed by the origin. + AllowedMethods []string `xml:"AllowedMethods,omitempty"` + // MaxAgeInSeconds - Required if CorsRule element is present. The number of seconds that the client/browser should cache a preflight response. + MaxAgeInSeconds int32 `xml:"MaxAgeInSeconds,omitempty"` + // ExposedHeaders - Required if CorsRule element is present. A list of response headers to expose to CORS clients. + ExposedHeaders []string `xml:"ExposedHeaders,omitempty"` + // AllowedHeaders - Required if CorsRule element is present. A list of headers allowed to be part of the cross-origin request. + AllowedHeaders []string `xml:"AllowedHeaders,omitempty"` +} + +// Logging specifies the access logging options for the Blob service. +type Logging struct { + Version string `xml:"Version"` + Delete bool `xml:"Delete"` + Read bool `xml:"Read"` + Write bool `xml:"Write"` + RetentionPolicy DeleteRetentionPolicy `xml:"RetentionPolicy"` +} + +// MetricsConfig specifies the hour and/or minute metrics options for the Blob service. +// Elements are all expected +type MetricsConfig struct { + Version string `xml:"Version"` + Enabled bool `xml:"Enabled"` + RetentionPolicy DeleteRetentionPolicy `xml:"RetentionPolicy"` + IncludeAPIs bool `xml:"IncludeAPIs"` +} diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts/resource_id.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts/resource_id.go new file mode 100644 index 0000000000000..e6c6303f9f79b --- /dev/null +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts/resource_id.go @@ -0,0 +1,155 @@ +package accounts + +import ( + "fmt" + "net/url" + "strings" + + "github.com/hashicorp/go-azure-helpers/lang/pointer" + "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" +) + +type SubDomainType string + +const ( + BlobSubDomainType SubDomainType = "blob" + DataLakeStoreSubDomainType SubDomainType = "dfs" + FileSubDomainType SubDomainType = "file" + QueueSubDomainType SubDomainType = "queue" + TableSubDomainType SubDomainType = "table" +) + +func PossibleValuesForSubDomainType() []SubDomainType { + return []SubDomainType{ + BlobSubDomainType, + DataLakeStoreSubDomainType, + FileSubDomainType, + QueueSubDomainType, + TableSubDomainType, + } +} + +// TODO: update this to implement `resourceids.ResourceId` once +// https://github.com/hashicorp/go-azure-helpers/issues/187 is fixed +var _ resourceids.Id = AccountId{} + +type AccountId struct { + AccountName string + ZoneName *string + SubDomainType SubDomainType + DomainSuffix string + IsEdgeZone bool +} + +func (a AccountId) ID() string { + components := []string{ + a.AccountName, + } + if a.IsEdgeZone { + // Storage Accounts hosted in an Edge Zone + // `{accountname}.{component}.{edgezone}.edgestorage.azure.net` + components = append(components, string(a.SubDomainType)) + if a.ZoneName != nil { + components = append(components, *a.ZoneName) + } + } else { + // Storage Accounts using a DNS Zone + // `{accountname}.{dnszone}.{component}.storage.azure.net` + // or a Regular Storage Account + // `{accountname}.{component}.core.windows.net` + if a.ZoneName != nil { + components = append(components, *a.ZoneName) + } + components = append(components, string(a.SubDomainType)) + } + components = append(components, a.DomainSuffix) + return fmt.Sprintf("https://%s", strings.Join(components, ".")) +} + +func (a AccountId) String() string { + components := []string{ + fmt.Sprintf("IsEdgeZone %t", a.IsEdgeZone), + fmt.Sprintf("ZoneName %q", pointer.From(a.ZoneName)), + fmt.Sprintf("Subdomain Type %q", string(a.SubDomainType)), + fmt.Sprintf("DomainSuffix %q", a.DomainSuffix), + } + return fmt.Sprintf("Account %q (%s)", a.AccountName, strings.Join(components, " / ")) +} + +func ParseAccountID(input, domainSuffix string) (*AccountId, error) { + uri, err := url.Parse(input) + if err != nil { + return nil, fmt.Errorf("parsing %q as a URL: %s", input, err) + } + + if !strings.HasSuffix(uri.Host, domainSuffix) { + return nil, fmt.Errorf("expected the account %q to use a domain suffix of %q", uri.Host, domainSuffix) + } + + // There's 3 different types of Storage Account ID: + // 1. Regular ol' Storage Accounts + // `{name}.{component}.core.windows.net` (e.g. `example1.blob.core.windows.net`) + // 2. Storage Accounts using a DNS Zone + // `{accountname}.{dnszone}.{component}.storage.azure.net` + // 3. Storage Accounts hosted in an Edge Zone + // `{accountname}.{component}.{edgezone}.edgestorage.azure.net` + // since both `dnszone` and `edgezone` are the only two identifiers, we need to check if `domainSuffix` includes `edge` + // to know how to treat these + + hostName := strings.TrimSuffix(uri.Host, fmt.Sprintf(".%s", domainSuffix)) + components := strings.Split(hostName, ".") + accountId := AccountId{ + DomainSuffix: domainSuffix, + IsEdgeZone: strings.Contains(strings.ToLower(domainSuffix), "edge"), + } + + if len(components) == 2 { + // this will be a regular Storage Account (e.g. `example1.blob.core.windows.net`) + accountId.AccountName = components[0] + subDomainType, err := parseSubDomainType(components[1]) + if err != nil { + return nil, err + } + accountId.SubDomainType = *subDomainType + return &accountId, nil + } + + if len(components) == 3 { + // This can either be a Zone'd Storage Account or a Storage Account within an Edge Zone + accountName := "" + subDomainTypeRaw := "" + zone := "" + if accountId.IsEdgeZone { + // `{accountname}.{component}.{edgezone}.edgestorage.azure.net` + accountName = components[0] + subDomainTypeRaw = components[1] + zone = components[2] + } else { + // `{accountname}.{dnszone}.{component}.storage.azure.net` + accountName = components[0] + zone = components[1] + subDomainTypeRaw = components[2] + } + + accountId.AccountName = accountName + subDomainType, err := parseSubDomainType(subDomainTypeRaw) + if err != nil { + return nil, err + } + accountId.SubDomainType = *subDomainType + accountId.ZoneName = pointer.To(zone) + return &accountId, nil + } + + return nil, fmt.Errorf("unknown storage account domain type %q", input) +} + +func parseSubDomainType(input string) (*SubDomainType, error) { + for _, k := range PossibleValuesForSubDomainType() { + if strings.EqualFold(input, string(k)) { + return pointer.To(k), nil + } + } + + return nil, fmt.Errorf("expected the subdomain type to be one of [%+v] but got %q", PossibleValuesForSubDomainType(), input) +} diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts/service_properties_shared.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts/service_properties_shared.go new file mode 100644 index 0000000000000..3019155f9183c --- /dev/null +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts/service_properties_shared.go @@ -0,0 +1,26 @@ +package accounts + +import ( + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" +) + +var _ client.Options = servicePropertiesOptions{} + +type servicePropertiesOptions struct { +} + +func (servicePropertiesOptions) ToHeaders() *client.Headers { + return nil +} + +func (servicePropertiesOptions) ToOData() *odata.Query { + return nil +} + +func (servicePropertiesOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("comp", "properties") + out.Append("restype", "service") + return out +} diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts/set_service_properties.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts/set_service_properties.go new file mode 100644 index 0000000000000..5252dc021eda2 --- /dev/null +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts/set_service_properties.go @@ -0,0 +1,52 @@ +package accounts + +import ( + "context" + "fmt" + "net/http" + + "github.com/hashicorp/go-azure-sdk/sdk/client" +) + +type SetServicePropertiesResult struct { + HttpResponse *http.Response +} + +func (c Client) SetServiceProperties(ctx context.Context, accountName string, input StorageServiceProperties) (result SetServicePropertiesResult, err error) { + if accountName == "" { + return result, fmt.Errorf("`accountName` cannot be an empty string") + } + + opts := client.RequestOptions{ + ContentType: "text/xml", + ExpectedStatusCodes: []int{ + http.StatusAccepted, + }, + HttpMethod: http.MethodPut, + OptionsObject: servicePropertiesOptions{}, + Path: "/", + } + + req, err := c.Client.NewRequest(ctx, opts) + if err != nil { + err = fmt.Errorf("building request: %+v", err) + return + } + + if err = req.Marshal(&input); err != nil { + err = fmt.Errorf("marshaling request: %+v", err) + return + } + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } + if err != nil { + err = fmt.Errorf("executing request: %+v", err) + return + } + + return +} diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts/version.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts/version.go new file mode 100644 index 0000000000000..427d66da7364d --- /dev/null +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts/version.go @@ -0,0 +1,4 @@ +package accounts + +const apiVersion = "2023-11-03" +const componentName = "blob/accounts" diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/README.md b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/README.md similarity index 87% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/README.md rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/README.md index aa5ebd16da14e..0b26e1cd140f3 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/README.md +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/README.md @@ -1,4 +1,4 @@ -## Blob Storage Blobs SDK for API version 2020-08-04 +## Blob Storage Blobs SDK for API version 2023-11-03 This package allows you to interact with the Blobs Blob Storage API @@ -18,7 +18,7 @@ import ( "time" "github.com/hashicorp/go-azure-sdk/sdk/auth" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs" ) func Example() error { @@ -30,7 +30,7 @@ func Example() error { blobClient, err := blobs.NewWithBaseUri(fmt.Sprintf("https://%s.blob.%s", accountName, domainSuffix)) if err != nil { - return fmt.Errorf("building client for environment: %+v", err) + return fmt.Errorf("building client for environment: %v", err) } auth, err := auth.NewSharedKeyAuthorizer(accountName, storageAccountKey, auth.SharedKey) diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/api.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/api.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/api.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/api.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/append_block.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/append_block.go similarity index 74% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/append_block.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/append_block.go index a1068d459c5c9..b82558f937d39 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/append_block.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/append_block.go @@ -1,10 +1,8 @@ package blobs import ( - "bytes" "context" "fmt" - "io" "net/http" "strconv" "strings" @@ -14,7 +12,6 @@ import ( ) type AppendBlockInput struct { - // A number indicating the byte offset to compare. // Append Block will succeed only if the append position is equal to this number. // If it is not, the request will fail with an AppendPositionConditionNotMet @@ -43,10 +40,13 @@ type AppendBlockInput struct { // Required if the blob has an active lease. // To perform this operation on a blob with an active lease, specify the valid lease ID for this header. LeaseID *string + + // The encryption scope to set for the request content. + EncryptionScope *string } type AppendBlockResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response BlobAppendOffset string BlobCommittedBlockCount int64 @@ -56,22 +56,25 @@ type AppendBlockResponse struct { } // AppendBlock commits a new block of data to the end of an existing append blob. -func (c Client) AppendBlock(ctx context.Context, containerName, blobName string, input AppendBlockInput) (resp AppendBlockResponse, err error) { - +func (c Client) AppendBlock(ctx context.Context, containerName, blobName string, input AppendBlockInput) (result AppendBlockResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + err = fmt.Errorf("`containerName` must be a lower-cased string") + return } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + err = fmt.Errorf("`blobName` cannot be an empty string") + return } if input.Content != nil && len(*input.Content) > (4*1024*1024) { - return resp, fmt.Errorf("`input.Content` must be at most 4MB") + err = fmt.Errorf("`input.Content` must be at most 4MB") + return } opts := client.RequestOptions{ @@ -91,36 +94,37 @@ func (c Client) AppendBlock(ctx context.Context, containerName, blobName string, return } - if input.Content != nil { - req.Body = io.NopCloser(bytes.NewReader(*input.Content)) - } - - req.ContentLength = int64(len(*input.Content)) - - resp.HttpResponse, err = req.Execute(ctx) + err = req.Marshal(input.Content) if err != nil { - err = fmt.Errorf("executing request: %+v", err) + err = fmt.Errorf("marshalling request: %+v", err) return } - if resp.HttpResponse != nil { - if resp.HttpResponse.Header != nil { - resp.BlobAppendOffset = resp.HttpResponse.Header.Get("x-ms-blob-append-offset") - resp.ContentMD5 = resp.HttpResponse.Header.Get("Content-MD5") - resp.ETag = resp.HttpResponse.Header.Get("ETag") - resp.LastModified = resp.HttpResponse.Header.Get("Last-Modified") + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + if resp.Header != nil { + result.BlobAppendOffset = resp.Header.Get("x-ms-blob-append-offset") + result.ContentMD5 = resp.Header.Get("Content-MD5") + result.ETag = resp.Header.Get("ETag") + result.LastModified = resp.Header.Get("Last-Modified") - if v := resp.HttpResponse.Header.Get("x-ms-blob-committed-block-count"); v != "" { + if v := resp.Header.Get("x-ms-blob-committed-block-count"); v != "" { i, innerErr := strconv.Atoi(v) if innerErr != nil { - err = fmt.Errorf("error parsing %q as an integer: %s", v, innerErr) + err = fmt.Errorf("parsing `x-ms-blob-committed-block-count` header value %q: %+v", v, innerErr) return } - resp.BlobCommittedBlockCount = int64(i) + result.BlobCommittedBlockCount = int64(i) } - } } + if err != nil { + err = fmt.Errorf("executing request: %+v", err) + return + } return } @@ -143,6 +147,9 @@ func (a appendBlockOptions) ToHeaders() *client.Headers { if a.input.LeaseID != nil { headers.Append("x-ms-lease-id", *a.input.LeaseID) } + if a.input.EncryptionScope != nil { + headers.Append("x-ms-encryption-scope", *a.input.EncryptionScope) + } if a.input.Content != nil { headers.Append("Content-Length", strconv.Itoa(len(*a.input.Content))) } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/client.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/client.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/client.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/client.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/copy.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/copy.go similarity index 90% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/copy.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/copy.go index 2ff309cc75da1..68bf1d816a99d 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/copy.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/copy.go @@ -103,32 +103,34 @@ type CopyInput struct { // If the source blob has been modified, the Blob service returns status code 412 (Precondition Failed). // This header cannot be specified if the source is an Azure File. SourceIfUnmodifiedSince *string + + // The encryption scope to set for the request content. + EncryptionScope *string } type CopyResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response CopyID string CopyStatus string } // Copy copies a blob to a destination within the storage account asynchronously. -func (c Client) Copy(ctx context.Context, containerName, blobName string, input CopyInput) (resp CopyResponse, err error) { - +func (c Client) Copy(ctx context.Context, containerName, blobName string, input CopyInput) (result CopyResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + return result, fmt.Errorf("`containerName` cannot be an empty string") } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + return result, fmt.Errorf("`containerName` must be a lower-cased string") } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + return result, fmt.Errorf("`blobName` cannot be an empty string") } if input.CopySource == "" { - return resp, fmt.Errorf("`input.CopySource` cannot be an empty string") + return result, fmt.Errorf("`input.CopySource` cannot be an empty string") } opts := client.RequestOptions{ @@ -148,19 +150,21 @@ func (c Client) Copy(ctx context.Context, containerName, blobName string, input return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + if resp.Header != nil { + result.CopyID = resp.Header.Get("x-ms-copy-id") + result.CopyStatus = resp.Header.Get("x-ms-copy-status") + } + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return } - if resp.HttpResponse != nil { - if resp.HttpResponse.Header != nil { - resp.CopyID = resp.HttpResponse.Header.Get("x-ms-copy-id") - resp.CopyStatus = resp.HttpResponse.Header.Get("x-ms-copy-status") - } - } - return } @@ -216,6 +220,10 @@ func (c copyOptions) ToHeaders() *client.Headers { headers.Append("x-ms-source-if-unmodified-since", *c.input.SourceIfUnmodifiedSince) } + if c.input.EncryptionScope != nil { + headers.Append("x-ms-encryption-scope", *c.input.EncryptionScope) + } + headers.Merge(metadata.SetMetaDataHeaders(c.input.MetaData)) return headers diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/copy_abort.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/copy_abort.go similarity index 77% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/copy_abort.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/copy_abort.go index 064c56f09ab87..5d9469a5097c9 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/copy_abort.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/copy_abort.go @@ -20,26 +20,29 @@ type AbortCopyInput struct { } type CopyAbortResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // AbortCopy aborts a pending Copy Blob operation, and leaves a destination blob with zero length and full metadata. -func (c Client) AbortCopy(ctx context.Context, containerName, blobName string, input AbortCopyInput) (resp CopyAbortResponse, err error) { - +func (c Client) AbortCopy(ctx context.Context, containerName, blobName string, input AbortCopyInput) (result CopyAbortResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + err = fmt.Errorf("`containerName` must be a lower-cased string") + return } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + err = fmt.Errorf("`blobName` cannot be an empty string") + return } if input.CopyID == "" { - return resp, fmt.Errorf("`input.CopyID` cannot be an empty string") + err = fmt.Errorf("`input.CopyID` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -59,7 +62,11 @@ func (c Client) AbortCopy(ctx context.Context, containerName, blobName string, i return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/copy_and_wait.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/copy_and_wait.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/copy_and_wait.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/copy_and_wait.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/copy_and_wait_poller.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/copy_and_wait_poller.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/copy_and_wait_poller.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/copy_and_wait_poller.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/delete.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/delete.go similarity index 79% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/delete.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/delete.go index e13aaa599fe6d..80c1e43323893 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/delete.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/delete.go @@ -21,22 +21,21 @@ type DeleteInput struct { } type DeleteResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // Delete marks the specified blob or snapshot for deletion. The blob is later deleted during garbage collection. -func (c Client) Delete(ctx context.Context, containerName, blobName string, input DeleteInput) (resp DeleteResponse, err error) { - +func (c Client) Delete(ctx context.Context, containerName, blobName string, input DeleteInput) (result DeleteResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + return result, fmt.Errorf("`containerName` cannot be an empty string") } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + return result, fmt.Errorf("`containerName` must be a lower-cased string") } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + return result, fmt.Errorf("`blobName` cannot be an empty string") } opts := client.RequestOptions{ @@ -56,7 +55,11 @@ func (c Client) Delete(ctx context.Context, containerName, blobName string, inpu return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/delete_snapshot.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/delete_snapshot.go similarity index 76% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/delete_snapshot.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/delete_snapshot.go index 0407eb1f78299..e5cfa3c8f0b6d 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/delete_snapshot.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/delete_snapshot.go @@ -20,26 +20,29 @@ type DeleteSnapshotInput struct { } type DeleteSnapshotResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // DeleteSnapshot marks a single Snapshot of a Blob for Deletion based on it's DateTime, which will be deleted during the next Garbage Collection cycle. -func (c Client) DeleteSnapshot(ctx context.Context, containerName, blobName string, input DeleteSnapshotInput) (resp DeleteSnapshotResponse, err error) { - +func (c Client) DeleteSnapshot(ctx context.Context, containerName, blobName string, input DeleteSnapshotInput) (result DeleteSnapshotResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + err = fmt.Errorf("`containerName` must be a lower-cased string") + return } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + err = fmt.Errorf("`blobName` cannot be an empty string") + return } if input.SnapshotDateTime == "" { - return resp, fmt.Errorf("`input.SnapshotDateTime` cannot be an empty string") + err = fmt.Errorf("`input.SnapshotDateTime` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -59,7 +62,11 @@ func (c Client) DeleteSnapshot(ctx context.Context, containerName, blobName stri return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/delete_snapshots.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/delete_snapshots.go similarity index 77% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/delete_snapshots.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/delete_snapshots.go index 34b3beb623a8e..dd0ce7be20fc0 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/delete_snapshots.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/delete_snapshots.go @@ -17,22 +17,24 @@ type DeleteSnapshotsInput struct { } type DeleteSnapshotsResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // DeleteSnapshots marks all Snapshots of a Blob for Deletion, which will be deleted during the next Garbage Collection Cycle. -func (c Client) DeleteSnapshots(ctx context.Context, containerName, blobName string, input DeleteSnapshotsInput) (resp DeleteSnapshotsResponse, err error) { - +func (c Client) DeleteSnapshots(ctx context.Context, containerName, blobName string, input DeleteSnapshotsInput) (result DeleteSnapshotsResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + err = fmt.Errorf("`containerName` must be a lower-cased string") + return } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + err = fmt.Errorf("`blobName` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -52,7 +54,11 @@ func (c Client) DeleteSnapshots(ctx context.Context, containerName, blobName str return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/get.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/get.go similarity index 67% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/get.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/get.go index 0f5572a8b9c25..5829324459f5f 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/get.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/get.go @@ -17,32 +17,31 @@ type GetInput struct { } type GetResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response - Contents []byte + Contents *[]byte } // Get reads or downloads a blob from the system, including its metadata and properties. -func (c Client) Get(ctx context.Context, containerName, blobName string, input GetInput) (resp GetResponse, err error) { - +func (c Client) Get(ctx context.Context, containerName, blobName string, input GetInput) (result GetResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + return result, fmt.Errorf("`containerName` cannot be an empty string") } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + return result, fmt.Errorf("`containerName` must be a lower-cased string") } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + return result, fmt.Errorf("`blobName` cannot be an empty string") } if input.LeaseID != nil && *input.LeaseID == "" { - return resp, fmt.Errorf("`input.LeaseID` should either be specified or nil, not an empty string") + return result, fmt.Errorf("`input.LeaseID` should either be specified or nil, not an empty string") } if (input.StartByte != nil && input.EndByte == nil) || input.StartByte == nil && input.EndByte != nil { - return resp, fmt.Errorf("`input.StartByte` and `input.EndByte` must both be specified, or both be nil") + return result, fmt.Errorf("`input.StartByte` and `input.EndByte` must both be specified, or both be nil") } opts := client.RequestOptions{ @@ -63,18 +62,22 @@ func (c Client) Get(ctx context.Context, containerName, blobName string, input G return } - resp.HttpResponse, err = req.Execute(ctx) - if err != nil { - err = fmt.Errorf("executing request: %+v", err) - return - } + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.Contents = &[]byte{} + result.HttpResponse = resp.Response - if resp.HttpResponse != nil { - err = resp.HttpResponse.Unmarshal(&resp.Contents) + err = resp.Unmarshal(result.Contents) if err != nil { - return resp, fmt.Errorf("unmarshalling response: %v", err) + err = fmt.Errorf("unmarshalling response: %+v", err) + return } } + if err != nil { + err = fmt.Errorf("executing request: %+v", err) + return + } return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/get_block_list.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/get_block_list.go similarity index 70% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/get_block_list.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/get_block_list.go index 9a783cb6ebac0..b7c4037d88f01 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/get_block_list.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/get_block_list.go @@ -17,7 +17,7 @@ type GetBlockListInput struct { } type GetBlockListResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response // The size of the blob in bytes BlobContentLength *int64 @@ -36,18 +36,17 @@ type GetBlockListResponse struct { } // GetBlockList retrieves the list of blocks that have been uploaded as part of a block blob. -func (c Client) GetBlockList(ctx context.Context, containerName, blobName string, input GetBlockListInput) (resp GetBlockListResponse, err error) { - +func (c Client) GetBlockList(ctx context.Context, containerName, blobName string, input GetBlockListInput) (result GetBlockListResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + return result, fmt.Errorf("`containerName` cannot be an empty string") } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + return result, fmt.Errorf("`containerName` must be a lower-cased string") } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + return result, fmt.Errorf("`blobName` cannot be an empty string") } opts := client.RequestOptions{ @@ -67,33 +66,37 @@ func (c Client) GetBlockList(ctx context.Context, containerName, blobName string return } - resp.HttpResponse, err = req.Execute(ctx) - if err != nil { - err = fmt.Errorf("executing request: %+v", err) - return - } + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response - if resp.HttpResponse != nil { - if resp.HttpResponse.Header != nil { - resp.ContentType = resp.HttpResponse.Header.Get("Content-Type") - resp.ETag = resp.HttpResponse.Header.Get("ETag") + if resp.Header != nil { + result.ContentType = resp.Header.Get("Content-Type") + result.ETag = resp.Header.Get("ETag") - if v := resp.HttpResponse.Header.Get("x-ms-blob-content-length"); v != "" { + if v := resp.Header.Get("x-ms-blob-content-length"); v != "" { i, innerErr := strconv.Atoi(v) if innerErr != nil { - err = fmt.Errorf("error parsing %q as an integer: %s", v, innerErr) + err = fmt.Errorf("parsing `x-ms-blob-content-length` header value %q: %s", v, innerErr) return } i64 := int64(i) - resp.BlobContentLength = &i64 + result.BlobContentLength = &i64 } } - err = resp.HttpResponse.Unmarshal(&resp) + + err = resp.Unmarshal(&result) if err != nil { - return resp, fmt.Errorf("unmarshalling response: %v", err) + err = fmt.Errorf("unmarshalling response: %+v", err) + return } } + if err != nil { + err = fmt.Errorf("executing request: %+v", err) + return + } return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/get_page_ranges.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/get_page_ranges.go similarity index 66% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/get_page_ranges.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/get_page_ranges.go index 6d0f54163eaad..fe83294cc0b38 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/get_page_ranges.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/get_page_ranges.go @@ -19,7 +19,7 @@ type GetPageRangesInput struct { } type GetPageRangesResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response // The size of the blob in bytes ContentLength *int64 @@ -42,22 +42,21 @@ type PageRange struct { } // GetPageRanges returns the list of valid page ranges for a page blob or snapshot of a page blob. -func (c Client) GetPageRanges(ctx context.Context, containerName, blobName string, input GetPageRangesInput) (resp GetPageRangesResponse, err error) { - +func (c Client) GetPageRanges(ctx context.Context, containerName, blobName string, input GetPageRangesInput) (result GetPageRangesResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + return result, fmt.Errorf("`containerName` cannot be an empty string") } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + return result, fmt.Errorf("`containerName` must be a lower-cased string") } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + return result, fmt.Errorf("`blobName` cannot be an empty string") } - if (input.StartByte != nil && input.EndByte == nil) || input.StartByte == nil && input.EndByte != nil { - return resp, fmt.Errorf("`input.StartByte` and `input.EndByte` must both be specified, or both be nil") + if (input.StartByte != nil && input.EndByte == nil) || (input.StartByte == nil && input.EndByte != nil) { + return result, fmt.Errorf("`input.StartByte` and `input.EndByte` must both be specified, or both be nil") } opts := client.RequestOptions{ @@ -77,34 +76,37 @@ func (c Client) GetPageRanges(ctx context.Context, containerName, blobName strin return } - resp.HttpResponse, err = req.Execute(ctx) - if err != nil { - err = fmt.Errorf("executing request: %+v", err) - return - } + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response - if resp.HttpResponse != nil { - if resp.HttpResponse.Header != nil { - resp.ContentType = resp.HttpResponse.Header.Get("Content-Type") - resp.ETag = resp.HttpResponse.Header.Get("ETag") + if resp.Header != nil { + result.ContentType = resp.Header.Get("Content-Type") + result.ETag = resp.Header.Get("ETag") - if v := resp.HttpResponse.Header.Get("x-ms-blob-content-length"); v != "" { + if v := resp.Header.Get("x-ms-blob-content-length"); v != "" { i, innerErr := strconv.Atoi(v) if innerErr != nil { - err = fmt.Errorf("Error parsing %q as an integer: %s", v, innerErr) + err = fmt.Errorf("parsing `x-ms-blob-content-length` header value %q: %+v", v, innerErr) return } i64 := int64(i) - resp.ContentLength = &i64 + result.ContentLength = &i64 } } - err = resp.HttpResponse.Unmarshal(&resp) + err = resp.Unmarshal(&result) if err != nil { - return resp, fmt.Errorf("unmarshalling response: %s", err) + err = fmt.Errorf("unmarshalling response: %+v", err) + return } } + if err != nil { + err = fmt.Errorf("executing request: %+v", err) + return + } return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/incremental_copy_blob.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/incremental_copy_blob.go similarity index 80% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/incremental_copy_blob.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/incremental_copy_blob.go index d059f11e2bc79..0423c0f99e22c 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/incremental_copy_blob.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/incremental_copy_blob.go @@ -19,29 +19,32 @@ type IncrementalCopyBlobInput struct { } type IncrementalCopyBlob struct { - HttpResponse *client.Response + HttpResponse *http.Response } // IncrementalCopyBlob copies a snapshot of the source page blob to a destination page blob. // The snapshot is copied such that only the differential changes between the previously copied // snapshot are transferred to the destination. // The copied snapshots are complete copies of the original snapshot and can be read or copied from as usual. -func (c Client) IncrementalCopyBlob(ctx context.Context, containerName, blobName string, input IncrementalCopyBlobInput) (resp IncrementalCopyBlob, err error) { - +func (c Client) IncrementalCopyBlob(ctx context.Context, containerName, blobName string, input IncrementalCopyBlobInput) (result IncrementalCopyBlob, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + err = fmt.Errorf("`containerName` must be a lower-cased string") + return } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + err = fmt.Errorf("`blobName` cannot be an empty string") + return } if input.CopySource == "" { - return resp, fmt.Errorf("`input.CopySource` cannot be an empty string") + err = fmt.Errorf("`input.CopySource` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -61,7 +64,11 @@ func (c Client) IncrementalCopyBlob(ctx context.Context, containerName, blobName return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/lease_acquire.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/lease_acquire.go similarity index 74% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/lease_acquire.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/lease_acquire.go index 214808ca07138..d4477564eaccd 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/lease_acquire.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/lease_acquire.go @@ -24,36 +24,41 @@ type AcquireLeaseInput struct { } type AcquireLeaseResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response LeaseID string } // AcquireLease establishes and manages a lock on a blob for write and delete operations. -func (c Client) AcquireLease(ctx context.Context, containerName, blobName string, input AcquireLeaseInput) (resp AcquireLeaseResponse, err error) { - +func (c Client) AcquireLease(ctx context.Context, containerName, blobName string, input AcquireLeaseInput) (result AcquireLeaseResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + err = fmt.Errorf("`containerName` must be a lower-cased string") + return } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + err = fmt.Errorf("`blobName` cannot be an empty string") + return } if input.LeaseID != nil && *input.LeaseID == "" { - return resp, fmt.Errorf("`input.LeaseID` cannot be an empty string, if specified") + err = fmt.Errorf("`input.LeaseID` cannot be an empty string, if specified") + return } if input.ProposedLeaseID != nil && *input.ProposedLeaseID == "" { - return resp, fmt.Errorf("`input.ProposedLeaseID` cannot be an empty string, if specified") + err = fmt.Errorf("`input.ProposedLeaseID` cannot be an empty string, if specified") + return } // An infinite lease duration is -1 seconds. A non-infinite lease can be between 15 and 60 seconds if input.LeaseDuration != -1 && (input.LeaseDuration <= 15 || input.LeaseDuration >= 60) { - return resp, fmt.Errorf("`input.LeaseDuration` must be -1 (infinite), or between 15 and 60 seconds") + err = fmt.Errorf("`input.LeaseDuration` must be -1 (infinite), or between 15 and 60 seconds") + return } opts := client.RequestOptions{ @@ -73,18 +78,20 @@ func (c Client) AcquireLease(ctx context.Context, containerName, blobName string return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + if resp.Header != nil { + result.LeaseID = resp.Header.Get("x-ms-lease-id") + } + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return } - if resp.HttpResponse != nil { - if resp.HttpResponse.Header != nil { - resp.LeaseID = resp.HttpResponse.Header.Get("x-ms-lease-id") - } - } - return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/lease_break.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/lease_break.go similarity index 81% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/lease_break.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/lease_break.go index 858c3061793f1..74e689106694b 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/lease_break.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/lease_break.go @@ -26,7 +26,7 @@ type BreakLeaseInput struct { } type BreakLeaseResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response // Approximate time remaining in the lease period, in seconds. // If the break is immediate, 0 is returned. @@ -34,22 +34,25 @@ type BreakLeaseResponse struct { } // BreakLease breaks an existing lock on a blob using the LeaseID. -func (c Client) BreakLease(ctx context.Context, containerName, blobName string, input BreakLeaseInput) (resp BreakLeaseResponse, err error) { - +func (c Client) BreakLease(ctx context.Context, containerName, blobName string, input BreakLeaseInput) (result BreakLeaseResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + err = fmt.Errorf("`containerName` must be a lower-cased string") + return } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + err = fmt.Errorf("`blobName` cannot be an empty string") + return } if input.LeaseID == "" { - return resp, fmt.Errorf("`input.LeaseID` cannot be an empty string") + err = fmt.Errorf("`input.LeaseID` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -69,7 +72,11 @@ func (c Client) BreakLease(ctx context.Context, containerName, blobName string, return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/lease_change.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/lease_change.go similarity index 70% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/lease_change.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/lease_change.go index c69d05483b89e..f983d1dd9c6c9 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/lease_change.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/lease_change.go @@ -16,32 +16,36 @@ type ChangeLeaseInput struct { } type ChangeLeaseResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response LeaseID string } // ChangeLease changes an existing lock on a blob for another lock. -func (c Client) ChangeLease(ctx context.Context, containerName, blobName string, input ChangeLeaseInput) (resp ChangeLeaseResponse, err error) { - +func (c Client) ChangeLease(ctx context.Context, containerName, blobName string, input ChangeLeaseInput) (result ChangeLeaseResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + err = fmt.Errorf("`containerName` must be a lower-cased string") + return } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + err = fmt.Errorf("`blobName` cannot be an empty string") + return } if input.ExistingLeaseID == "" { - return resp, fmt.Errorf("`input.ExistingLeaseID` cannot be an empty string") + err = fmt.Errorf("`input.ExistingLeaseID` cannot be an empty string") + return } if input.ProposedLeaseID == "" { - return resp, fmt.Errorf("`input.ProposedLeaseID` cannot be an empty string") + err = fmt.Errorf("`input.ProposedLeaseID` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -61,18 +65,20 @@ func (c Client) ChangeLease(ctx context.Context, containerName, blobName string, return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + if resp.Header != nil { + result.LeaseID = resp.Header.Get("x-ms-lease-id") + } + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return } - if resp.HttpResponse != nil { - if resp.HttpResponse.Header != nil { - resp.LeaseID = resp.HttpResponse.Header.Get("x-ms-lease-id") - } - } - return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/lease_release.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/lease_release.go similarity index 73% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/lease_release.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/lease_release.go index 350493da229bd..2101828b24e10 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/lease_release.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/lease_release.go @@ -11,7 +11,7 @@ import ( ) type ReleaseLeaseResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } type ReleaseLeaseInput struct { @@ -19,22 +19,25 @@ type ReleaseLeaseInput struct { } // ReleaseLease releases a lock based on the Lease ID. -func (c Client) ReleaseLease(ctx context.Context, containerName, blobName string, input ReleaseLeaseInput) (resp ReleaseLeaseResponse, err error) { - +func (c Client) ReleaseLease(ctx context.Context, containerName, blobName string, input ReleaseLeaseInput) (result ReleaseLeaseResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + err = fmt.Errorf("`containerName` must be a lower-cased string") + return } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + err = fmt.Errorf("`blobName` cannot be an empty string") + return } if input.LeaseID == "" { - return resp, fmt.Errorf("`input.LeaseID` cannot be an empty string") + err = fmt.Errorf("`input.LeaseID` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -54,7 +57,11 @@ func (c Client) ReleaseLease(ctx context.Context, containerName, blobName string return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/lease_renew.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/lease_renew.go similarity index 72% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/lease_renew.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/lease_renew.go index 2a82a0af2a9e0..e43a12d96ea93 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/lease_renew.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/lease_renew.go @@ -11,29 +11,32 @@ import ( ) type RenewLeaseResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } type RenewLeaseInput struct { LeaseID string } -func (c Client) RenewLease(ctx context.Context, containerName, blobName string, input RenewLeaseInput) (resp RenewLeaseResponse, err error) { - +func (c Client) RenewLease(ctx context.Context, containerName, blobName string, input RenewLeaseInput) (result RenewLeaseResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + err = fmt.Errorf("`containerName` must be a lower-cased string") + return } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + err = fmt.Errorf("`blobName` cannot be an empty string") + return } if input.LeaseID == "" { - return resp, fmt.Errorf("`input.LeaseID` cannot be an empty string") + err = fmt.Errorf("`input.LeaseID` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -53,7 +56,11 @@ func (c Client) RenewLease(ctx context.Context, containerName, blobName string, return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/metadata_set.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/metadata_set.go similarity index 75% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/metadata_set.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/metadata_set.go index 604e7a7bd31d7..ce6c047d02560 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/metadata_set.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/metadata_set.go @@ -21,26 +21,29 @@ type SetMetaDataInput struct { } type SetMetaDataResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // SetMetaData marks the specified blob or snapshot for deletion. The blob is later deleted during garbage collection. -func (c Client) SetMetaData(ctx context.Context, containerName, blobName string, input SetMetaDataInput) (resp SetMetaDataResponse, err error) { - +func (c Client) SetMetaData(ctx context.Context, containerName, blobName string, input SetMetaDataInput) (result SetMetaDataResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + err = fmt.Errorf("`containerName` must be a lower-cased string") + return } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + err = fmt.Errorf("`blobName` cannot be an empty string") + return } - if err := metadata.Validate(input.MetaData); err != nil { - return resp, fmt.Errorf(fmt.Sprintf("`input.MetaData` is not valid: %s.", err)) + if err = metadata.Validate(input.MetaData); err != nil { + err = fmt.Errorf(fmt.Sprintf("`input.MetaData` is not valid: %s.", err)) + return } opts := client.RequestOptions{ @@ -60,7 +63,11 @@ func (c Client) SetMetaData(ctx context.Context, containerName, blobName string, return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/models.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/models.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/models.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/models.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/properties_get.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/properties_get.go similarity index 72% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/properties_get.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/properties_get.go index 86b7c1100bd5a..3edfa89008458 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/properties_get.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/properties_get.go @@ -19,7 +19,7 @@ type GetPropertiesInput struct { } type GetPropertiesResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response // The tier of page blob on a premium storage account or tier of block blob on blob storage or general purpose v2 account. AccessTier AccessTier @@ -158,19 +158,24 @@ type GetPropertiesResponse struct { // Is the Storage Account encrypted using server-side encryption? This should always return true ServerEncrypted bool + + // The encryption scope for the request content. + EncryptionScope string } // GetProperties returns all user-defined metadata, standard HTTP properties, and system properties for the blob -func (c Client) GetProperties(ctx context.Context, containerName, blobName string, input GetPropertiesInput) (resp GetPropertiesResponse, err error) { - +func (c Client) GetProperties(ctx context.Context, containerName, blobName string, input GetPropertiesInput) (result GetPropertiesResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + err = fmt.Errorf("`containerName` must be a lower-cased string") + return } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + err = fmt.Errorf("`blobName` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -190,77 +195,80 @@ func (c Client) GetProperties(ctx context.Context, containerName, blobName strin return } - resp.HttpResponse, err = req.Execute(ctx) - if err != nil { - err = fmt.Errorf("executing request: %+v", err) - return - } - - if resp.HttpResponse != nil { - if resp.HttpResponse.Header != nil { - resp.AccessTier = AccessTier(resp.HttpResponse.Header.Get("x-ms-access-tier")) - resp.AccessTierChangeTime = resp.HttpResponse.Header.Get("x-ms-access-tier-change-time") - resp.ArchiveStatus = ArchiveStatus(resp.HttpResponse.Header.Get("x-ms-archive-status")) - resp.BlobCommittedBlockCount = resp.HttpResponse.Header.Get("x-ms-blob-committed-block-count") - resp.BlobSequenceNumber = resp.HttpResponse.Header.Get("x-ms-blob-sequence-number") - resp.BlobType = BlobType(resp.HttpResponse.Header.Get("x-ms-blob-type")) - resp.CacheControl = resp.HttpResponse.Header.Get("Cache-Control") - resp.ContentDisposition = resp.HttpResponse.Header.Get("Content-Disposition") - resp.ContentEncoding = resp.HttpResponse.Header.Get("Content-Encoding") - resp.ContentLanguage = resp.HttpResponse.Header.Get("Content-Language") - resp.ContentMD5 = resp.HttpResponse.Header.Get("Content-MD5") - resp.ContentType = resp.HttpResponse.Header.Get("Content-Type") - resp.CopyCompletionTime = resp.HttpResponse.Header.Get("x-ms-copy-completion-time") - resp.CopyDestinationSnapshot = resp.HttpResponse.Header.Get("x-ms-copy-destination-snapshot") - resp.CopyID = resp.HttpResponse.Header.Get("x-ms-copy-id") - resp.CopyProgress = resp.HttpResponse.Header.Get("x-ms-copy-progress") - resp.CopySource = resp.HttpResponse.Header.Get("x-ms-copy-source") - resp.CopyStatus = CopyStatus(resp.HttpResponse.Header.Get("x-ms-copy-status")) - resp.CopyStatusDescription = resp.HttpResponse.Header.Get("x-ms-copy-status-description") - resp.CreationTime = resp.HttpResponse.Header.Get("x-ms-creation-time") - resp.ETag = resp.HttpResponse.Header.Get("Etag") - resp.LastModified = resp.HttpResponse.Header.Get("Last-Modified") - resp.LeaseDuration = LeaseDuration(resp.HttpResponse.Header.Get("x-ms-lease-duration")) - resp.LeaseState = LeaseState(resp.HttpResponse.Header.Get("x-ms-lease-state")) - resp.LeaseStatus = LeaseStatus(resp.HttpResponse.Header.Get("x-ms-lease-status")) - resp.MetaData = metadata.ParseFromHeaders(resp.HttpResponse.Header) - - if v := resp.HttpResponse.Header.Get("x-ms-access-tier-inferred"); v != "" { + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + if resp.Header != nil { + result.AccessTier = AccessTier(resp.Header.Get("x-ms-access-tier")) + result.AccessTierChangeTime = resp.Header.Get("x-ms-access-tier-change-time") + result.ArchiveStatus = ArchiveStatus(resp.Header.Get("x-ms-archive-status")) + result.BlobCommittedBlockCount = resp.Header.Get("x-ms-blob-committed-block-count") + result.BlobSequenceNumber = resp.Header.Get("x-ms-blob-sequence-number") + result.BlobType = BlobType(resp.Header.Get("x-ms-blob-type")) + result.CacheControl = resp.Header.Get("Cache-Control") + result.ContentDisposition = resp.Header.Get("Content-Disposition") + result.ContentEncoding = resp.Header.Get("Content-Encoding") + result.ContentLanguage = resp.Header.Get("Content-Language") + result.ContentMD5 = resp.Header.Get("Content-MD5") + result.ContentType = resp.Header.Get("Content-Type") + result.CopyCompletionTime = resp.Header.Get("x-ms-copy-completion-time") + result.CopyDestinationSnapshot = resp.Header.Get("x-ms-copy-destination-snapshot") + result.CopyID = resp.Header.Get("x-ms-copy-id") + result.CopyProgress = resp.Header.Get("x-ms-copy-progress") + result.CopySource = resp.Header.Get("x-ms-copy-source") + result.CopyStatus = CopyStatus(resp.Header.Get("x-ms-copy-status")) + result.CopyStatusDescription = resp.Header.Get("x-ms-copy-status-description") + result.CreationTime = resp.Header.Get("x-ms-creation-time") + result.ETag = resp.Header.Get("Etag") + result.LastModified = resp.Header.Get("Last-Modified") + result.LeaseDuration = LeaseDuration(resp.Header.Get("x-ms-lease-duration")) + result.LeaseState = LeaseState(resp.Header.Get("x-ms-lease-state")) + result.LeaseStatus = LeaseStatus(resp.Header.Get("x-ms-lease-status")) + result.EncryptionScope = resp.Header.Get("x-ms-encryption-scope") + result.MetaData = metadata.ParseFromHeaders(resp.Header) + + if v := resp.Header.Get("x-ms-access-tier-inferred"); v != "" { b, innerErr := strconv.ParseBool(v) if innerErr != nil { - err = fmt.Errorf("error parsing %q as a bool: %s", v, innerErr) + err = fmt.Errorf("parsing `x-ms-access-tier-inferred` header value %q: %s", v, innerErr) return } - resp.AccessTierInferred = b + result.AccessTierInferred = b } - if v := resp.HttpResponse.Header.Get("Content-Length"); v != "" { + if v := resp.Header.Get("Content-Length"); v != "" { i, innerErr := strconv.Atoi(v) if innerErr != nil { - err = fmt.Errorf("error parsing %q as an integer: %s", v, innerErr) + err = fmt.Errorf("parsing `Content-Length` header value %q: %s", v, innerErr) } - resp.ContentLength = int64(i) + result.ContentLength = int64(i) } - if v := resp.HttpResponse.Header.Get("x-ms-incremental-copy"); v != "" { + if v := resp.Header.Get("x-ms-incremental-copy"); v != "" { b, innerErr := strconv.ParseBool(v) if innerErr != nil { - err = fmt.Errorf("error parsing %q as a bool: %s", v, innerErr) + err = fmt.Errorf("parsing `x-ms-incremental-copy` header value %q: %s", v, innerErr) return } - resp.IncrementalCopy = b + result.IncrementalCopy = b } - if v := resp.HttpResponse.Header.Get("x-ms-server-encrypted"); v != "" { + if v := resp.Header.Get("x-ms-server-encrypted"); v != "" { b, innerErr := strconv.ParseBool(v) if innerErr != nil { - err = fmt.Errorf("error parsing %q as a bool: %s", v, innerErr) + err = fmt.Errorf("parsing `x-ms-server-encrypted` header value %q: %s", v, innerErr) return } - resp.ServerEncrypted = b + result.ServerEncrypted = b } } } + if err != nil { + err = fmt.Errorf("executing request: %+v", err) + return + } return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/properties_set.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/properties_set.go similarity index 86% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/properties_set.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/properties_set.go index ebe098556dedd..73b417f045401 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/properties_set.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/properties_set.go @@ -25,25 +25,24 @@ type SetPropertiesInput struct { } type SetPropertiesResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response BlobSequenceNumber string Etag string } // SetProperties sets system properties on the blob. -func (c Client) SetProperties(ctx context.Context, containerName, blobName string, input SetPropertiesInput) (resp SetPropertiesResponse, err error) { - +func (c Client) SetProperties(ctx context.Context, containerName, blobName string, input SetPropertiesInput) (result SetPropertiesResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + return result, fmt.Errorf("`containerName` cannot be an empty string") } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + return result, fmt.Errorf("`containerName` must be a lower-cased string") } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + return result, fmt.Errorf("`blobName` cannot be an empty string") } opts := client.RequestOptions{ @@ -63,7 +62,11 @@ func (c Client) SetProperties(ctx context.Context, containerName, blobName strin return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_append_blob.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/put_append_blob.go similarity index 77% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_append_blob.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/put_append_blob.go index 0f3aa30733a57..8cc53001882f3 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_append_blob.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/put_append_blob.go @@ -19,31 +19,35 @@ type PutAppendBlobInput struct { ContentMD5 *string ContentType *string LeaseID *string + EncryptionScope *string MetaData map[string]string } type PutAppendBlobResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // PutAppendBlob is a wrapper around the Put API call (with a stricter input object) // which creates a new append blob, or updates the content of an existing blob. -func (c Client) PutAppendBlob(ctx context.Context, containerName, blobName string, input PutAppendBlobInput) (resp PutAppendBlobResponse, err error) { - +func (c Client) PutAppendBlob(ctx context.Context, containerName, blobName string, input PutAppendBlobInput) (result PutAppendBlobResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + err = fmt.Errorf("`containerName` must be a lower-cased string") + return } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + err = fmt.Errorf("`blobName` cannot be an empty string") + return } - if err := metadata.Validate(input.MetaData); err != nil { - return resp, fmt.Errorf(fmt.Sprintf("`input.MetaData` is not valid: %s.", err)) + if err = metadata.Validate(input.MetaData); err != nil { + err = fmt.Errorf(fmt.Sprintf("`input.MetaData` is not valid: %s.", err)) + return } opts := client.RequestOptions{ @@ -63,7 +67,11 @@ func (c Client) PutAppendBlob(ctx context.Context, containerName, blobName strin return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return @@ -103,6 +111,9 @@ func (p putAppendBlobOptions) ToHeaders() *client.Headers { if p.input.LeaseID != nil { headers.Append("x-ms-lease-id", *p.input.LeaseID) } + if p.input.EncryptionScope != nil { + headers.Append("x-ms-encryption-scope", *p.input.EncryptionScope) + } headers.Merge(metadata.SetMetaDataHeaders(p.input.MetaData)) return headers diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_block.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/put_block.go similarity index 63% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_block.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/put_block.go index a6059c4aed279..f261ddec31408 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_block.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/put_block.go @@ -1,8 +1,10 @@ package blobs import ( + "bytes" "context" "fmt" + "io" "net/http" "strconv" "strings" @@ -12,39 +14,43 @@ import ( ) type PutBlockInput struct { - BlockID string - Content []byte - ContentMD5 *string - LeaseID *string + BlockID string + Content []byte + ContentMD5 *string + LeaseID *string + EncryptionScope *string } type PutBlockResponse struct { - HttpResponse *client.Response - - ContentMD5 string + HttpResponse *http.Response + ContentMD5 string } // PutBlock creates a new block to be committed as part of a blob. -func (c Client) PutBlock(ctx context.Context, containerName, blobName string, input PutBlockInput) (resp PutBlockResponse, err error) { - +func (c Client) PutBlock(ctx context.Context, containerName, blobName string, input PutBlockInput) (result PutBlockResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + err = fmt.Errorf("`containerName` must be a lower-cased string") + return } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + err = fmt.Errorf("`blobName` cannot be an empty string") + return } if input.BlockID == "" { - return resp, fmt.Errorf("`input.BlockID` cannot be an empty string") + err = fmt.Errorf("`input.BlockID` cannot be an empty string") + return } if len(input.Content) == 0 { - return resp, fmt.Errorf("`input.Content` cannot be empty") + err = fmt.Errorf("`input.Content` cannot be empty") + return } opts := client.RequestOptions{ @@ -64,12 +70,14 @@ func (c Client) PutBlock(ctx context.Context, containerName, blobName string, in return } - err = req.Marshal(&input.Content) - if err != nil { - return resp, fmt.Errorf("marshalling request: %v", err) - } + req.ContentLength = int64(len(input.Content)) + req.Body = io.NopCloser(bytes.NewReader(input.Content)) - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return @@ -92,6 +100,9 @@ func (p putBlockOptions) ToHeaders() *client.Headers { if p.input.LeaseID != nil { headers.Append("x-ms-lease-id", *p.input.LeaseID) } + if p.input.EncryptionScope != nil { + headers.Append("x-ms-encryption-scope", *p.input.EncryptionScope) + } return headers } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_block_blob.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/put_block_blob.go similarity index 73% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_block_blob.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/put_block_blob.go index 462ea17272a08..d5d677393c9ed 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_block_blob.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/put_block_blob.go @@ -21,35 +21,40 @@ type PutBlockBlobInput struct { ContentMD5 *string ContentType *string LeaseID *string + EncryptionScope *string MetaData map[string]string } type PutBlockBlobResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // PutBlockBlob is a wrapper around the Put API call (with a stricter input object) // which creates a new block append blob, or updates the content of an existing block blob. -func (c Client) PutBlockBlob(ctx context.Context, containerName, blobName string, input PutBlockBlobInput) (resp PutBlockBlobResponse, err error) { - +func (c Client) PutBlockBlob(ctx context.Context, containerName, blobName string, input PutBlockBlobInput) (result PutBlockBlobResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + err = fmt.Errorf("`containerName` must be a lower-cased string") + return } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + err = fmt.Errorf("`blobName` cannot be an empty string") + return } if input.Content != nil && len(*input.Content) == 0 { - return resp, fmt.Errorf("`input.Content` must either be nil or not empty") + err = fmt.Errorf("`input.Content` must either be nil or not empty") + return } - if err := metadata.Validate(input.MetaData); err != nil { - return resp, fmt.Errorf(fmt.Sprintf("`input.MetaData` is not valid: %s.", err)) + if err = metadata.Validate(input.MetaData); err != nil { + err = fmt.Errorf(fmt.Sprintf("`input.MetaData` is not valid: %s.", err)) + return } opts := client.RequestOptions{ @@ -63,18 +68,27 @@ func (c Client) PutBlockBlob(ctx context.Context, containerName, blobName string Path: fmt.Sprintf("/%s/%s", containerName, blobName), } + if input.ContentType != nil { + opts.ContentType = *input.ContentType + } + req, err := c.Client.NewRequest(ctx, opts) if err != nil { err = fmt.Errorf("building request: %+v", err) return } - err = req.Marshal(&input.Content) + err = req.Marshal(input.Content) if err != nil { - return resp, fmt.Errorf("marshalling request: %v", err) + err = fmt.Errorf("marshalling request: %+v", err) + return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return @@ -112,6 +126,9 @@ func (p putBlockBlobOptions) ToHeaders() *client.Headers { if p.input.LeaseID != nil { headers.Append("x-ms-lease-id", *p.input.LeaseID) } + if p.input.EncryptionScope != nil { + headers.Append("x-ms-encryption-scope", *p.input.EncryptionScope) + } if p.input.Content != nil { headers.Append("Content-Length", strconv.Itoa(len(*p.input.Content))) } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_block_blob_file.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/put_block_blob_file.go similarity index 79% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_block_blob_file.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/put_block_blob_file.go index 932fb320607d8..f5f21b0736edf 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_block_blob_file.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/put_block_blob_file.go @@ -11,7 +11,7 @@ import ( func (c Client) PutBlockBlobFromFile(ctx context.Context, containerName, blobName string, file *os.File, input PutBlockBlobInput) error { fileInfo, err := file.Stat() if err != nil { - return fmt.Errorf("error loading file info: %s", err) + return fmt.Errorf("loading file info: %s", err) } fileSize := fileInfo.Size() @@ -20,14 +20,14 @@ func (c Client) PutBlockBlobFromFile(ctx context.Context, containerName, blobNam _, err = file.ReadAt(bytes, 0) if err != nil { if err != io.EOF { - return fmt.Errorf("Error reading bytes: %s", err) + return fmt.Errorf("reading bytes: %s", err) } } input.Content = &bytes if _, err = c.PutBlockBlob(ctx, containerName, blobName, input); err != nil { - return fmt.Errorf("error putting bytes: %s", err) + return fmt.Errorf("putting bytes: %s", err) } return nil diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_block_list.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/put_block_list.go similarity index 78% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_block_list.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/put_block_list.go index bfe451b941c96..a600fdbe369a2 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_block_list.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/put_block_list.go @@ -29,12 +29,13 @@ type PutBlockListInput struct { ContentLanguage *string ContentMD5 *string ContentType *string - MetaData map[string]string LeaseID *string + EncryptionScope *string + MetaData map[string]string } type PutBlockListResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response ContentMD5 string ETag string @@ -44,18 +45,20 @@ type PutBlockListResponse struct { // PutBlockList writes a blob by specifying the list of block IDs that make up the blob. // In order to be written as part of a blob, a block must have been successfully written // to the server in a prior Put Block operation. -func (c Client) PutBlockList(ctx context.Context, containerName, blobName string, input PutBlockListInput) (resp PutBlockListResponse, err error) { - +func (c Client) PutBlockList(ctx context.Context, containerName, blobName string, input PutBlockListInput) (result PutBlockListResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + err = fmt.Errorf("`containerName` must be a lower-cased string") + return } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + err = fmt.Errorf("`blobName` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -77,23 +80,26 @@ func (c Client) PutBlockList(ctx context.Context, containerName, blobName string err = req.Marshal(&input.BlockList) if err != nil { - return resp, fmt.Errorf("marshalling request: %v", err) + err = fmt.Errorf("marshalling request: %+v", err) + return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + if resp.Header != nil { + result.ContentMD5 = resp.Header.Get("Content-MD5") + result.ETag = resp.Header.Get("ETag") + result.LastModified = resp.Header.Get("Last-Modified") + } + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return } - if resp.HttpResponse != nil { - if resp.HttpResponse.Header != nil { - resp.ContentMD5 = resp.HttpResponse.Header.Get("Content-MD5") - resp.ETag = resp.HttpResponse.Header.Get("ETag") - resp.LastModified = resp.HttpResponse.Header.Get("Last-Modified") - } - } - return } @@ -125,6 +131,9 @@ func (p putBlockListOptions) ToHeaders() *client.Headers { if p.input.LeaseID != nil { headers.Append("x-ms-lease-id", *p.input.LeaseID) } + if p.input.EncryptionScope != nil { + headers.Append("x-ms-encryption-scope", *p.input.EncryptionScope) + } headers.Merge(metadata.SetMetaDataHeaders(p.input.MetaData)) diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_block_url.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/put_block_url.go similarity index 67% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_block_url.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/put_block_url.go index cd8487c5c265d..088742367bea0 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_block_url.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/put_block_url.go @@ -14,37 +14,42 @@ type PutBlockFromURLInput struct { BlockID string CopySource string - ContentMD5 *string - LeaseID *string - Range *string + ContentMD5 *string + LeaseID *string + Range *string + EncryptionScope *string } type PutBlockFromURLResponse struct { - HttpResponse *client.Response ContentMD5 string + HttpResponse *http.Response } // PutBlockFromURL creates a new block to be committed as part of a blob where the contents are read from a URL -func (c Client) PutBlockFromURL(ctx context.Context, containerName, blobName string, input PutBlockFromURLInput) (resp PutBlockFromURLResponse, err error) { - +func (c Client) PutBlockFromURL(ctx context.Context, containerName, blobName string, input PutBlockFromURLInput) (result PutBlockFromURLResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + err = fmt.Errorf("`containerName` must be a lower-cased string") + return } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + err = fmt.Errorf("`blobName` cannot be an empty string") + return } if input.BlockID == "" { - return resp, fmt.Errorf("`input.BlockID` cannot be an empty string") + err = fmt.Errorf("`input.BlockID` cannot be an empty string") + return } if input.CopySource == "" { - return resp, fmt.Errorf("`input.CopySource` cannot be an empty string") + err = fmt.Errorf("`input.CopySource` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -64,18 +69,20 @@ func (c Client) PutBlockFromURL(ctx context.Context, containerName, blobName str return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + if resp.Header != nil { + result.ContentMD5 = resp.Header.Get("Content-MD5") + } + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return } - if resp.HttpResponse != nil { - if resp.HttpResponse.Header != nil { - resp.ContentMD5 = resp.HttpResponse.Header.Get("Content-MD5") - } - } - return } @@ -97,6 +104,9 @@ func (p putBlockUrlOptions) ToHeaders() *client.Headers { if p.input.Range != nil { headers.Append("x-ms-source-range", *p.input.Range) } + if p.input.EncryptionScope != nil { + headers.Append("x-ms-encryption-scope", *p.input.EncryptionScope) + } return headers } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_page_blob.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/put_page_blob.go similarity index 83% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_page_blob.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/put_page_blob.go index 2b733c4c13117..74bfc6b2b2601 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_page_blob.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/put_page_blob.go @@ -20,6 +20,7 @@ type PutPageBlobInput struct { ContentMD5 *string ContentType *string LeaseID *string + EncryptionScope *string MetaData map[string]string BlobContentLengthBytes int64 @@ -28,27 +29,30 @@ type PutPageBlobInput struct { } type PutPageBlobResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // PutPageBlob is a wrapper around the Put API call (with a stricter input object) // which creates a new block blob, or updates the content of an existing page blob. -func (c Client) PutPageBlob(ctx context.Context, containerName, blobName string, input PutPageBlobInput) (resp PutPageBlobResponse, err error) { - +func (c Client) PutPageBlob(ctx context.Context, containerName, blobName string, input PutPageBlobInput) (result PutPageBlobResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + err = fmt.Errorf("`containerName` must be a lower-cased string") + return } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + err = fmt.Errorf("`blobName` cannot be an empty string") + return } if input.BlobContentLengthBytes == 0 || input.BlobContentLengthBytes%512 != 0 { - return resp, fmt.Errorf("`input.BlobContentLengthBytes` must be aligned to a 512-byte boundary") + err = fmt.Errorf("`input.BlobContentLengthBytes` must be aligned to a 512-byte boundary") + return } opts := client.RequestOptions{ @@ -68,7 +72,11 @@ func (c Client) PutPageBlob(ctx context.Context, containerName, blobName string, return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return @@ -130,6 +138,10 @@ func (p putPageBlobOptions) ToHeaders() *client.Headers { headers.Append("x-ms-lease-id", *p.input.LeaseID) } + if p.input.EncryptionScope != nil { + headers.Append("x-ms-encryption-scope", *p.input.EncryptionScope) + } + headers.Merge(metadata.SetMetaDataHeaders(p.input.MetaData)) return headers } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_page_clear.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/put_page_clear.go similarity index 68% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_page_clear.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/put_page_clear.go index 1a995138d166e..45e0499e431d1 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_page_clear.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/put_page_clear.go @@ -14,34 +14,39 @@ type PutPageClearInput struct { StartByte int64 EndByte int64 - LeaseID *string + LeaseID *string + EncryptionScope *string } type PutPageClearResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // PutPageClear clears a range of pages within a page blob. -func (c Client) PutPageClear(ctx context.Context, containerName, blobName string, input PutPageClearInput) (resp PutPageClearResponse, err error) { - +func (c Client) PutPageClear(ctx context.Context, containerName, blobName string, input PutPageClearInput) (result PutPageClearResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + err = fmt.Errorf("`containerName` must be a lower-cased string") + return } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + err = fmt.Errorf("`blobName` cannot be an empty string") + return } if input.StartByte < 0 { - return resp, fmt.Errorf("`input.StartByte` must be greater than or equal to 0") + err = fmt.Errorf("`input.StartByte` must be greater than or equal to 0") + return } if input.EndByte <= 0 { - return resp, fmt.Errorf("`input.EndByte` must be greater than 0") + err = fmt.Errorf("`input.EndByte` must be greater than 0") + return } opts := client.RequestOptions{ @@ -61,7 +66,11 @@ func (c Client) PutPageClear(ctx context.Context, containerName, blobName string return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return @@ -83,6 +92,10 @@ func (p putPageClearOptions) ToHeaders() *client.Headers { if p.input.LeaseID != nil { headers.Append("x-ms-lease-id", *p.input.LeaseID) } + if p.input.EncryptionScope != nil { + headers.Append("x-ms-encryption-scope", *p.input.EncryptionScope) + } + return headers } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_page_update.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/put_page_update.go similarity index 72% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_page_update.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/put_page_update.go index 448fe343d903f..ab5f258373e37 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/put_page_update.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/put_page_update.go @@ -26,10 +26,11 @@ type PutPageUpdateInput struct { IfMatch *string IfNoneMatch *string LeaseID *string + EncryptionScope *string } type PutPageUpdateResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response BlobSequenceNumber string ContentMD5 string @@ -37,32 +38,37 @@ type PutPageUpdateResponse struct { } // PutPageUpdate writes a range of pages to a page blob. -func (c Client) PutPageUpdate(ctx context.Context, containerName, blobName string, input PutPageUpdateInput) (resp PutPageUpdateResponse, err error) { - +func (c Client) PutPageUpdate(ctx context.Context, containerName, blobName string, input PutPageUpdateInput) (result PutPageUpdateResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + err = fmt.Errorf("`containerName` must be a lower-cased string") + return } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + err = fmt.Errorf("`blobName` cannot be an empty string") + return } if input.StartByte < 0 { - return resp, fmt.Errorf("`input.StartByte` must be greater than or equal to 0") + err = fmt.Errorf("`input.StartByte` must be greater than or equal to 0") + return } if input.EndByte <= 0 { - return resp, fmt.Errorf("`input.EndByte` must be greater than 0") + err = fmt.Errorf("`input.EndByte` must be greater than 0") + return } expectedSize := (input.EndByte - input.StartByte) + 1 actualSize := int64(len(input.Content)) if expectedSize != actualSize { - return resp, fmt.Errorf(fmt.Sprintf("Content Size was defined as %d but got %d.", expectedSize, actualSize)) + err = fmt.Errorf(fmt.Sprintf("Content Size was defined as %d but got %d.", expectedSize, actualSize)) + return } opts := client.RequestOptions{ @@ -82,21 +88,26 @@ func (c Client) PutPageUpdate(ctx context.Context, containerName, blobName strin return } + // this is needed to avoid `Content-Length: 0` in the request req.Body = io.NopCloser(bytes.NewReader(input.Content)) req.ContentLength = int64(len(input.Content)) - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + if resp.Header != nil { + result.BlobSequenceNumber = resp.Header.Get("x-ms-blob-sequence-number") + result.ContentMD5 = resp.Header.Get("Content-MD5") + result.LastModified = resp.Header.Get("Last-Modified") + } + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return } - if resp.HttpResponse != nil && resp.HttpResponse.Header != nil { - resp.BlobSequenceNumber = resp.HttpResponse.Header.Get("x-ms-blob-sequence-number") - resp.ContentMD5 = resp.HttpResponse.Header.Get("Content-MD5") - resp.LastModified = resp.HttpResponse.Header.Get("Last-Modified") - } - return } @@ -114,6 +125,10 @@ func (p putPageUpdateOptions) ToHeaders() *client.Headers { headers.Append("x-ms-lease-id", *p.input.LeaseID) } + if p.input.EncryptionScope != nil { + headers.Append("x-ms-encryption-scope", *p.input.EncryptionScope) + } + if p.input.IfSequenceNumberEQ != nil { headers.Append("x-ms-if-sequence-number-eq", *p.input.IfSequenceNumberEQ) } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/resource_id.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/resource_id.go similarity index 97% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/resource_id.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/resource_id.go index a31673f4e25aa..95b78f5ca780f 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/resource_id.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/resource_id.go @@ -6,7 +6,7 @@ import ( "strings" "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts" ) // TODO: update this to implement `resourceids.ResourceId` once diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/set_tier.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/set_tier.go similarity index 75% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/set_tier.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/set_tier.go index 35cca5b8d7f9f..66b9d64884ae4 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/set_tier.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/set_tier.go @@ -15,22 +15,24 @@ type SetTierInput struct { } type SetTierResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // SetTier sets the tier on a blob. -func (c Client) SetTier(ctx context.Context, containerName, blobName string, input SetTierInput) (resp SetTierResponse, err error) { - +func (c Client) SetTier(ctx context.Context, containerName, blobName string, input SetTierInput) (result SetTierResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + err = fmt.Errorf("`containerName` must be a lower-cased string") + return } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + err = fmt.Errorf("`blobName` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -51,7 +53,11 @@ func (c Client) SetTier(ctx context.Context, containerName, blobName string, inp return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/snapshot.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/snapshot.go similarity index 79% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/snapshot.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/snapshot.go index 8a90dcdaf2044..ebbcb2011220b 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/snapshot.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/snapshot.go @@ -16,6 +16,9 @@ type SnapshotInput struct { // This must be specified if a Lease is present on the Blob, else a 403 is returned LeaseID *string + // The encryption scope to set for the request content. + EncryptionScope *string + // MetaData is a user-defined name-value pair associated with the blob. // If no name-value pairs are specified, the operation will copy the base blob metadata to the snapshot. // If one or more name-value pairs are specified, the snapshot is created with the specified metadata, @@ -41,7 +44,7 @@ type SnapshotInput struct { } type SnapshotResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response // The ETag of the snapshot ETag string @@ -53,22 +56,25 @@ type SnapshotResponse struct { } // Snapshot captures a Snapshot of a given Blob -func (c Client) Snapshot(ctx context.Context, containerName, blobName string, input SnapshotInput) (resp SnapshotResponse, err error) { - +func (c Client) Snapshot(ctx context.Context, containerName, blobName string, input SnapshotInput) (result SnapshotResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + err = fmt.Errorf("`containerName` must be a lower-cased string") + return } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + err = fmt.Errorf("`blobName` cannot be an empty string") + return } - if err := metadata.Validate(input.MetaData); err != nil { - return resp, fmt.Errorf(fmt.Sprintf("`input.MetaData` is not valid: %s.", err)) + if err = metadata.Validate(input.MetaData); err != nil { + err = fmt.Errorf(fmt.Sprintf("`input.MetaData` is not valid: %s.", err)) + return } opts := client.RequestOptions{ @@ -88,17 +94,21 @@ func (c Client) Snapshot(ctx context.Context, containerName, blobName string, in return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + if resp.Header != nil { + result.ETag = resp.Header.Get("ETag") + result.SnapshotDateTime = resp.Header.Get("x-ms-snapshot") + } + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return } - if resp.HttpResponse != nil && resp.HttpResponse.Header != nil { - resp.ETag = resp.HttpResponse.Header.Get("ETag") - resp.SnapshotDateTime = resp.HttpResponse.Header.Get("x-ms-snapshot") - } - return } @@ -113,6 +123,10 @@ func (s snapshotOptions) ToHeaders() *client.Headers { headers.Append("x-ms-lease-id", *s.input.LeaseID) } + if s.input.EncryptionScope != nil { + headers.Append("x-ms-encryption-scope", *s.input.EncryptionScope) + } + if s.input.IfModifiedSince != nil { headers.Append("If-Modified-Since", *s.input.IfModifiedSince) } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/snapshot_get_properties.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/snapshot_get_properties.go new file mode 100644 index 0000000000000..09e53cf43f19f --- /dev/null +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/snapshot_get_properties.go @@ -0,0 +1,168 @@ +package blobs + +import ( + "context" + "fmt" + "net/http" + "strconv" + "strings" + + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" + "github.com/tombuildsstuff/giovanni/storage/internal/metadata" +) + +type GetSnapshotPropertiesInput struct { + // The ID of the Lease + // This must be specified if a Lease is present on the Blob, else a 403 is returned + LeaseID *string + + // The ID of the Snapshot which should be retrieved + SnapshotID string +} + +// GetSnapshotProperties returns all user-defined metadata, standard HTTP properties, and system properties for +// the specified snapshot of a blob +func (c Client) GetSnapshotProperties(ctx context.Context, containerName, blobName string, input GetSnapshotPropertiesInput) (result GetPropertiesResponse, err error) { + if containerName == "" { + err = fmt.Errorf("`containerName` cannot be an empty string") + return + } + + if strings.ToLower(containerName) != containerName { + err = fmt.Errorf("`containerName` must be a lower-cased string") + return + } + + if blobName == "" { + err = fmt.Errorf("`blobName` cannot be an empty string") + return + } + + if input.SnapshotID == "" { + err = fmt.Errorf("`input.SnapshotID` cannot be an empty string") + return + } + + opts := client.RequestOptions{ + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodHead, + OptionsObject: snapshotGetPropertiesOptions{ + input: input, + }, + Path: fmt.Sprintf("/%s/%s", containerName, blobName), + } + + req, err := c.Client.NewRequest(ctx, opts) + if err != nil { + err = fmt.Errorf("building request: %+v", err) + return + } + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + if resp.Header != nil { + result.AccessTier = AccessTier(resp.Header.Get("x-ms-access-tier")) + result.AccessTierChangeTime = resp.Header.Get("x-ms-access-tier-change-time") + result.ArchiveStatus = ArchiveStatus(resp.Header.Get("x-ms-archive-status")) + result.BlobCommittedBlockCount = resp.Header.Get("x-ms-blob-committed-block-count") + result.BlobSequenceNumber = resp.Header.Get("x-ms-blob-sequence-number") + result.BlobType = BlobType(resp.Header.Get("x-ms-blob-type")) + result.CacheControl = resp.Header.Get("Cache-Control") + result.ContentDisposition = resp.Header.Get("Content-Disposition") + result.ContentEncoding = resp.Header.Get("Content-Encoding") + result.ContentLanguage = resp.Header.Get("Content-Language") + result.ContentMD5 = resp.Header.Get("Content-MD5") + result.ContentType = resp.Header.Get("Content-Type") + result.CopyCompletionTime = resp.Header.Get("x-ms-copy-completion-time") + result.CopyDestinationSnapshot = resp.Header.Get("x-ms-copy-destination-snapshot") + result.CopyID = resp.Header.Get("x-ms-copy-id") + result.CopyProgress = resp.Header.Get("x-ms-copy-progress") + result.CopySource = resp.Header.Get("x-ms-copy-source") + result.CopyStatus = CopyStatus(resp.Header.Get("x-ms-copy-status")) + result.CopyStatusDescription = resp.Header.Get("x-ms-copy-status-description") + result.CreationTime = resp.Header.Get("x-ms-creation-time") + result.ETag = resp.Header.Get("Etag") + result.LastModified = resp.Header.Get("Last-Modified") + result.LeaseDuration = LeaseDuration(resp.Header.Get("x-ms-lease-duration")) + result.LeaseState = LeaseState(resp.Header.Get("x-ms-lease-state")) + result.LeaseStatus = LeaseStatus(resp.Header.Get("x-ms-lease-status")) + result.MetaData = metadata.ParseFromHeaders(resp.Header) + + if v := resp.Header.Get("Content-Length"); v != "" { + i, innerErr := strconv.Atoi(v) + if innerErr != nil { + err = fmt.Errorf("parsing `Content-Length` header value %q: %+v", v, innerErr) + } + + result.ContentLength = int64(i) + } + + if v := resp.Header.Get("x-ms-access-tier-inferred"); v != "" { + b, innerErr := strconv.ParseBool(v) + if innerErr != nil { + err = fmt.Errorf("parsing `x-ms-access-tier-inferred` header value %q: %+v", v, innerErr) + return + } + + result.AccessTierInferred = b + } + + if v := resp.Header.Get("x-ms-incremental-copy"); v != "" { + b, innerErr := strconv.ParseBool(v) + if innerErr != nil { + err = fmt.Errorf("parsing `x-ms-incremental-copy` header value %q: %+v", v, innerErr) + return + } + + result.IncrementalCopy = b + } + + if v := resp.Header.Get("x-ms-server-encrypted"); v != "" { + b, innerErr := strconv.ParseBool(v) + if innerErr != nil { + err = fmt.Errorf("parsing `\"x-ms-server-encrypted` header value %q: %+v", v, innerErr) + return + } + + result.ServerEncrypted = b + } + } + } + if err != nil { + err = fmt.Errorf("executing request: %+v", err) + return + } + + if result.HttpResponse != nil { + } + + return +} + +type snapshotGetPropertiesOptions struct { + input GetSnapshotPropertiesInput +} + +func (s snapshotGetPropertiesOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} + if s.input.LeaseID != nil { + headers.Append("x-ms-lease-id", *s.input.LeaseID) + } + return headers +} + +func (s snapshotGetPropertiesOptions) ToOData() *odata.Query { + return nil +} + +func (s snapshotGetPropertiesOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + out.Append("snapshot", s.input.SnapshotID) + return out +} diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/undelete.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/undelete.go similarity index 74% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/undelete.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/undelete.go index e46277c77af14..149971fc1035e 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/undelete.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/undelete.go @@ -11,22 +11,24 @@ import ( ) type UndeleteResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // Undelete restores the contents and metadata of soft deleted blob and any associated soft deleted snapshots. -func (c Client) Undelete(ctx context.Context, containerName, blobName string) (resp UndeleteResponse, err error) { - +func (c Client) Undelete(ctx context.Context, containerName, blobName string) (result UndeleteResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } if strings.ToLower(containerName) != containerName { - return resp, fmt.Errorf("`containerName` must be a lower-cased string") + err = fmt.Errorf("`containerName` must be a lower-cased string") + return } if blobName == "" { - return resp, fmt.Errorf("`blobName` cannot be an empty string") + err = fmt.Errorf("`blobName` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -44,7 +46,11 @@ func (c Client) Undelete(ctx context.Context, containerName, blobName string) (r return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/version.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/version.go similarity index 79% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/version.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/version.go index 414d3405774ab..da934d3c1001f 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs/version.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs/version.go @@ -1,5 +1,5 @@ package blobs // APIVersion is the version of the API used for all Storage API Operations -const apiVersion = "2020-08-04" +const apiVersion = "2023-11-03" const componentName = "blob/blobs" diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/README.md b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/README.md similarity index 91% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/README.md rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/README.md index c93528771d6ed..6283cd7f71135 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/README.md +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/README.md @@ -1,4 +1,4 @@ -## Blob Storage Container SDK for API version 2020-08-04 +## Blob Storage Container SDK for API version 2023-11-03 This package allows you to interact with the Containers Blob Storage API @@ -19,7 +19,7 @@ import ( "fmt" "github.com/hashicorp/go-azure-sdk/sdk/auth" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers" ) func Example() error { diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/api.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/api.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/api.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/api.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/client.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/client.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/client.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/client.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/create.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/create.go new file mode 100644 index 0000000000000..f47c4cf1f422e --- /dev/null +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/create.go @@ -0,0 +1,135 @@ +package containers + +import ( + "bytes" + "context" + "encoding/xml" + "fmt" + "io" + "net/http" + "strings" + + "github.com/hashicorp/go-azure-helpers/lang/response" + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" + "github.com/tombuildsstuff/giovanni/storage/internal/metadata" +) + +type CreateInput struct { + // Specifies whether data in the container may be accessed publicly and the level of access + AccessLevel AccessLevel + + // The encryption scope to set as the default on the container. + DefaultEncryptionScope string + + // Setting this to ture indicates that every blob that's uploaded to this container uses the default encryption scope. + EncryptionScopeOverrideDisabled bool + + // A name-value pair to associate with the container as metadata. + MetaData map[string]string +} + +type CreateResponse struct { + HttpResponse *http.Response +} + +// Create creates a new container under the specified account. +// If the container with the same name already exists, the operation fails. +func (c Client) Create(ctx context.Context, containerName string, input CreateInput) (result CreateResponse, err error) { + if containerName == "" { + err = fmt.Errorf("`containerName` cannot be an empty string") + return + } + if err = metadata.Validate(input.MetaData); err != nil { + err = fmt.Errorf("`input.MetaData` is not valid: %+v", err) + return + } + + // Retry the container creation if a conflicting container is still in the process of being deleted + retryFunc := func(resp *http.Response, _ *odata.OData) (bool, error) { + if resp != nil { + if response.WasStatusCode(resp, http.StatusConflict) { + // TODO: move this error response parsing to a common helper function + respBody, err := io.ReadAll(resp.Body) + if err != nil { + return false, fmt.Errorf("could not parse response body") + } + resp.Body.Close() + respBody = bytes.TrimPrefix(respBody, []byte("\xef\xbb\xbf")) + res := ErrorResponse{} + if err = xml.Unmarshal(respBody, &res); err != nil { + return false, err + } + resp.Body = io.NopCloser(bytes.NewBuffer(respBody)) + if res.Code != nil { + return strings.Contains(*res.Code, "ContainerBeingDeleted"), nil + } + } + } + return false, nil + } + + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusCreated, + }, + HttpMethod: http.MethodPut, + OptionsObject: createOptions{ + input: input, + }, + Path: fmt.Sprintf("/%s", containerName), + RetryFunc: retryFunc, + } + + req, err := c.Client.NewRequest(ctx, opts) + if err != nil { + err = fmt.Errorf("building request: %+v", err) + return + } + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } + if err != nil { + err = fmt.Errorf("executing request: %+v", err) + return + } + + return +} + +var _ client.Options = createOptions{} + +type createOptions struct { + input CreateInput +} + +func (o createOptions) ToHeaders() *client.Headers { + headers := containerOptions{ + metaData: o.input.MetaData, + }.ToHeaders() + + // If this header is not included in the request, container data is private to the account owner. + if o.input.AccessLevel != Private { + headers.Append("x-ms-blob-public-access", string(o.input.AccessLevel)) + } + + if o.input.DefaultEncryptionScope != "" { + // These two headers must be used together. + headers.Append("x-ms-default-encryption-scope", o.input.DefaultEncryptionScope) + headers.Append("x-ms-deny-encryption-scope-override", fmt.Sprintf("%t", o.input.EncryptionScopeOverrideDisabled)) + } + + return headers +} + +func (createOptions) ToOData() *odata.Query { + return nil +} + +func (createOptions) ToQuery() *client.QueryParams { + return containerOptions{}.ToQuery() +} diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/delete.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/delete.go similarity index 76% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/delete.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/delete.go index 0aea0ed7f1df4..d654e4aba8a75 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/delete.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/delete.go @@ -9,14 +9,15 @@ import ( ) type DeleteResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // Delete marks the specified container for deletion. // The container and any blobs contained within it are later deleted during garbage collection. -func (c Client) Delete(ctx context.Context, containerName string) (resp DeleteResponse, err error) { +func (c Client) Delete(ctx context.Context, containerName string) (result DeleteResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -28,12 +29,18 @@ func (c Client) Delete(ctx context.Context, containerName string) (resp DeleteRe OptionsObject: containerOptions{}, Path: fmt.Sprintf("/%s", containerName), } + req, err := c.Client.NewRequest(ctx, opts) if err != nil { err = fmt.Errorf("building request: %+v", err) return } - resp.HttpResponse, err = req.Execute(ctx) + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/get_properties.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/get_properties.go similarity index 52% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/get_properties.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/get_properties.go index 2655b0ba89e1e..ca97cf83a7f95 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/get_properties.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/get_properties.go @@ -16,14 +16,15 @@ type GetPropertiesInput struct { } type GetPropertiesResponse struct { - HttpResponse *client.Response - Model *ContainerProperties + ContainerProperties + HttpResponse *http.Response } // GetProperties returns the properties for this Container without a Lease -func (c Client) GetProperties(ctx context.Context, containerName string, input GetPropertiesInput) (resp GetPropertiesResponse, err error) { +func (c Client) GetProperties(ctx context.Context, containerName string, input GetPropertiesInput) (result GetPropertiesResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -37,40 +38,48 @@ func (c Client) GetProperties(ctx context.Context, containerName string, input G }, Path: fmt.Sprintf("/%s", containerName), } + req, err := c.Client.NewRequest(ctx, opts) if err != nil { err = fmt.Errorf("building request: %+v", err) return } - resp.HttpResponse, err = req.Execute(ctx) + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + if resp.Header != nil { + result.DefaultEncryptionScope = resp.Header.Get("x-ms-default-encryption-scope") + result.LeaseStatus = LeaseStatus(resp.Header.Get("x-ms-lease-status")) + result.LeaseState = LeaseState(resp.Header.Get("x-ms-lease-state")) + if result.LeaseStatus == Locked { + duration := LeaseDuration(resp.Header.Get("x-ms-lease-duration")) + result.LeaseDuration = &duration + } + + // If this header is not returned in the response, the container is private to the account owner. + accessLevel := resp.Header.Get("x-ms-blob-public-access") + if accessLevel != "" { + result.AccessLevel = AccessLevel(accessLevel) + } else { + result.AccessLevel = Private + } + + // we can't necessarily use strconv.ParseBool here since this could be nil (only in some API versions) + result.EncryptionScopeOverrideDisabled = strings.EqualFold(resp.Header.Get("x-ms-deny-encryption-scope-override"), "true") + result.HasImmutabilityPolicy = strings.EqualFold(resp.Header.Get("x-ms-has-immutability-policy"), "true") + result.HasLegalHold = strings.EqualFold(resp.Header.Get("x-ms-has-legal-hold"), "true") + + result.MetaData = metadata.ParseFromHeaders(resp.Header) + } + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return } - if resp.HttpResponse != nil { - resp.Model = &ContainerProperties{} - resp.Model.LeaseStatus = LeaseStatus(resp.HttpResponse.Header.Get("x-ms-lease-status")) - resp.Model.LeaseState = LeaseState(resp.HttpResponse.Header.Get("x-ms-lease-state")) - if resp.Model.LeaseStatus == Locked { - duration := LeaseDuration(resp.HttpResponse.Header.Get("x-ms-lease-duration")) - resp.Model.LeaseDuration = &duration - } - - // If this header is not returned in the response, the container is private to the account owner. - accessLevel := resp.HttpResponse.Header.Get("x-ms-blob-public-access") - if accessLevel != "" { - resp.Model.AccessLevel = AccessLevel(accessLevel) - } else { - resp.Model.AccessLevel = Private - } - - // we can't necessarily use strconv.ParseBool here since this could be nil (only in some API versions) - resp.Model.HasImmutabilityPolicy = strings.EqualFold(resp.HttpResponse.Header.Get("x-ms-has-immutability-policy"), "true") - resp.Model.HasLegalHold = strings.EqualFold(resp.HttpResponse.Header.Get("x-ms-has-legal-hold"), "true") - resp.Model.MetaData = metadata.ParseFromHeaders(resp.HttpResponse.Header) - } - return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/lease_acquire.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/lease_acquire.go similarity index 80% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/lease_acquire.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/lease_acquire.go index 409f15a47172f..a863c14982476 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/lease_acquire.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/lease_acquire.go @@ -18,8 +18,8 @@ type AcquireLeaseInput struct { } type AcquireLeaseResponse struct { - HttpResponse *client.Response - Model *AcquireLeaseModel + AcquireLeaseModel + HttpResponse *http.Response } type AcquireLeaseModel struct { @@ -27,13 +27,13 @@ type AcquireLeaseModel struct { } // AcquireLease establishes and manages a lock on a container for delete operations. -func (c Client) AcquireLease(ctx context.Context, containerName string, input AcquireLeaseInput) (resp AcquireLeaseResponse, err error) { +func (c Client) AcquireLease(ctx context.Context, containerName string, input AcquireLeaseInput) (result AcquireLeaseResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + return result, fmt.Errorf("`containerName` cannot be an empty string") } // An infinite lease duration is -1 seconds. A non-infinite lease can be between 15 and 60 seconds if input.LeaseDuration != -1 && (input.LeaseDuration <= 15 || input.LeaseDuration >= 60) { - return resp, fmt.Errorf("`input.LeaseDuration` must be -1 (infinite), or between 15 and 60 seconds") + return result, fmt.Errorf("`input.LeaseDuration` must be -1 (infinite), or between 15 and 60 seconds") } opts := client.RequestOptions{ @@ -48,23 +48,27 @@ func (c Client) AcquireLease(ctx context.Context, containerName string, input Ac }, Path: fmt.Sprintf("/%s", containerName), } + req, err := c.Client.NewRequest(ctx, opts) if err != nil { err = fmt.Errorf("building request: %+v", err) return } - resp.HttpResponse, err = req.Execute(ctx) + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + if resp.Header != nil { + result.LeaseID = resp.Header.Get("x-ms-lease-id") + } + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return } - if resp.HttpResponse != nil { - resp.Model = &AcquireLeaseModel{ - LeaseID: resp.HttpResponse.Header.Get("x-ms-lease-id"), - } - } - return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/lease_break.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/lease_break.go similarity index 80% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/lease_break.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/lease_break.go index 0ede9a818a0fd..b141e2582f007 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/lease_break.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/lease_break.go @@ -3,11 +3,10 @@ package containers import ( "context" "fmt" - "net/http" - "strconv" - "github.com/hashicorp/go-azure-sdk/sdk/client" "github.com/hashicorp/go-azure-sdk/sdk/odata" + "net/http" + "strconv" ) type BreakLeaseInput struct { @@ -25,8 +24,8 @@ type BreakLeaseInput struct { } type BreakLeaseResponse struct { - HttpResponse *client.Response - Model *BreakLeaseModel + BreakLeaseModel + HttpResponse *http.Response } type BreakLeaseModel struct { @@ -36,12 +35,12 @@ type BreakLeaseModel struct { } // BreakLease breaks a lock based on it's Lease ID -func (c Client) BreakLease(ctx context.Context, containerName string, input BreakLeaseInput) (resp BreakLeaseResponse, err error) { +func (c Client) BreakLease(ctx context.Context, containerName string, input BreakLeaseInput) (result BreakLeaseResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + return result, fmt.Errorf("`containerName` cannot be an empty string") } if input.LeaseID == "" { - return resp, fmt.Errorf("`input.LeaseID` cannot be an empty string") + return result, fmt.Errorf("`input.LeaseID` cannot be an empty string") } opts := client.RequestOptions{ @@ -56,27 +55,30 @@ func (c Client) BreakLease(ctx context.Context, containerName string, input Brea }, Path: fmt.Sprintf("/%s", containerName), } + req, err := c.Client.NewRequest(ctx, opts) if err != nil { err = fmt.Errorf("building request: %+v", err) return } - resp.HttpResponse, err = req.Execute(ctx) - if err != nil { - err = fmt.Errorf("executing request: %+v", err) - return - } - if resp.HttpResponse != nil { - leaseRaw := resp.HttpResponse.Header.Get("x-ms-lease-time") - if leaseRaw != "" { - if i, err := strconv.Atoi(leaseRaw); err == nil { - resp.Model = &BreakLeaseModel{ - LeaseTime: i, + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + if resp.Header != nil { + if leaseTimeRaw := resp.Header.Get("x-ms-lease-time"); leaseTimeRaw != "" { + if leaseTime, err := strconv.Atoi(leaseTimeRaw); err == nil { + result.LeaseTime = leaseTime } } } } + if err != nil { + err = fmt.Errorf("executing request: %+v", err) + return + } return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/lease_change.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/lease_change.go similarity index 76% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/lease_change.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/lease_change.go index 6326507707ee1..1c1d7321066d4 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/lease_change.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/lease_change.go @@ -15,8 +15,8 @@ type ChangeLeaseInput struct { } type ChangeLeaseResponse struct { - HttpResponse *client.Response - Model *ChangeLeaseModel + ChangeLeaseModel + HttpResponse *http.Response } type ChangeLeaseModel struct { @@ -24,15 +24,18 @@ type ChangeLeaseModel struct { } // ChangeLease changes the lock from one Lease ID to another Lease ID -func (c Client) ChangeLease(ctx context.Context, containerName string, input ChangeLeaseInput) (resp ChangeLeaseResponse, err error) { +func (c Client) ChangeLease(ctx context.Context, containerName string, input ChangeLeaseInput) (result ChangeLeaseResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } if input.ExistingLeaseID == "" { - return resp, fmt.Errorf("`input.ExistingLeaseID` cannot be an empty string") + err = fmt.Errorf("`input.ExistingLeaseID` cannot be an empty string") + return } if input.ProposedLeaseID == "" { - return resp, fmt.Errorf("`input.ProposedLeaseID` cannot be an empty string") + err = fmt.Errorf("`input.ProposedLeaseID` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -47,23 +50,27 @@ func (c Client) ChangeLease(ctx context.Context, containerName string, input Cha }, Path: fmt.Sprintf("/%s", containerName), } + req, err := c.Client.NewRequest(ctx, opts) if err != nil { err = fmt.Errorf("building request: %+v", err) return } - resp.HttpResponse, err = req.Execute(ctx) + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + if resp.Header != nil { + result.LeaseID = resp.Header.Get("x-ms-lease-id") + } + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return } - if resp.HttpResponse != nil { - resp.Model = &ChangeLeaseModel{ - LeaseID: resp.HttpResponse.Header.Get("x-ms-lease-id"), - } - } - return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/lease_release.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/lease_release.go similarity index 79% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/lease_release.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/lease_release.go index 8a2cf4114e002..cdff4e2cf9ce8 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/lease_release.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/lease_release.go @@ -14,16 +14,18 @@ type ReleaseLeaseInput struct { } type ReleaseLeaseResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // ReleaseLease releases the lock based on the Lease ID -func (c Client) ReleaseLease(ctx context.Context, containerName string, input ReleaseLeaseInput) (resp ReleaseLeaseResponse, err error) { +func (c Client) ReleaseLease(ctx context.Context, containerName string, input ReleaseLeaseInput) (result ReleaseLeaseResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } if input.LeaseId == "" { - return resp, fmt.Errorf("`input.LeaseId` cannot be an empty string") + err = fmt.Errorf("`input.LeaseId` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -37,12 +39,18 @@ func (c Client) ReleaseLease(ctx context.Context, containerName string, input Re }, Path: fmt.Sprintf("/%s", containerName), } + req, err := c.Client.NewRequest(ctx, opts) if err != nil { err = fmt.Errorf("building request: %+v", err) return } - resp.HttpResponse, err = req.Execute(ctx) + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/lease_renew.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/lease_renew.go similarity index 79% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/lease_renew.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/lease_renew.go index eda202989f230..38c948689996b 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/lease_renew.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/lease_renew.go @@ -14,16 +14,18 @@ type RenewLeaseInput struct { } type RenewLeaseResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // RenewLease renews the lock based on the Lease ID -func (c Client) RenewLease(ctx context.Context, containerName string, input RenewLeaseInput) (resp RenewLeaseResponse, err error) { +func (c Client) RenewLease(ctx context.Context, containerName string, input RenewLeaseInput) (result RenewLeaseResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } if input.LeaseId == "" { - return resp, fmt.Errorf("`input.LeaseId` cannot be an empty string") + err = fmt.Errorf("`input.LeaseId` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -37,12 +39,18 @@ func (c Client) RenewLease(ctx context.Context, containerName string, input Rene }, Path: fmt.Sprintf("/%s", containerName), } + req, err := c.Client.NewRequest(ctx, opts) if err != nil { err = fmt.Errorf("building request: %+v", err) return } - resp.HttpResponse, err = req.Execute(ctx) + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/list_blobs.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/list_blobs.go similarity index 90% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/list_blobs.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/list_blobs.go index f3bd4674d30d2..86ddc7c0a9df0 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/list_blobs.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/list_blobs.go @@ -19,8 +19,9 @@ type ListBlobsInput struct { } type ListBlobsResponse struct { - HttpResponse *client.Response - Model *ListBlobsResult + ListBlobsResult + + HttpResponse *http.Response } type ListBlobsResult struct { @@ -80,12 +81,14 @@ type BlobPrefix struct { } // ListBlobs lists the blobs matching the specified query within the specified Container -func (c Client) ListBlobs(ctx context.Context, containerName string, input ListBlobsInput) (resp ListBlobsResponse, err error) { +func (c Client) ListBlobs(ctx context.Context, containerName string, input ListBlobsInput) (result ListBlobsResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } if input.MaxResults != nil && (*input.MaxResults <= 0 || *input.MaxResults > 5000) { - return resp, fmt.Errorf("`input.MaxResults` can either be nil or between 0 and 5000") + err = fmt.Errorf("`input.MaxResults` can either be nil or between 0 and 5000") + return } opts := client.RequestOptions{ ContentType: "application/xml; charset=utf-8", @@ -102,23 +105,28 @@ func (c Client) ListBlobs(ctx context.Context, containerName string, input ListB }, Path: fmt.Sprintf("/%s", containerName), } + req, err := c.Client.NewRequest(ctx, opts) if err != nil { err = fmt.Errorf("building request: %+v", err) return } - resp.HttpResponse, err = req.Execute(ctx) - if err != nil { - err = fmt.Errorf("executing request: %+v", err) - return - } - if resp.HttpResponse != nil { - if err = resp.HttpResponse.Unmarshal(&resp.Model); err != nil { - err = fmt.Errorf("unmarshaling response: %+v", err) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + err = resp.Unmarshal(&result) + if err != nil { + err = fmt.Errorf("unmarshalling response: %+v", err) return } } + if err != nil { + err = fmt.Errorf("executing request: %+v", err) + return + } return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/models.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/models.go similarity index 74% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/models.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/models.go index ddfe1953aae6c..94c3b86b29162 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/models.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/models.go @@ -1,5 +1,7 @@ package containers +import "encoding/xml" + type AccessLevel string var ( @@ -19,13 +21,15 @@ var ( ) type ContainerProperties struct { - AccessLevel AccessLevel - LeaseStatus LeaseStatus - LeaseState LeaseState - LeaseDuration *LeaseDuration - MetaData map[string]string - HasImmutabilityPolicy bool - HasLegalHold bool + AccessLevel AccessLevel + DefaultEncryptionScope string + EncryptionScopeOverrideDisabled bool + LeaseStatus LeaseStatus + LeaseState LeaseState + LeaseDuration *LeaseDuration + MetaData map[string]string + HasImmutabilityPolicy bool + HasLegalHold bool } type Dataset string @@ -39,8 +43,9 @@ var ( ) type ErrorResponse struct { - Code *string `xml:"Code"` - Message *string `xml:"Message"` + XMLName xml.Name `xml:"Error"` + Code *string `xml:"Code"` + Message *string `xml:"Message"` } type LeaseDuration string diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/options.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/options.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/options.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/options.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/resource_id.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/resource_id.go similarity index 97% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/resource_id.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/resource_id.go index 321ea60e4a298..691360246ed83 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/resource_id.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/resource_id.go @@ -6,7 +6,7 @@ import ( "strings" "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts" ) // GetResourceManagerResourceID returns the Resource Manager specific diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/set_acl.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/set_acl.go similarity index 87% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/set_acl.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/set_acl.go index 642053735ff4a..280ad4e391ff1 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/set_acl.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/set_acl.go @@ -15,14 +15,15 @@ type SetAccessControlInput struct { } type SetAccessControlResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // SetAccessControl sets the Access Control for a Container without a Lease ID // NOTE: The SetAccessControl operation only supports Shared Key authorization. -func (c Client) SetAccessControl(ctx context.Context, containerName string, input SetAccessControlInput) (resp SetAccessControlResponse, err error) { +func (c Client) SetAccessControl(ctx context.Context, containerName string, input SetAccessControlInput) (result SetAccessControlResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -37,12 +38,18 @@ func (c Client) SetAccessControl(ctx context.Context, containerName string, inpu }, Path: fmt.Sprintf("/%s", containerName), } + req, err := c.Client.NewRequest(ctx, opts) if err != nil { err = fmt.Errorf("building request: %+v", err) return } - resp.HttpResponse, err = req.Execute(ctx) + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/set_metadata.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/set_metadata.go similarity index 81% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/set_metadata.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/set_metadata.go index 578c9a1695580..3f8bb07e2819f 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/set_metadata.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/set_metadata.go @@ -16,16 +16,18 @@ type SetMetaDataInput struct { } type SetMetaDataResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // SetMetaData sets the specified MetaData on the Container without a Lease ID -func (c Client) SetMetaData(ctx context.Context, containerName string, input SetMetaDataInput) (resp SetMetaDataResponse, err error) { +func (c Client) SetMetaData(ctx context.Context, containerName string, input SetMetaDataInput) (result SetMetaDataResponse, err error) { if containerName == "" { - return resp, fmt.Errorf("`containerName` cannot be an empty string") + err = fmt.Errorf("`containerName` cannot be an empty string") + return } - if err := metadata.Validate(input.MetaData); err != nil { - return resp, fmt.Errorf("`input.MetaData` is not valid: %s", err) + if err = metadata.Validate(input.MetaData); err != nil { + err = fmt.Errorf("`input.MetaData` is not valid: %s", err) + return } opts := client.RequestOptions{ @@ -40,12 +42,18 @@ func (c Client) SetMetaData(ctx context.Context, containerName string, input Set }, Path: fmt.Sprintf("/%s", containerName), } + req, err := c.Client.NewRequest(ctx, opts) if err != nil { err = fmt.Errorf("building request: %+v", err) return } - resp.HttpResponse, err = req.Execute(ctx) + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/version.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/version.go similarity index 65% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/version.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/version.go index d55e9ee67f889..1806c68f41431 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers/version.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers/version.go @@ -1,4 +1,4 @@ package containers -const apiVersion = "2020-08-04" +const apiVersion = "2023-11-03" const componentName = "blob/containers" diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/README.md b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/README.md similarity index 90% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/README.md rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/README.md index df369cc10c473..ac35149dab397 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/README.md +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/README.md @@ -1,4 +1,4 @@ -## Data Lake Storage Gen2 File Systems SDK for API version 2020-08-04 +## Data Lake Storage Gen2 File Systems SDK for API version 2023-11-03 This package allows you to interact with the Data Lake Storage Gen2 File Systems API @@ -14,12 +14,11 @@ package main import ( "context" "fmt" - "os" "github.com/hashicorp/go-azure-helpers/authentication" "github.com/hashicorp/go-azure-helpers/sender" "github.com/hashicorp/go-azure-sdk/sdk/auth" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems" ) func Example() error { diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/client.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/client.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/client.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/client.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/create.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/create.go similarity index 85% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/create.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/create.go index d0d4bab6321e4..5bf1b66b52516 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/create.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/create.go @@ -18,14 +18,14 @@ type CreateInput struct { } type CreateResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // Create creates a Data Lake Store Gen2 FileSystem within a Storage Account -func (c Client) Create(ctx context.Context, fileSystemName string, input CreateInput) (resp CreateResponse, err error) { - +func (c Client) Create(ctx context.Context, fileSystemName string, input CreateInput) (result CreateResponse, err error) { if fileSystemName == "" { - return resp, fmt.Errorf("`fileSystemName` cannot be an empty string") + err = fmt.Errorf("`fileSystemName` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -42,12 +42,16 @@ func (c Client) Create(ctx context.Context, fileSystemName string, input CreateI } req, err := c.Client.NewRequest(ctx, opts) - if err != nil { err = fmt.Errorf("building request: %+v", err) return } - resp.HttpResponse, err = req.Execute(ctx) + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/delete.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/delete.go similarity index 75% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/delete.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/delete.go index a6d33b3328011..6900f2899d352 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/delete.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/delete.go @@ -9,14 +9,14 @@ import ( ) type DeleteResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // Delete deletes a Data Lake Store Gen2 FileSystem within a Storage Account -func (c Client) Delete(ctx context.Context, fileSystemName string) (resp DeleteResponse, err error) { - +func (c Client) Delete(ctx context.Context, fileSystemName string) (result DeleteResponse, err error) { if fileSystemName == "" { - return resp, fmt.Errorf("`fileSystemName` cannot be an empty string") + err = fmt.Errorf("`fileSystemName` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -28,12 +28,18 @@ func (c Client) Delete(ctx context.Context, fileSystemName string) (resp DeleteR OptionsObject: fileSystemOptions{}, Path: fmt.Sprintf("/%s", fileSystemName), } + req, err := c.Client.NewRequest(ctx, opts) if err != nil { err = fmt.Errorf("building request: %+v", err) return } - resp.HttpResponse, err = req.Execute(ctx) + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/helpers.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/helpers.go similarity index 90% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/helpers.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/helpers.go index 605ed425929df..7822a128154e5 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/helpers.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/helpers.go @@ -29,7 +29,7 @@ func parseProperties(input string) (*map[string]string, error) { // as such we can't string split on that -_- position := strings.Index(propertyRaw, "=") if position < 0 { - return nil, fmt.Errorf("Expected there to be an equals in the key value pair: %q", propertyRaw) + return nil, fmt.Errorf("expected an equal sign in the key value pair: %q", propertyRaw) } key := propertyRaw[0:position] diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/options.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/options.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/options.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/options.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/properties_get.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/properties_get.go similarity index 67% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/properties_get.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/properties_get.go index e8e4a67d0a058..47f394ab6dd2b 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/properties_get.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/properties_get.go @@ -10,7 +10,7 @@ import ( ) type GetPropertiesResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response // A map of base64-encoded strings to store as user-defined properties with the File System // Note that items may only contain ASCII characters in the ISO-8859-1 character set. @@ -23,10 +23,10 @@ type GetPropertiesResponse struct { } // GetProperties gets the properties for a Data Lake Store Gen2 FileSystem within a Storage Account -func (c Client) GetProperties(ctx context.Context, fileSystemName string) (resp GetPropertiesResponse, err error) { - +func (c Client) GetProperties(ctx context.Context, fileSystemName string) (result GetPropertiesResponse, err error) { if fileSystemName == "" { - return resp, fmt.Errorf("`fileSystemName` cannot be an empty string") + err = fmt.Errorf("`fileSystemName` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -45,24 +45,27 @@ func (c Client) GetProperties(ctx context.Context, fileSystemName string) (resp return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + if resp.Header != nil { + propertiesRaw := resp.Header.Get("x-ms-properties") + var properties *map[string]string + properties, err = parseProperties(propertiesRaw) + if err != nil { + return + } + + result.Properties = *properties + result.NamespaceEnabled = strings.EqualFold(resp.Header.Get("x-ms-namespace-enabled"), "true") + } + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return } - if resp.HttpResponse != nil { - - propertiesRaw := resp.HttpResponse.Header.Get("x-ms-properties") - var properties *map[string]string - properties, err = parseProperties(propertiesRaw) - if err != nil { - return - } - - resp.Properties = *properties - resp.NamespaceEnabled = strings.EqualFold(resp.HttpResponse.Header.Get("x-ms-namespace-enabled"), "true") - - } return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/properties_set.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/properties_set.go similarity index 89% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/properties_set.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/properties_set.go index 82c259a236e8c..775807aeb338d 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/properties_set.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/properties_set.go @@ -26,14 +26,14 @@ type SetPropertiesInput struct { } type SetPropertiesResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // SetProperties sets the Properties for a Data Lake Store Gen2 FileSystem within a Storage Account -func (c Client) SetProperties(ctx context.Context, fileSystemName string, input SetPropertiesInput) (resp SetPropertiesResponse, err error) { - +func (c Client) SetProperties(ctx context.Context, fileSystemName string, input SetPropertiesInput) (result SetPropertiesResponse, err error) { if fileSystemName == "" { - return resp, fmt.Errorf("`fileSystemName` cannot be an empty string") + err = fmt.Errorf("`fileSystemName` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -52,12 +52,16 @@ func (c Client) SetProperties(ctx context.Context, fileSystemName string, input } req, err := c.Client.NewRequest(ctx, opts) - if err != nil { err = fmt.Errorf("building request: %+v", err) return } - resp.HttpResponse, err = req.Execute(ctx) + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/resource_id.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/resource_id.go similarity index 97% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/resource_id.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/resource_id.go index a2664ac47590b..60670df684a14 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/resource_id.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/resource_id.go @@ -6,7 +6,7 @@ import ( "strings" "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts" ) // GetResourceManagerResourceID returns the Resource Manager specific diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/version.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/version.go similarity index 68% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/version.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/version.go index ff22a87f4ecaf..954c9cac5a64f 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems/version.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems/version.go @@ -1,4 +1,4 @@ package filesystems -const apiVersion = "2020-08-04" +const apiVersion = "2023-11-03" const componentName = "datalakestore/filesystems" diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/client.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths/client.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/client.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths/client.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/create.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths/create.go similarity index 79% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/create.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths/create.go index c95ea17ba1a50..8db9b66413eba 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/create.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths/create.go @@ -19,14 +19,14 @@ type CreateInput struct { } type CreateResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // Create creates a Data Lake Store Gen2 Path within a Storage Account -func (c Client) Create(ctx context.Context, fileSystemName string, path string, input CreateInput) (resp CreateResponse, err error) { +func (c Client) Create(ctx context.Context, fileSystemName string, path string, input CreateInput) (result CreateResponse, err error) { if fileSystemName == "" { - return resp, fmt.Errorf("`fileSystemName` cannot be an empty string") + return result, fmt.Errorf("`fileSystemName` cannot be an empty string") } opts := client.RequestOptions{ @@ -46,12 +46,17 @@ func (c Client) Create(ctx context.Context, fileSystemName string, path string, if err != nil { err = fmt.Errorf("building request: %+v", err) - return resp, err + return result, err + } + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response } - resp.HttpResponse, err = req.Execute(ctx) if err != nil { err = fmt.Errorf("executing request: %+v", err) - return resp, err + return result, err } return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/delete.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths/delete.go similarity index 74% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/delete.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths/delete.go index 4ea6e9312cdbb..990be5157dc9e 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/delete.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths/delete.go @@ -9,14 +9,14 @@ import ( ) type DeleteResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // Delete deletes a Data Lake Store Gen2 FileSystem within a Storage Account -func (c Client) Delete(ctx context.Context, fileSystemName string, path string) (resp DeleteResponse, err error) { +func (c Client) Delete(ctx context.Context, fileSystemName string, path string) (result DeleteResponse, err error) { if fileSystemName == "" { - return resp, fmt.Errorf("`fileSystemName` cannot be an empty string") + return result, fmt.Errorf("`fileSystemName` cannot be an empty string") } opts := client.RequestOptions{ @@ -33,7 +33,12 @@ func (c Client) Delete(ctx context.Context, fileSystemName string, path string) err = fmt.Errorf("building request: %+v", err) return } - resp.HttpResponse, err = req.Execute(ctx) + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/helpers.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths/helpers.go similarity index 77% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/helpers.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths/helpers.go index e6ef6f4bfb9f3..08d893c2b81d7 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/helpers.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths/helpers.go @@ -11,5 +11,5 @@ func parsePathResource(input string) (PathResource, error) { case "directory": return PathResourceDirectory, nil } - return "", fmt.Errorf("Unhandled path resource type %q", input) + return "", fmt.Errorf("unhandled path resource type %q", input) } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/properties_get.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths/properties_get.go similarity index 64% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/properties_get.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths/properties_get.go index 2bb81afc574fa..f5dcb782a5a40 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/properties_get.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths/properties_get.go @@ -11,7 +11,7 @@ import ( ) type GetPropertiesResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response ETag string LastModified time.Time @@ -24,7 +24,7 @@ type GetPropertiesResponse struct { } type GetPropertiesInput struct { - action GetPropertiesAction + Action GetPropertiesAction } type GetPropertiesAction string @@ -35,9 +35,10 @@ const ( ) // GetProperties gets the properties for a Data Lake Store Gen2 Path in a FileSystem within a Storage Account -func (c Client) GetProperties(ctx context.Context, fileSystemName string, path string, input GetPropertiesInput) (resp GetPropertiesResponse, err error) { +func (c Client) GetProperties(ctx context.Context, fileSystemName string, path string, input GetPropertiesInput) (result GetPropertiesResponse, err error) { if fileSystemName == "" { - return resp, fmt.Errorf("`fileSystemName` cannot be an empty string") + err = fmt.Errorf("`fileSystemName` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -47,7 +48,7 @@ func (c Client) GetProperties(ctx context.Context, fileSystemName string, path s }, HttpMethod: http.MethodHead, OptionsObject: getPropertyOptions{ - action: input.action, + action: input.Action, }, Path: fmt.Sprintf("/%s/%s", fileSystemName, path), } @@ -56,31 +57,36 @@ func (c Client) GetProperties(ctx context.Context, fileSystemName string, path s if err != nil { err = fmt.Errorf("building request: %+v", err) - return resp, err + return result, err } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + if resp.Header != nil { + result.ResourceType = PathResource(resp.Header.Get("x-ms-resource-type")) + result.ETag = resp.Header.Get("ETag") + + if lastModifiedRaw := resp.Header.Get("Last-Modified"); lastModifiedRaw != "" { + lastModified, err := time.Parse(time.RFC1123, lastModifiedRaw) + if err != nil { + return GetPropertiesResponse{}, err + } + result.LastModified = lastModified + } + + result.Owner = resp.Header.Get("x-ms-owner") + result.Group = resp.Header.Get("x-ms-group") + result.ACL = resp.Header.Get("x-ms-acl") + } + } if err != nil { err = fmt.Errorf("executing request: %+v", err) - return resp, err + return result, err } - if resp.HttpResponse != nil { - resp.ResourceType = PathResource(resp.HttpResponse.Header.Get("x-ms-resource-type")) - resp.ETag = resp.HttpResponse.Header.Get("ETag") - - if lastModifiedRaw := resp.HttpResponse.Header.Get("Last-Modified"); lastModifiedRaw != "" { - lastModified, err := time.Parse(time.RFC1123, lastModifiedRaw) - if err != nil { - return GetPropertiesResponse{}, err - } - resp.LastModified = lastModified - } - - resp.Owner = resp.HttpResponse.Header.Get("x-ms-owner") - resp.Group = resp.HttpResponse.Header.Get("x-ms-group") - resp.ACL = resp.HttpResponse.Header.Get("x-ms-acl") - } return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/properties_set.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths/properties_set.go similarity index 85% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/properties_set.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths/properties_set.go index 055f199cbc873..826e0ef46ce92 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/properties_set.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths/properties_set.go @@ -24,14 +24,14 @@ type SetAccessControlInput struct { } type SetPropertiesResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // SetProperties sets the access control properties for a Data Lake Store Gen2 Path within a Storage Account File System -func (c Client) SetAccessControl(ctx context.Context, fileSystemName string, path string, input SetAccessControlInput) (resp SetPropertiesResponse, err error) { - +func (c Client) SetAccessControl(ctx context.Context, fileSystemName string, path string, input SetAccessControlInput) (result SetPropertiesResponse, err error) { if fileSystemName == "" { - return resp, fmt.Errorf("`fileSystemName` cannot be an empty string") + err = fmt.Errorf("`fileSystemName` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -50,13 +50,17 @@ func (c Client) SetAccessControl(ctx context.Context, fileSystemName string, pat if err != nil { err = fmt.Errorf("building request: %+v", err) - return resp, err + return result, err } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) - return resp, err + return result, err } return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/resource_id.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths/resource_id.go similarity index 97% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/resource_id.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths/resource_id.go index 61022090e7744..58570e6abd354 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/resource_id.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths/resource_id.go @@ -6,7 +6,7 @@ import ( "strings" "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts" ) // TODO: update this to implement `resourceids.ResourceId` once diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/version.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths/version.go similarity index 64% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/version.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths/version.go index bd06c2d4d15c0..70c22f9a4ac06 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths/version.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths/version.go @@ -1,4 +1,4 @@ package paths -const apiVersion = "2020-08-04" +const apiVersion = "2023-11-03" const componentName = "datalakestore/paths" diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/README.md b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/README.md similarity index 92% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/README.md rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/README.md index 602f0a6d9910a..d81f7b0c581a7 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/README.md +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/README.md @@ -1,4 +1,4 @@ -## File Storage Directories SDK for API version 2020-08-04 +## File Storage Directories SDK for API version 2023-11-03 This package allows you to interact with the Directories File Storage API @@ -21,7 +21,7 @@ import ( "fmt" "github.com/hashicorp/go-azure-sdk/sdk/auth" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories" ) func Example() error { diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/api.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/api.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/api.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/api.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/client.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/client.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/client.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/client.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/create.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/create.go similarity index 84% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/create.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/create.go index 7f63f9f87737c..fdca3cf3f9a94 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/create.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/create.go @@ -28,26 +28,30 @@ type CreateDirectoryInput struct { } type CreateDirectoryResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // Create creates a new directory under the specified share or parent directory. -func (c Client) Create(ctx context.Context, shareName, path string, input CreateDirectoryInput) (resp CreateDirectoryResponse, err error) { +func (c Client) Create(ctx context.Context, shareName, path string, input CreateDirectoryInput) (result CreateDirectoryResponse, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + err = fmt.Errorf("`shareName` cannot be an empty string") + return } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + err = fmt.Errorf("`shareName` must be a lower-cased string") + return } if err = metadata.Validate(input.MetaData); err != nil { - return resp, fmt.Errorf("`input.MetaData` is not valid: %s", err) + err = fmt.Errorf("`input.MetaData` is not valid: %s", err) + return } if path == "" { - return resp, fmt.Errorf("`path` cannot be an empty string") + err = fmt.Errorf("`path` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -68,7 +72,11 @@ func (c Client) Create(ctx context.Context, shareName, path string, input Create return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/delete.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/delete.go similarity index 70% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/delete.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/delete.go index fb96108862e40..35b7298307ae1 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/delete.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/delete.go @@ -10,23 +10,26 @@ import ( ) type DeleteResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // Delete removes the specified empty directory // Note that the directory must be empty before it can be deleted. -func (c Client) Delete(ctx context.Context, shareName, path string) (resp DeleteResponse, err error) { +func (c Client) Delete(ctx context.Context, shareName, path string) (result DeleteResponse, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + err = fmt.Errorf("`shareName` cannot be an empty string") + return } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + err = fmt.Errorf("`shareName` must be a lower-cased string") + return } if path == "" { - return resp, fmt.Errorf("`path` cannot be an empty string") + err = fmt.Errorf("`path` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -45,7 +48,11 @@ func (c Client) Delete(ctx context.Context, shareName, path string) (resp Delete return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/get.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/get.go similarity index 69% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/get.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/get.go index 5c900c4d10ffd..2aeb03186f084 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/get.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/get.go @@ -11,7 +11,7 @@ import ( ) type GetResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response // A set of name-value pairs that contain metadata for the directory. MetaData map[string]string @@ -23,17 +23,20 @@ type GetResponse struct { // Get returns all system properties for the specified directory, // and can also be used to check the existence of a directory. -func (c Client) Get(ctx context.Context, shareName, path string) (resp GetResponse, err error) { +func (c Client) Get(ctx context.Context, shareName, path string) (result GetResponse, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + err = fmt.Errorf("`shareName` cannot be an empty string") + return } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + err = fmt.Errorf("`shareName` must be a lower-cased string") + return } if path == "" { - return resp, fmt.Errorf("`path` cannot be an empty string") + err = fmt.Errorf("`path` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -52,18 +55,20 @@ func (c Client) Get(ctx context.Context, shareName, path string) (resp GetRespon return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + if resp.Header != nil { + result.DirectoryMetaDataEncrypted = strings.EqualFold(resp.Header.Get("x-ms-server-encrypted"), "true") + result.MetaData = metadata.ParseFromHeaders(resp.Header) + } + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return } - if resp.HttpResponse != nil { - if resp.HttpResponse.Header != nil { - resp.MetaData = metadata.ParseFromHeaders(resp.HttpResponse.Header) - } - resp.DirectoryMetaDataEncrypted = strings.EqualFold(resp.HttpResponse.Header.Get("x-ms-server-encrypted"), "true") - } - return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/metadata_get.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/metadata_get.go similarity index 73% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/metadata_get.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/metadata_get.go index 1911d39616f4c..cfefeb5d5726f 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/metadata_get.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/metadata_get.go @@ -12,23 +12,26 @@ import ( ) type GetMetaDataResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response MetaData map[string]string } // GetMetaData returns all user-defined metadata for the specified directory -func (c Client) GetMetaData(ctx context.Context, shareName, path string) (resp GetMetaDataResponse, err error) { +func (c Client) GetMetaData(ctx context.Context, shareName, path string) (result GetMetaDataResponse, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + err = fmt.Errorf("`shareName` cannot be an empty string") + return } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + err = fmt.Errorf("`shareName` must be a lower-cased string") + return } if path == "" { - return resp, fmt.Errorf("`path` cannot be an empty string") + err = fmt.Errorf("`path` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -47,18 +50,20 @@ func (c Client) GetMetaData(ctx context.Context, shareName, path string) (resp G return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + if resp.Header != nil { + result.MetaData = metadata.ParseFromHeaders(resp.Header) + } + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return } - if resp.HttpResponse != nil { - if resp.HttpResponse.Header != nil { - resp.MetaData = metadata.ParseFromHeaders(resp.HttpResponse.Header) - } - } - return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/metadata_set.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/metadata_set.go similarity index 74% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/metadata_set.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/metadata_set.go index 965f5ffef12ac..8aa9097d3ef90 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/metadata_set.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/metadata_set.go @@ -12,7 +12,7 @@ import ( ) type SetMetaDataResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } type SetMetaDataInput struct { @@ -20,22 +20,26 @@ type SetMetaDataInput struct { } // SetMetaData updates user defined metadata for the specified directory -func (c Client) SetMetaData(ctx context.Context, shareName, path string, input SetMetaDataInput) (resp SetMetaDataResponse, err error) { +func (c Client) SetMetaData(ctx context.Context, shareName, path string, input SetMetaDataInput) (result SetMetaDataResponse, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + err = fmt.Errorf("`shareName` cannot be an empty string") + return } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + err = fmt.Errorf("`shareName` must be a lower-cased string") + return } - if err := metadata.Validate(input.MetaData); err != nil { - return resp, fmt.Errorf("`metadata` is not valid: %s", err) + if err = metadata.Validate(input.MetaData); err != nil { + err = fmt.Errorf("`metadata` is not valid: %s", err) + return } if path == "" { - return resp, fmt.Errorf("`path` cannot be an empty string") + err = fmt.Errorf("`path` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -56,7 +60,11 @@ func (c Client) SetMetaData(ctx context.Context, shareName, path string, input S return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/options.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/options.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/options.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/options.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/resource_id.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/resource_id.go similarity index 97% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/resource_id.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/resource_id.go index 26b0d4ca3f432..b49c41ade78b3 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/resource_id.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/resource_id.go @@ -6,7 +6,7 @@ import ( "strings" "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts" ) // TODO: update this to implement `resourceids.ResourceId` once diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/version.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/version.go similarity index 81% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/version.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/version.go index 508cbe75c3fea..785860cbd0920 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories/version.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories/version.go @@ -1,5 +1,5 @@ package directories // APIVersion is the version of the API used for all Storage API Operations -const apiVersion = "2020-08-04" +const apiVersion = "2023-11-03" const componentName = "file/directories" diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/README.md b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/README.md similarity index 92% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/README.md rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/README.md index dc8df5ff3af18..0ac6146b88cc0 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/README.md +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/README.md @@ -1,4 +1,4 @@ -## File Storage Files SDK for API version 2020-08-04 +## File Storage Files SDK for API version 2023-11-03 This package allows you to interact with the Files File Storage API @@ -21,7 +21,7 @@ import ( "fmt" "github.com/hashicorp/go-azure-sdk/sdk/auth" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files" ) func Example() error { diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/api.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/api.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/api.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/api.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/client.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/client.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/client.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/client.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/copy.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/copy.go similarity index 77% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/copy.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/copy.go index 577f95d60e30c..d8351395df861 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/copy.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/copy.go @@ -25,7 +25,7 @@ type CopyInput struct { } type CopyResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response // The CopyID, which can be passed to AbortCopy to abort the copy. CopyID string @@ -35,26 +35,31 @@ type CopyResponse struct { } // Copy copies a blob or file to a destination file within the storage account asynchronously. -func (c Client) Copy(ctx context.Context, shareName, path, fileName string, input CopyInput) (resp CopyResponse, err error) { +func (c Client) Copy(ctx context.Context, shareName, path, fileName string, input CopyInput) (result CopyResponse, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + err = fmt.Errorf("`shareName` cannot be an empty string") + return } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + err = fmt.Errorf("`shareName` must be a lower-cased string") + return } if fileName == "" { - return resp, fmt.Errorf("`fileName` cannot be an empty string") + err = fmt.Errorf("`fileName` cannot be an empty string") + return } if input.CopySource == "" { - return resp, fmt.Errorf("`input.CopySource` cannot be an empty string") + err = fmt.Errorf("`input.CopySource` cannot be an empty string") + return } if err = metadata.Validate(input.MetaData); err != nil { - return resp, fmt.Errorf("`input.MetaData` is not valid: %s", err) + err = fmt.Errorf("`input.MetaData` is not valid: %s", err) + return } if path != "" { @@ -78,19 +83,22 @@ func (c Client) Copy(ctx context.Context, shareName, path, fileName string, inpu err = fmt.Errorf("building request: %+v", err) return } - resp.HttpResponse, err = req.Execute(ctx) + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + if resp.Header != nil { + result.CopyID = resp.Header.Get("x-ms-copy-id") + result.CopySuccess = resp.Header.Get("x-ms-copy-status") + } + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return } - if resp.HttpResponse != nil { - if resp.HttpResponse.Header != nil { - resp.CopyID = resp.HttpResponse.Header.Get("x-ms-copy-id") - resp.CopySuccess = resp.HttpResponse.Header.Get("x-ms-copy-status") - } - } - return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/copy_abort.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/copy_abort.go similarity index 75% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/copy_abort.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/copy_abort.go index 55611602d37e4..191929b8dab52 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/copy_abort.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/copy_abort.go @@ -15,26 +15,30 @@ type CopyAbortInput struct { } type CopyAbortResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // AbortCopy aborts a pending Copy File operation, and leaves a destination file with zero length and full metadata -func (c Client) AbortCopy(ctx context.Context, shareName, path, fileName string, input CopyAbortInput) (resp CopyAbortResponse, err error) { +func (c Client) AbortCopy(ctx context.Context, shareName, path, fileName string, input CopyAbortInput) (result CopyAbortResponse, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + err = fmt.Errorf("`shareName` cannot be an empty string") + return } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + err = fmt.Errorf("`shareName` must be a lower-cased string") + return } if fileName == "" { - return resp, fmt.Errorf("`fileName` cannot be an empty string") + err = fmt.Errorf("`fileName` cannot be an empty string") + return } if input.copyID == "" { - return resp, fmt.Errorf("`copyID` cannot be an empty string") + err = fmt.Errorf("`copyID` cannot be an empty string") + return } if path != "" { @@ -59,7 +63,11 @@ func (c Client) AbortCopy(ctx context.Context, shareName, path, fileName string, return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/copy_and_wait_poller.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/copy_and_wait_poller.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/copy_and_wait_poller.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/copy_and_wait_poller.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/copy_wait.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/copy_wait.go similarity index 59% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/copy_wait.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/copy_wait.go index 1ccb5f31e635b..9223f54331ae4 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/copy_wait.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/copy_wait.go @@ -9,20 +9,20 @@ import ( ) // CopyAndWait is a convenience method which doesn't exist in the API, which copies the file and then waits for the copy to complete -func (c Client) CopyAndWait(ctx context.Context, shareName, path, fileName string, input CopyInput) (resp CopyResponse, err error) { - copy, e := c.Copy(ctx, shareName, path, fileName, input) +func (c Client) CopyAndWait(ctx context.Context, shareName, path, fileName string, input CopyInput) (result CopyResponse, err error) { + fileCopy, e := c.Copy(ctx, shareName, path, fileName, input) if err != nil { - resp.HttpResponse = copy.HttpResponse - err = fmt.Errorf("error copying: %s", e) + result.HttpResponse = fileCopy.HttpResponse + err = fmt.Errorf("copying: %s", e) return } - resp.CopyID = copy.CopyID + result.CopyID = fileCopy.CopyID pollerType := NewCopyAndWaitPoller(&c, shareName, path, fileName) poller := pollers.NewPoller(pollerType, 10*time.Second, pollers.DefaultNumberOfDroppedConnectionsToAllow) - if err := poller.PollUntilDone(ctx); err != nil { - return resp, fmt.Errorf("waiting for file to copy: %+v", err) + if err = poller.PollUntilDone(ctx); err != nil { + return result, fmt.Errorf("waiting for file to copy: %+v", err) } return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/create.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/create.go similarity index 88% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/create.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/create.go index 7c08a85bc1f1b..5fb8e97d2e8b3 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/create.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/create.go @@ -51,25 +51,29 @@ type CreateInput struct { } type CreateResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // Create creates a new file or replaces a file. -func (c Client) Create(ctx context.Context, shareName, path, fileName string, input CreateInput) (resp CreateResponse, err error) { +func (c Client) Create(ctx context.Context, shareName, path, fileName string, input CreateInput) (result CreateResponse, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + err = fmt.Errorf("`shareName` cannot be an empty string") + return } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + err = fmt.Errorf("`shareName` must be a lower-cased string") + return } if fileName == "" { - return resp, fmt.Errorf("`fileName` cannot be an empty string") + err = fmt.Errorf("`fileName` cannot be an empty string") + return } if err = metadata.Validate(input.MetaData); err != nil { - return resp, fmt.Errorf("`input.MetaData` is not valid: %s", err) + err = fmt.Errorf("`input.MetaData` is not valid: %s", err) + return } if path != "" { @@ -94,7 +98,11 @@ func (c Client) Create(ctx context.Context, shareName, path, fileName string, in return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/delete.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/delete.go similarity index 69% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/delete.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/delete.go index d5e32405038f6..f3841fa0427d8 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/delete.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/delete.go @@ -10,22 +10,25 @@ import ( ) type DeleteResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // Delete immediately deletes the file from the File Share. -func (c Client) Delete(ctx context.Context, shareName, path, fileName string) (resp DeleteResponse, err error) { +func (c Client) Delete(ctx context.Context, shareName, path, fileName string) (result DeleteResponse, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + err = fmt.Errorf("`shareName` cannot be an empty string") + return } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + err = fmt.Errorf("`shareName` must be a lower-cased string") + return } if fileName == "" { - return resp, fmt.Errorf("`fileName` cannot be an empty string") + err = fmt.Errorf("`fileName` cannot be an empty string") + return } if path != "" { @@ -48,7 +51,11 @@ func (c Client) Delete(ctx context.Context, shareName, path, fileName string) (r return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/metadata_get.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/metadata_get.go similarity index 73% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/metadata_get.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/metadata_get.go index 3e0fbad008adc..a4d1cc9ef5328 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/metadata_get.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/metadata_get.go @@ -12,23 +12,26 @@ import ( ) type GetMetaDataResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response MetaData map[string]string } // GetMetaData returns the MetaData for the specified File. -func (c Client) GetMetaData(ctx context.Context, shareName, path, fileName string) (resp GetMetaDataResponse, err error) { +func (c Client) GetMetaData(ctx context.Context, shareName, path, fileName string) (result GetMetaDataResponse, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + err = fmt.Errorf("`shareName` cannot be an empty string") + return } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + err = fmt.Errorf("`shareName` must be a lower-cased string") + return } if fileName == "" { - return resp, fmt.Errorf("`fileName` cannot be an empty string") + err = fmt.Errorf("`fileName` cannot be an empty string") + return } if path != "" { @@ -51,18 +54,20 @@ func (c Client) GetMetaData(ctx context.Context, shareName, path, fileName strin return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + if resp.Header != nil { + result.MetaData = metadata.ParseFromHeaders(resp.Header) + } + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return } - if resp.HttpResponse != nil { - if resp.HttpResponse.Header != nil { - resp.MetaData = metadata.ParseFromHeaders(resp.HttpResponse.Header) - } - } - return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/metadata_set.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/metadata_set.go similarity index 76% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/metadata_set.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/metadata_set.go index 4087ef58fdc7d..3a51a1086bfd9 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/metadata_set.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/metadata_set.go @@ -12,7 +12,7 @@ import ( ) type SetMetaDataResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } type SetMetaDataInput struct { @@ -20,21 +20,25 @@ type SetMetaDataInput struct { } // SetMetaData updates the specified File to have the specified MetaData. -func (c Client) SetMetaData(ctx context.Context, shareName, path, fileName string, input SetMetaDataInput) (resp SetMetaDataResponse, err error) { +func (c Client) SetMetaData(ctx context.Context, shareName, path, fileName string, input SetMetaDataInput) (result SetMetaDataResponse, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + err = fmt.Errorf("`shareName` cannot be an empty string") + return } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + err = fmt.Errorf("`shareName` must be a lower-cased string") + return } if fileName == "" { - return resp, fmt.Errorf("`fileName` cannot be an empty string") + err = fmt.Errorf("`fileName` cannot be an empty string") + return } if err = metadata.Validate(input.MetaData); err != nil { - return resp, fmt.Errorf("`input.MetaData` is not valid: %s", err) + err = fmt.Errorf("`input.MetaData` is not valid: %s", err) + return } if path != "" { @@ -59,7 +63,11 @@ func (c Client) SetMetaData(ctx context.Context, shareName, path, fileName strin return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/properties_get.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/properties_get.go new file mode 100644 index 0000000000000..2ea1f633efe83 --- /dev/null +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/properties_get.go @@ -0,0 +1,112 @@ +package files + +import ( + "context" + "fmt" + "net/http" + "strconv" + "strings" + + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/tombuildsstuff/giovanni/storage/internal/metadata" +) + +type GetResponse struct { + HttpResponse *http.Response + + CacheControl string + ContentDisposition string + ContentEncoding string + ContentLanguage string + ContentLength *int64 + ContentMD5 string + ContentType string + CopyID string + CopyStatus string + CopySource string + CopyProgress string + CopyStatusDescription string + CopyCompletionTime string + Encrypted bool + + MetaData map[string]string +} + +// GetProperties returns the Properties for the specified file +func (c Client) GetProperties(ctx context.Context, shareName, path, fileName string) (result GetResponse, err error) { + if shareName == "" { + err = fmt.Errorf("`shareName` cannot be an empty string") + return + } + + if strings.ToLower(shareName) != shareName { + err = fmt.Errorf("`shareName` must be a lower-cased string") + return + } + + if fileName == "" { + err = fmt.Errorf("`fileName` cannot be an empty string") + return + } + + if path != "" { + path = fmt.Sprintf("/%s/", path) + } + + opts := client.RequestOptions{ + ContentType: "application/xml; charset=utf-8", + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodHead, + OptionsObject: nil, + Path: fmt.Sprintf("%s/%s%s", shareName, path, fileName), + } + + req, err := c.Client.NewRequest(ctx, opts) + if err != nil { + err = fmt.Errorf("building request: %+v", err) + return + } + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + if resp.Header != nil { + result.CacheControl = resp.Header.Get("Cache-Control") + result.ContentDisposition = resp.Header.Get("Content-Disposition") + result.ContentEncoding = resp.Header.Get("Content-Encoding") + result.ContentLanguage = resp.Header.Get("Content-Language") + result.ContentMD5 = resp.Header.Get("Content-MD5") + result.ContentType = resp.Header.Get("Content-Type") + result.CopyCompletionTime = resp.Header.Get("x-ms-copy-completion-time") + result.CopyID = resp.Header.Get("x-ms-copy-id") + result.CopyProgress = resp.Header.Get("x-ms-copy-progress") + result.CopySource = resp.Header.Get("x-ms-copy-source") + result.CopyStatus = resp.Header.Get("x-ms-copy-status") + result.CopyStatusDescription = resp.Header.Get("x-ms-copy-status-description") + result.Encrypted = strings.EqualFold(resp.Header.Get("x-ms-server-encrypted"), "true") + result.MetaData = metadata.ParseFromHeaders(resp.Header) + + contentLengthRaw := resp.Header.Get("Content-Length") + if contentLengthRaw != "" { + var contentLength int + contentLength, err = strconv.Atoi(contentLengthRaw) + if err != nil { + err = fmt.Errorf("parsing `Content-Length` header value %q: %s", contentLengthRaw, err) + return + } + contentLengthI64 := int64(contentLength) + result.ContentLength = &contentLengthI64 + } + } + } + if err != nil { + err = fmt.Errorf("executing request: %+v", err) + return + } + + return +} diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/properties_set.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/properties_set.go similarity index 92% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/properties_set.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/properties_set.go index 0e2c547a8d962..83bd84118eb5e 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/properties_set.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/properties_set.go @@ -68,21 +68,24 @@ type SetPropertiesInput struct { } type SetPropertiesResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // SetProperties sets the specified properties on the specified File -func (c Client) SetProperties(ctx context.Context, shareName, path, fileName string, input SetPropertiesInput) (resp SetPropertiesResponse, err error) { +func (c Client) SetProperties(ctx context.Context, shareName, path, fileName string, input SetPropertiesInput) (result SetPropertiesResponse, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + err = fmt.Errorf("`shareName` cannot be an empty string") + return } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + err = fmt.Errorf("`shareName` must be a lower-cased string") + return } if fileName == "" { - return resp, fmt.Errorf("`fileName` cannot be an empty string") + err = fmt.Errorf("`fileName` cannot be an empty string") + return } if path != "" { @@ -107,7 +110,11 @@ func (c Client) SetProperties(ctx context.Context, shareName, path, fileName str return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/range_clear.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/range_clear.go similarity index 73% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/range_clear.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/range_clear.go index c2391a1c9c041..0a1e8149ed730 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/range_clear.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/range_clear.go @@ -16,30 +16,35 @@ type ClearByteRangeInput struct { } type ClearByteRangeResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // ClearByteRange clears the specified Byte Range from within the specified File -func (c Client) ClearByteRange(ctx context.Context, shareName, path, fileName string, input ClearByteRangeInput) (resp ClearByteRangeResponse, err error) { +func (c Client) ClearByteRange(ctx context.Context, shareName, path, fileName string, input ClearByteRangeInput) (result ClearByteRangeResponse, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + err = fmt.Errorf("`shareName` cannot be an empty string") + return } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + err = fmt.Errorf("`shareName` must be a lower-cased string") + return } if fileName == "" { - return resp, fmt.Errorf("`fileName` cannot be an empty string") + err = fmt.Errorf("`fileName` cannot be an empty string") + return } if input.StartBytes < 0 { - return resp, fmt.Errorf("`input.StartBytes` must be greater or equal to 0") + err = fmt.Errorf("`input.StartBytes` must be greater or equal to 0") + return } if input.EndBytes <= 0 { - return resp, fmt.Errorf("`input.EndBytes` must be greater than 0") + err = fmt.Errorf("`input.EndBytes` must be greater than 0") + return } if path != "" { @@ -64,7 +69,11 @@ func (c Client) ClearByteRange(ctx context.Context, shareName, path, fileName st return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/range_get.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/range_get.go similarity index 65% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/range_get.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/range_get.go index 90a1089b3798d..f8b40b87d1a70 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/range_get.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/range_get.go @@ -3,7 +3,6 @@ package files import ( "context" "fmt" - "io" "net/http" "strings" @@ -17,40 +16,46 @@ type GetByteRangeInput struct { } type GetByteRangeResponse struct { - HttpResponse *client.Response - - Contents []byte + HttpResponse *http.Response + Contents *[]byte } // GetByteRange returns the specified Byte Range from the specified File. -func (c Client) GetByteRange(ctx context.Context, shareName, path, fileName string, input GetByteRangeInput) (resp GetByteRangeResponse, err error) { +func (c Client) GetByteRange(ctx context.Context, shareName, path, fileName string, input GetByteRangeInput) (result GetByteRangeResponse, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + err = fmt.Errorf("`shareName` cannot be an empty string") + return } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + err = fmt.Errorf("`shareName` must be a lower-cased string") + return } if fileName == "" { - return resp, fmt.Errorf("`fileName` cannot be an empty string") + err = fmt.Errorf("`fileName` cannot be an empty string") + return } if input.StartBytes < 0 { - return resp, fmt.Errorf("`input.StartBytes` must be greater or equal to 0") + err = fmt.Errorf("`input.StartBytes` must be greater or equal to 0") + return } if input.EndBytes <= 0 { - return resp, fmt.Errorf("`input.EndBytes` must be greater than 0") + err = fmt.Errorf("`input.EndBytes` must be greater than 0") + return } expectedBytes := input.EndBytes - input.StartBytes if expectedBytes < (4 * 1024) { - return resp, fmt.Errorf("requested Byte Range must be at least 4KB") + err = fmt.Errorf("requested Byte Range must be at least 4KB") + return } if expectedBytes > (4 * 1024 * 1024) { - return resp, fmt.Errorf("requested Byte Range must be at most 4MB") + err = fmt.Errorf("requested Byte Range must be at most 4MB") + return } if path != "" { @@ -75,18 +80,21 @@ func (c Client) GetByteRange(ctx context.Context, shareName, path, fileName stri return } - resp.HttpResponse, err = req.Execute(ctx) - if err != nil { - err = fmt.Errorf("executing request: %+v", err) - return - } + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.Contents = &[]byte{} + result.HttpResponse = resp.Response - if resp.HttpResponse != nil { - bytes, err := io.ReadAll(resp.HttpResponse.Body) + err = resp.Unmarshal(result.Contents) if err != nil { - return resp, fmt.Errorf("reading response body: %v", err) + err = fmt.Errorf("unmarshalling response: %+v", err) + return } - resp.Contents = bytes + } + if err != nil { + err = fmt.Errorf("executing request: %+v", err) + return } return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/range_get_file.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/range_get_file.go similarity index 89% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/range_get_file.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/range_get_file.go index f81852604283b..e923eb31f3b0f 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/range_get_file.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/range_get_file.go @@ -5,10 +5,9 @@ import ( "fmt" "log" "math" + "net/http" "runtime" "sync" - - "github.com/hashicorp/go-azure-sdk/sdk/client" ) type GetFileInput struct { @@ -16,18 +15,17 @@ type GetFileInput struct { } type GetFileResponse struct { - HttpResponse *client.Response - - OutputBytes []byte + HttpResponse *http.Response + OutputBytes *[]byte } // GetFile is a helper method to download a file by chunking it automatically -func (c Client) GetFile(ctx context.Context, shareName, path, fileName string, input GetFileInput) (resp GetFileResponse, err error) { +func (c Client) GetFile(ctx context.Context, shareName, path, fileName string, input GetFileInput) (result GetFileResponse, err error) { // first look up the file and check out how many bytes it is file, e := c.GetProperties(ctx, shareName, path, fileName) if err != nil { - resp.HttpResponse = file.HttpResponse + result.HttpResponse = file.HttpResponse err = e return } @@ -37,7 +35,7 @@ func (c Client) GetFile(ctx context.Context, shareName, path, fileName string, i return } - resp.HttpResponse = file.HttpResponse + result.HttpResponse = file.HttpResponse length := *file.ContentLength chunkSize := int64(4 * 1024 * 1024) // 4MB @@ -92,10 +90,10 @@ func (c Client) GetFile(ctx context.Context, shareName, path, fileName string, i // then finally put it all together, in order and return it output := make([]byte, length) for _, v := range results { - copy(output[v.startBytes:v.endBytes], v.bytes) + copy(output[v.startBytes:v.endBytes], *v.bytes) } - resp.OutputBytes = output + *result.OutputBytes = output return } @@ -108,7 +106,7 @@ type downloadFileChunkInput struct { type downloadFileChunkResult struct { startBytes int64 endBytes int64 - bytes []byte + bytes *[]byte } func (c Client) downloadFileChunk(ctx context.Context, shareName, path, fileName string, input downloadFileChunkInput) (*downloadFileChunkResult, error) { diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/range_put.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/range_put.go similarity index 71% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/range_put.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/range_put.go index 7588f8b4131e4..58e6f9bb0cff9 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/range_put.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/range_put.go @@ -23,39 +23,45 @@ type PutByteRangeInput struct { } type PutRangeResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // PutByteRange puts the specified Byte Range in the specified File. -func (c Client) PutByteRange(ctx context.Context, shareName, path, fileName string, input PutByteRangeInput) (resp PutRangeResponse, err error) { - +func (c Client) PutByteRange(ctx context.Context, shareName, path, fileName string, input PutByteRangeInput) (result PutRangeResponse, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + err = fmt.Errorf("`shareName` cannot be an empty string") + return } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + err = fmt.Errorf("`shareName` must be a lower-cased string") + return } if fileName == "" { - return resp, fmt.Errorf("`fileName` cannot be an empty string") + err = fmt.Errorf("`fileName` cannot be an empty string") + return } if input.StartBytes < 0 { - return resp, fmt.Errorf("`input.StartBytes` must be greater or equal to 0") + err = fmt.Errorf("`input.StartBytes` must be greater or equal to 0") + return } if input.EndBytes <= 0 { - return resp, fmt.Errorf("`input.EndBytes` must be greater than 0") + err = fmt.Errorf("`input.EndBytes` must be greater than 0") + return } expectedBytes := input.EndBytes - input.StartBytes actualBytes := len(input.Content) if expectedBytes != int64(actualBytes) { - return resp, fmt.Errorf(fmt.Sprintf("The specified byte-range (%d) didn't match the content size (%d).", expectedBytes, actualBytes)) + err = fmt.Errorf(fmt.Sprintf("The specified byte-range (%d) didn't match the content size (%d).", expectedBytes, actualBytes)) + return } if expectedBytes > (4 * 1024 * 1024) { - return resp, fmt.Errorf("specified Byte Range must be at most 4MB") + err = fmt.Errorf("specified Byte Range must be at most 4MB") + return } if path != "" { @@ -82,7 +88,11 @@ func (c Client) PutByteRange(ctx context.Context, shareName, path, fileName stri req.Body = io.NopCloser(bytes.NewReader(input.Content)) req.ContentLength = int64(len(input.Content)) - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/range_put_file.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/range_put_file.go similarity index 93% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/range_put_file.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/range_put_file.go index 16cb68719311b..660122c1aa8f8 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/range_put_file.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/range_put_file.go @@ -16,7 +16,6 @@ func (c Client) PutFile(ctx context.Context, shareName, path, fileName string, f if err != nil { return fmt.Errorf("error loading file info: %s", err) } - if fileInfo.Size() == 0 { return fmt.Errorf("file is empty which is not supported") } @@ -67,7 +66,7 @@ func (c Client) PutFile(ctx context.Context, shareName, path, fileName string, f // TODO: we should switch to hashicorp/multi-error here if len(errors) > 0 { - return fmt.Errorf("Error uploading file: %s", <-errors) + return fmt.Errorf("uploading file: %s", <-errors) } return nil @@ -95,7 +94,7 @@ func (c Client) uploadChunk(ctx context.Context, shareName, path, fileName strin _, err = file.ReadAt(bytes, startBytes) if err != nil { if err != io.EOF { - return result, fmt.Errorf("Error reading bytes: %s", err) + return result, fmt.Errorf("reading bytes: %s", err) } } @@ -106,7 +105,7 @@ func (c Client) uploadChunk(ctx context.Context, shareName, path, fileName strin } result, err = c.PutByteRange(ctx, shareName, path, fileName, putBytesInput) if err != nil { - return result, fmt.Errorf("error putting bytes: %s", err) + return result, fmt.Errorf("putting bytes: %s", err) } return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/ranges_list.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/ranges_list.go similarity index 70% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/ranges_list.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/ranges_list.go index 9a67cab828573..0b89e6c1a1102 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/ranges_list.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/ranges_list.go @@ -11,7 +11,7 @@ import ( ) type ListRangesResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response Ranges []Range `xml:"Range"` } @@ -22,22 +22,25 @@ type Range struct { } // ListRanges returns the list of valid ranges for the specified File. -func (c Client) ListRanges(ctx context.Context, shareName, path, fileName string) (resp ListRangesResponse, err error) { - +func (c Client) ListRanges(ctx context.Context, shareName, path, fileName string) (result ListRangesResponse, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + err = fmt.Errorf("`shareName` cannot be an empty string") + return } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + err = fmt.Errorf("`shareName` must be a lower-cased string") + return } if path == "" { - return resp, fmt.Errorf("`path` cannot be an empty string") + err = fmt.Errorf("`path` cannot be an empty string") + return } if fileName == "" { - return resp, fmt.Errorf("`fileName` cannot be an empty string") + err = fmt.Errorf("`fileName` cannot be an empty string") + return } if path != "" { @@ -60,16 +63,22 @@ func (c Client) ListRanges(ctx context.Context, shareName, path, fileName string return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + err = resp.Unmarshal(&result) + if err != nil { + err = fmt.Errorf("unmarshalling response: %+v", err) + return + } + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return } - if resp.HttpResponse != nil { - resp.HttpResponse.Unmarshal(&resp) - } - return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/resource_id.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/resource_id.go similarity index 97% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/resource_id.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/resource_id.go index b29471c87e326..492889780e31d 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/resource_id.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/resource_id.go @@ -6,7 +6,7 @@ import ( "strings" "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts" ) // TODO: update this to implement `resourceids.ResourceId` once diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/version.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/version.go similarity index 60% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/version.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/version.go index 5b70f293ad019..1d4bc38bea91a 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files/version.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files/version.go @@ -1,4 +1,4 @@ package files -const apiVersion = "2020-08-04" +const apiVersion = "2023-11-03" const componentName = "file/files" diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/README.md b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/README.md similarity index 90% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/README.md rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/README.md index 68b41e2d5e492..5ec0fb4f8fc08 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/README.md +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/README.md @@ -1,4 +1,4 @@ -## File Storage Shares SDK for API version 2020-08-04 +## File Storage Shares SDK for API version 2023-11-03 This package allows you to interact with the Shares File Storage API @@ -17,7 +17,7 @@ import ( "fmt" "github.com/hashicorp/go-azure-sdk/sdk/auth" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares" ) func Example() error { diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/acl_get.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/acl_get.go similarity index 75% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/acl_get.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/acl_get.go index 56aa6413d4b80..8add483a5e3ef 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/acl_get.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/acl_get.go @@ -11,19 +11,20 @@ import ( ) type GetACLResult struct { - HttpResponse *client.Response + HttpResponse *http.Response SignedIdentifiers []SignedIdentifier `xml:"SignedIdentifier"` } // GetACL get the Access Control List for the specified Storage Share -func (c Client) GetACL(ctx context.Context, shareName string) (resp GetACLResult, err error) { - +func (c Client) GetACL(ctx context.Context, shareName string) (result GetACLResult, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + err = fmt.Errorf("`shareName` cannot be an empty string") + return } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + err = fmt.Errorf("`shareName` must be a lower-cased string") + return } opts := client.RequestOptions{ @@ -42,18 +43,22 @@ func (c Client) GetACL(ctx context.Context, shareName string) (resp GetACLResult return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + err = resp.Unmarshal(&result) + if err != nil { + err = fmt.Errorf("unmarshalling response: %+v", err) + return + } + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return } - if resp.HttpResponse != nil { - err = resp.HttpResponse.Unmarshal(&resp) - if err != nil { - return resp, fmt.Errorf("unmarshalling response: %v", err) - } - } return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/acl_set.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/acl_set.go similarity index 78% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/acl_set.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/acl_set.go index 33b7c84a47d01..216d714eb2ac6 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/acl_set.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/acl_set.go @@ -15,24 +15,24 @@ import ( ) type SetAclResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } type SetAclInput struct { SignedIdentifiers []SignedIdentifier `xml:"SignedIdentifier"` - - XMLName xml.Name `xml:"SignedIdentifiers"` + XMLName xml.Name `xml:"SignedIdentifiers"` } // SetACL sets the specified Access Control List on the specified Storage Share -func (c Client) SetACL(ctx context.Context, shareName string, input SetAclInput) (resp SetAclResponse, err error) { - +func (c Client) SetACL(ctx context.Context, shareName string, input SetAclInput) (result SetAclResponse, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + err = fmt.Errorf("`shareName` cannot be an empty string") + return } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + err = fmt.Errorf("`shareName` must be a lower-cased string") + return } opts := client.RequestOptions{ @@ -53,7 +53,8 @@ func (c Client) SetACL(ctx context.Context, shareName string, input SetAclInput) b, err := xml.Marshal(&input) if err != nil { - return resp, fmt.Errorf("marshalling input: %v", err) + err = fmt.Errorf("marshalling input: %+v", err) + return } withHeader := xml.Header + string(b) bytesWithHeader := []byte(withHeader) @@ -61,11 +62,16 @@ func (c Client) SetACL(ctx context.Context, shareName string, input SetAclInput) req.Header.Set("Content-Length", strconv.Itoa(len(bytesWithHeader))) req.Body = io.NopCloser(bytes.NewReader(bytesWithHeader)) - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return } + return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/api.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/api.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/api.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/api.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/client.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/client.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/client.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/client.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/create.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/create.go similarity index 62% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/create.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/create.go index b0184600af0e0..46e8757466fc6 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/create.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/create.go @@ -1,12 +1,16 @@ package shares import ( + "bytes" "context" + "encoding/xml" "fmt" + "io" "net/http" "strconv" "strings" + "github.com/hashicorp/go-azure-helpers/lang/response" "github.com/hashicorp/go-azure-sdk/sdk/client" "github.com/hashicorp/go-azure-sdk/sdk/odata" "github.com/tombuildsstuff/giovanni/storage/internal/metadata" @@ -36,26 +40,54 @@ type CreateInput struct { } type CreateResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // Create creates the specified Storage Share within the specified Storage Account -func (c Client) Create(ctx context.Context, shareName string, input CreateInput) (resp CreateResponse, err error) { +func (c Client) Create(ctx context.Context, shareName string, input CreateInput) (result CreateResponse, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + err = fmt.Errorf("`shareName` cannot be an empty string") + return } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + err = fmt.Errorf("`shareName` must be a lower-cased string") + return } if input.QuotaInGB <= 0 || input.QuotaInGB > 102400 { - return resp, fmt.Errorf("`input.QuotaInGB` must be greater than 0, and less than/equal to 100TB (102400 GB)") + err = fmt.Errorf("`input.QuotaInGB` must be greater than 0, and less than/equal to 100TB (102400 GB)") + return } if err = metadata.Validate(input.MetaData); err != nil { - return resp, fmt.Errorf("`input.MetaData` is not valid: %s", err) + err = fmt.Errorf("`input.MetaData` is not valid: %s", err) + return + } + + // Retry the share creation if a conflicting share is still in the process of being deleted + retryFunc := func(resp *http.Response, _ *odata.OData) (bool, error) { + if resp != nil { + if response.WasStatusCode(resp, http.StatusConflict) { + // TODO: move this error response parsing to a common helper function + respBody, err := io.ReadAll(resp.Body) + if err != nil { + return false, fmt.Errorf("could not parse response body") + } + resp.Body.Close() + respBody = bytes.TrimPrefix(respBody, []byte("\xef\xbb\xbf")) + res := ErrorResponse{} + if err = xml.Unmarshal(respBody, &res); err != nil { + return false, err + } + resp.Body = io.NopCloser(bytes.NewBuffer(respBody)) + if res.Code != nil { + return strings.Contains(*res.Code, "ShareBeingDeleted"), nil + } + } + } + return false, nil } opts := client.RequestOptions{ @@ -67,18 +99,25 @@ func (c Client) Create(ctx context.Context, shareName string, input CreateInput) OptionsObject: CreateOptions{ input: input, }, - Path: fmt.Sprintf("/%s", shareName), + Path: fmt.Sprintf("/%s", shareName), + RetryFunc: retryFunc, } req, err := c.Client.NewRequest(ctx, opts) if err != nil { err = fmt.Errorf("building request: %+v", err) return } - resp.HttpResponse, err = req.Execute(ctx) + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return } + return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/delete.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/delete.go similarity index 80% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/delete.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/delete.go index 7ae11b3dbef3f..84667f68a3efa 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/delete.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/delete.go @@ -11,7 +11,7 @@ import ( ) type DeleteResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } type DeleteInput struct { @@ -19,13 +19,15 @@ type DeleteInput struct { } // Delete deletes the specified Storage Share from within a Storage Account -func (c Client) Delete(ctx context.Context, shareName string, input DeleteInput) (resp DeleteResponse, err error) { +func (c Client) Delete(ctx context.Context, shareName string, input DeleteInput) (result DeleteResponse, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + err = fmt.Errorf("`shareName` cannot be an empty string") + return } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + err = fmt.Errorf("`shareName` must be a lower-cased string") + return } opts := client.RequestOptions{ @@ -45,7 +47,11 @@ func (c Client) Delete(ctx context.Context, shareName string, input DeleteInput) return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/metadata_get.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/metadata_get.go similarity index 76% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/metadata_get.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/metadata_get.go index e31762bd2d8a3..eeb8b4d1e7dcf 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/metadata_get.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/metadata_get.go @@ -12,18 +12,18 @@ import ( ) type GetMetaDataResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response MetaData map[string]string } // GetMetaData returns the MetaData associated with the specified Storage Share -func (c Client) GetMetaData(ctx context.Context, shareName string) (resp GetMetaDataResponse, err error) { +func (c Client) GetMetaData(ctx context.Context, shareName string) (result GetMetaDataResponse, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + return result, fmt.Errorf("`shareName` cannot be an empty string") } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + return result, fmt.Errorf("`shareName` must be a lower-cased string") } opts := client.RequestOptions{ @@ -42,18 +42,20 @@ func (c Client) GetMetaData(ctx context.Context, shareName string) (resp GetMeta return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + if resp.Header != nil { + result.MetaData = metadata.ParseFromHeaders(resp.Header) + } + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return } - if resp.HttpResponse != nil { - if resp.HttpResponse.Header != nil { - resp.MetaData = metadata.ParseFromHeaders(resp.HttpResponse.Header) - } - } - return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/metadata_set.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/metadata_set.go similarity index 75% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/metadata_set.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/metadata_set.go index 3a23d90e780f5..55bf1d4bedfce 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/metadata_set.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/metadata_set.go @@ -12,7 +12,7 @@ import ( ) type SetMetaDataResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } type SetMetaDataInput struct { @@ -20,18 +20,21 @@ type SetMetaDataInput struct { } // SetMetaData sets the MetaData on the specified Storage Share -func (c Client) SetMetaData(ctx context.Context, shareName string, input SetMetaDataInput) (resp SetMetaDataResponse, err error) { +func (c Client) SetMetaData(ctx context.Context, shareName string, input SetMetaDataInput) (result SetMetaDataResponse, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + err = fmt.Errorf("`shareName` cannot be an empty string") + return } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + err = fmt.Errorf("`shareName` must be a lower-cased string") + return } - if err := metadata.Validate(input.MetaData); err != nil { - return resp, fmt.Errorf("`metadata` is not valid: %v", err) + if err = metadata.Validate(input.MetaData); err != nil { + err = fmt.Errorf("`metadata` is not valid: %+v", err) + return } opts := client.RequestOptions{ @@ -52,7 +55,11 @@ func (c Client) SetMetaData(ctx context.Context, shareName string, input SetMeta return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/models.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/models.go similarity index 78% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/models.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/models.go index 32727164cc835..61c3be66ae478 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/models.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/models.go @@ -1,5 +1,7 @@ package shares +import "encoding/xml" + type SignedIdentifier struct { Id string `xml:"Id"` AccessPolicy AccessPolicy `xml:"AccessPolicy"` @@ -20,3 +22,9 @@ const ( // NFS indicates the share can be accessed by NFSv4.1. A premium account is required for this option. NFS ShareProtocol = "NFS" ) + +type ErrorResponse struct { + XMLName xml.Name `xml:"Error"` + Code *string `xml:"Code"` + Message *string `xml:"Message"` +} diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/options.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/options.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/options.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/options.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/properties_get.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/properties_get.go similarity index 59% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/properties_get.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/properties_get.go index 763584ef648b4..fb153628fd092 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/properties_get.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/properties_get.go @@ -12,7 +12,7 @@ import ( ) type GetPropertiesResult struct { - HttpResponse *client.Response + HttpResponse *http.Response MetaData map[string]string QuotaInGB int @@ -21,13 +21,15 @@ type GetPropertiesResult struct { } // GetProperties returns the properties about the specified Storage Share -func (c Client) GetProperties(ctx context.Context, shareName string) (resp GetPropertiesResult, err error) { +func (c Client) GetProperties(ctx context.Context, shareName string) (result GetPropertiesResult, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + err = fmt.Errorf("`shareName` cannot be an empty string") + return } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + err = fmt.Errorf("`shareName` must be a lower-cased string") + return } opts := client.RequestOptions{ @@ -46,37 +48,40 @@ func (c Client) GetProperties(ctx context.Context, shareName string) (resp GetPr return } - resp.HttpResponse, err = req.Execute(ctx) - if err != nil { - err = fmt.Errorf("executing request: %+v", err) - return - } + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response - if resp.HttpResponse != nil { - if resp.HttpResponse.Header != nil { - resp.MetaData = metadata.ParseFromHeaders(resp.HttpResponse.Header) + if resp.Header != nil { + result.MetaData = metadata.ParseFromHeaders(resp.Header) - quotaRaw := resp.HttpResponse.Header.Get("x-ms-share-quota") + quotaRaw := resp.Header.Get("x-ms-share-quota") if quotaRaw != "" { quota, e := strconv.Atoi(quotaRaw) if e != nil { - return resp, fmt.Errorf("error converting %q to an integer: %s", quotaRaw, err) + err = fmt.Errorf("error converting %q to an integer: %s", quotaRaw, err) + return } - resp.QuotaInGB = quota + result.QuotaInGB = quota } protocol := SMB - if protocolRaw := resp.HttpResponse.Header.Get("x-ms-enabled-protocols"); protocolRaw != "" { + if protocolRaw := resp.Header.Get("x-ms-enabled-protocols"); protocolRaw != "" { protocol = ShareProtocol(protocolRaw) } - if accessTierRaw := resp.HttpResponse.Header.Get("x-ms-access-tier"); accessTierRaw != "" { + if accessTierRaw := resp.Header.Get("x-ms-access-tier"); accessTierRaw != "" { tier := AccessTier(accessTierRaw) - resp.AccessTier = &tier + result.AccessTier = &tier } - resp.EnabledProtocol = protocol + result.EnabledProtocol = protocol } } + if err != nil { + err = fmt.Errorf("executing request: %+v", err) + return + } return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/properties_set.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/properties_set.go similarity index 78% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/properties_set.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/properties_set.go index ef3854af6de92..f80df4fdce1c6 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/properties_set.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/properties_set.go @@ -17,22 +17,22 @@ type ShareProperties struct { } type SetPropertiesResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // SetProperties lets you update the Quota for the specified Storage Share -func (c Client) SetProperties(ctx context.Context, shareName string, properties ShareProperties) (resp SetPropertiesResponse, err error) { +func (c Client) SetProperties(ctx context.Context, shareName string, properties ShareProperties) (result SetPropertiesResponse, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + return result, fmt.Errorf("`shareName` cannot be an empty string") } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + return result, fmt.Errorf("`shareName` must be a lower-cased string") } if newQuotaGB := properties.QuotaInGb; newQuotaGB != nil && (*newQuotaGB <= 0 || *newQuotaGB > 102400) { - return resp, fmt.Errorf("`newQuotaGB` must be greater than 0, and less than/equal to 100TB (102400 GB)") + return result, fmt.Errorf("`newQuotaGB` must be greater than 0, and less than/equal to 100TB (102400 GB)") } opts := client.RequestOptions{ @@ -53,7 +53,11 @@ func (c Client) SetProperties(ctx context.Context, shareName string, properties return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/resource_id.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/resource_id.go similarity index 97% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/resource_id.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/resource_id.go index 73b93bd707688..c46092b4400f7 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/resource_id.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/resource_id.go @@ -6,7 +6,7 @@ import ( "strings" "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts" ) // GetResourceManagerResourceID returns the Resource Manager specific diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/snapshot_create.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/snapshot_create.go similarity index 79% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/snapshot_create.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/snapshot_create.go index 8ba7a07c7b4a8..d4dff0328043f 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/snapshot_create.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/snapshot_create.go @@ -16,7 +16,7 @@ type CreateSnapshotInput struct { } type CreateSnapshotResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response // This header is a DateTime value that uniquely identifies the share snapshot. // The value of this header may be used in subsequent requests to access the share snapshot. @@ -27,18 +27,21 @@ type CreateSnapshotResponse struct { // CreateSnapshot creates a read-only snapshot of the share // A share can support creation of 200 share snapshots. Attempting to create more than 200 share snapshots fails with 409 (Conflict). // Attempting to create a share snapshot while a previous Snapshot Share operation is in progress fails with 409 (Conflict). -func (c Client) CreateSnapshot(ctx context.Context, shareName string, input CreateSnapshotInput) (resp CreateSnapshotResponse, err error) { +func (c Client) CreateSnapshot(ctx context.Context, shareName string, input CreateSnapshotInput) (result CreateSnapshotResponse, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + err = fmt.Errorf("`shareName` cannot be an empty string") + return } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + err = fmt.Errorf("`shareName` must be a lower-cased string") + return } if err = metadata.Validate(input.MetaData); err != nil { - return resp, fmt.Errorf("`input.MetaData` is not valid: %v", err) + err = fmt.Errorf("`input.MetaData` is not valid: %+v", err) + return } opts := client.RequestOptions{ @@ -59,17 +62,20 @@ func (c Client) CreateSnapshot(ctx context.Context, shareName string, input Crea return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + if resp.Header != nil { + result.SnapshotDateTime = resp.Header.Get("x-ms-snapshot") + } + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return } - if resp.HttpResponse != nil { - if resp.HttpResponse.Header != nil { - resp.SnapshotDateTime = resp.HttpResponse.Header.Get("x-ms-snapshot") - } - } return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/snapshot_delete.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/snapshot_delete.go similarity index 75% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/snapshot_delete.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/snapshot_delete.go index bf3ccd6719a68..64dd532068a03 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/snapshot_delete.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/snapshot_delete.go @@ -11,22 +11,22 @@ import ( ) type DeleteSnapshotResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // DeleteSnapshot deletes the specified Snapshot of a Storage Share -func (c Client) DeleteSnapshot(ctx context.Context, accountName, shareName string, shareSnapshot string) (resp DeleteSnapshotResponse, err error) { +func (c Client) DeleteSnapshot(ctx context.Context, accountName, shareName string, shareSnapshot string) (result DeleteSnapshotResponse, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + return result, fmt.Errorf("`shareName` cannot be an empty string") } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + return result, fmt.Errorf("`shareName` must be a lower-cased string") } if shareSnapshot == "" { - return resp, fmt.Errorf("`shareSnapshot` cannot be an empty string") + return result, fmt.Errorf("`shareSnapshot` cannot be an empty string") } opts := client.RequestOptions{ @@ -47,7 +47,11 @@ func (c Client) DeleteSnapshot(ctx context.Context, accountName, shareName strin return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/snapshot_get.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/snapshot_get.go similarity index 74% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/snapshot_get.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/snapshot_get.go index f4a12e9f0cdc5..e4aee485b0163 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/snapshot_get.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/snapshot_get.go @@ -12,7 +12,7 @@ import ( ) type GetSnapshotPropertiesResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response MetaData map[string]string } @@ -22,17 +22,20 @@ type GetSnapshotPropertiesInput struct { } // GetSnapshot gets information about the specified Snapshot of the specified Storage Share -func (c Client) GetSnapshot(ctx context.Context, shareName string, input GetSnapshotPropertiesInput) (resp GetSnapshotPropertiesResponse, err error) { +func (c Client) GetSnapshot(ctx context.Context, shareName string, input GetSnapshotPropertiesInput) (result GetSnapshotPropertiesResponse, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + err = fmt.Errorf("`shareName` cannot be an empty string") + return } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + err = fmt.Errorf("`shareName` must be a lower-cased string") + return } if input.snapshotShare == "" { - return resp, fmt.Errorf("`snapshotShare` cannot be an empty string") + err = fmt.Errorf("`snapshotShare` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -53,18 +56,20 @@ func (c Client) GetSnapshot(ctx context.Context, shareName string, input GetSnap return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + if resp.Header != nil { + result.MetaData = metadata.ParseFromHeaders(resp.Header) + } + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return } - if resp.HttpResponse != nil { - if resp.HttpResponse.Header != nil { - resp.MetaData = metadata.ParseFromHeaders(resp.HttpResponse.Header) - } - } - return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/stats.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/stats.go similarity index 76% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/stats.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/stats.go index 23e48afe40433..d375d837ed7e8 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/stats.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/stats.go @@ -11,7 +11,7 @@ import ( ) type GetStatsResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response // The approximate size of the data stored on the share. // Note that this value may not include all recently created or recently resized files. @@ -19,13 +19,15 @@ type GetStatsResponse struct { } // GetStats returns information about the specified Storage Share -func (c Client) GetStats(ctx context.Context, shareName string) (resp GetStatsResponse, err error) { +func (c Client) GetStats(ctx context.Context, shareName string) (result GetStatsResponse, err error) { if shareName == "" { - return resp, fmt.Errorf("`shareName` cannot be an empty string") + err = fmt.Errorf("`shareName` cannot be an empty string") + return } if strings.ToLower(shareName) != shareName { - return resp, fmt.Errorf("`shareName` must be a lower-cased string") + err = fmt.Errorf("`shareName` must be a lower-cased string") + return } opts := client.RequestOptions{ @@ -44,18 +46,22 @@ func (c Client) GetStats(ctx context.Context, shareName string) (resp GetStatsRe return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + err = resp.Unmarshal(&result) + if err != nil { + err = fmt.Errorf("unmarshalling response: %+v", err) + return + } + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return } - if resp.HttpResponse != nil { - err = resp.HttpResponse.Unmarshal(&resp) - if err != nil { - return resp, fmt.Errorf("unmarshalling response: %v", err) - } - } return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/version.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/version.go similarity index 61% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/version.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/version.go index a3c5b6d501703..6f62a9bdaf858 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares/version.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares/version.go @@ -1,4 +1,4 @@ package shares -const apiVersion = "2020-08-04" +const apiVersion = "2023-11-03" const componentName = "file/shares" diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/README.md b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/README.md similarity index 91% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/README.md rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/README.md index 7c9fd1a3c6ec5..745cc6d70ca51 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/README.md +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/README.md @@ -1,4 +1,4 @@ -## Queue Storage Queues SDK for API version 2020-08-04 +## Queue Storage Queues SDK for API version 2023-11-03 This package allows you to interact with the Queues Queue Storage API @@ -17,7 +17,7 @@ import ( "fmt" "github.com/hashicorp/go-azure-sdk/sdk/auth" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues" ) func Example() error { diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/api.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/api.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/api.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/api.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/client.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/client.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/client.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/client.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/create.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/create.go similarity index 78% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/create.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/create.go index d156052ca70d7..f548088ce288f 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/create.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/create.go @@ -16,22 +16,22 @@ type CreateInput struct { } type CreateResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // Create creates the specified Queue within the specified Storage Account -func (c Client) Create(ctx context.Context, queueName string, input CreateInput) (resp CreateResponse, err error) { +func (c Client) Create(ctx context.Context, queueName string, input CreateInput) (result CreateResponse, err error) { if queueName == "" { - return resp, fmt.Errorf("`queueName` cannot be an empty string") + return result, fmt.Errorf("`queueName` cannot be an empty string") } if strings.ToLower(queueName) != queueName { - return resp, fmt.Errorf("`queueName` must be a lower-cased string") + return result, fmt.Errorf("`queueName` must be a lower-cased string") } if err := metadata.Validate(input.MetaData); err != nil { - return resp, fmt.Errorf("`metadata` is not valid: %s", err) + return result, fmt.Errorf("`metadata` is not valid: %s", err) } opts := client.RequestOptions{ @@ -52,7 +52,11 @@ func (c Client) Create(ctx context.Context, queueName string, input CreateInput) return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/delete.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/delete.go similarity index 72% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/delete.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/delete.go index 39d5d64fa0598..e8d7babb12fe1 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/delete.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/delete.go @@ -10,18 +10,18 @@ import ( ) type DeleteResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // Delete deletes the specified Queue within the specified Storage Account -func (c Client) Delete(ctx context.Context, queueName string) (resp DeleteResponse, err error) { +func (c Client) Delete(ctx context.Context, queueName string) (result DeleteResponse, err error) { if queueName == "" { - return resp, fmt.Errorf("`queueName` cannot be an empty string") + return result, fmt.Errorf("`queueName` cannot be an empty string") } if strings.ToLower(queueName) != queueName { - return resp, fmt.Errorf("`queueName` must be a lower-cased string") + return result, fmt.Errorf("`queueName` must be a lower-cased string") } opts := client.RequestOptions{ @@ -40,7 +40,11 @@ func (c Client) Delete(ctx context.Context, queueName string) (resp DeleteRespon return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/metadata_get.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/metadata_get.go similarity index 69% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/metadata_get.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/metadata_get.go index 14c32d64d0f55..c8a259f451ba6 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/metadata_get.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/metadata_get.go @@ -12,20 +12,20 @@ import ( ) type GetMetaDataResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response MetaData map[string]string } // GetMetaData returns the metadata for this Queue -func (c Client) GetMetaData(ctx context.Context, queueName string) (resp GetMetaDataResponse, err error) { +func (c Client) GetMetaData(ctx context.Context, queueName string) (result GetMetaDataResponse, err error) { if queueName == "" { - return resp, fmt.Errorf("`queueName` cannot be an empty string") + return result, fmt.Errorf("`queueName` cannot be an empty string") } if strings.ToLower(queueName) != queueName { - return resp, fmt.Errorf("`queueName` must be a lower-cased string") + return result, fmt.Errorf("`queueName` must be a lower-cased string") } opts := client.RequestOptions{ @@ -44,15 +44,23 @@ func (c Client) GetMetaData(ctx context.Context, queueName string) (resp GetMeta return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + if resp.Header != nil { + result.MetaData = metadata.ParseFromHeaders(resp.Header) + } + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return } - if resp.HttpResponse != nil { - if resp.HttpResponse.Header != nil { - resp.MetaData = metadata.ParseFromHeaders(resp.HttpResponse.Header) + if result.HttpResponse != nil { + if result.HttpResponse.Header != nil { + result.MetaData = metadata.ParseFromHeaders(result.HttpResponse.Header) } } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/metadata_set.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/metadata_set.go similarity index 78% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/metadata_set.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/metadata_set.go index ea8eac3192da4..6ab770de1f52b 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/metadata_set.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/metadata_set.go @@ -12,7 +12,7 @@ import ( ) type SetMetaDataResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } type SetMetaDataInput struct { @@ -20,18 +20,18 @@ type SetMetaDataInput struct { } // SetMetaData returns the metadata for this Queue -func (c Client) SetMetaData(ctx context.Context, queueName string, input SetMetaDataInput) (resp SetMetaDataResponse, err error) { +func (c Client) SetMetaData(ctx context.Context, queueName string, input SetMetaDataInput) (result SetMetaDataResponse, err error) { if queueName == "" { - return resp, fmt.Errorf("`queueName` cannot be an empty string") + return result, fmt.Errorf("`queueName` cannot be an empty string") } if strings.ToLower(queueName) != queueName { - return resp, fmt.Errorf("`queueName` must be a lower-cased string") + return result, fmt.Errorf("`queueName` must be a lower-cased string") } if err := metadata.Validate(input.MetaData); err != nil { - return resp, fmt.Errorf("`metadata` is not valid: %v", err) + return result, fmt.Errorf("`metadata` is not valid: %+v", err) } opts := client.RequestOptions{ @@ -52,7 +52,11 @@ func (c Client) SetMetaData(ctx context.Context, queueName string, input SetMeta return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/models.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/models.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/models.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/models.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/properties_get.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/properties_get.go similarity index 77% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/properties_get.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/properties_get.go index b2ea774e55348..0647f26d1b8f3 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/properties_get.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/properties_get.go @@ -11,11 +11,11 @@ import ( type GetStorageServicePropertiesResponse struct { StorageServiceProperties - HttpResponse *client.Response + HttpResponse *http.Response } // GetServiceProperties gets the properties for this queue -func (c Client) GetServiceProperties(ctx context.Context) (resp GetStorageServicePropertiesResponse, err error) { +func (c Client) GetServiceProperties(ctx context.Context) (result GetStorageServicePropertiesResponse, err error) { opts := client.RequestOptions{ ContentType: "application/xml; charset=utf-8", @@ -33,18 +33,21 @@ func (c Client) GetServiceProperties(ctx context.Context) (resp GetStorageServic return } - resp.HttpResponse, err = req.Execute(ctx) - if err != nil { - err = fmt.Errorf("executing request: %+v", err) - return - } + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response - if resp.HttpResponse != nil { - err = resp.HttpResponse.Unmarshal(&resp) + err = resp.Unmarshal(&result) if err != nil { - return resp, fmt.Errorf("unmarshalling respnse: %v", err) + err = fmt.Errorf("unmarshalling response: %+v", err) + return } } + if err != nil { + err = fmt.Errorf("executing request: %+v", err) + return + } return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/properties_set.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/properties_set.go similarity index 84% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/properties_set.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/properties_set.go index 744bd9767ed10..d80b6728b3986 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/properties_set.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/properties_set.go @@ -14,7 +14,7 @@ import ( ) type SetStorageServicePropertiesResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } type SetStorageServicePropertiesInput struct { @@ -22,7 +22,7 @@ type SetStorageServicePropertiesInput struct { } // SetServiceProperties sets the properties for this queue -func (c Client) SetServiceProperties(ctx context.Context, input SetStorageServicePropertiesInput) (resp SetStorageServicePropertiesResponse, err error) { +func (c Client) SetServiceProperties(ctx context.Context, input SetStorageServicePropertiesInput) (result SetStorageServicePropertiesResponse, err error) { opts := client.RequestOptions{ ContentType: "application/xml; charset=utf-8", @@ -42,14 +42,18 @@ func (c Client) SetServiceProperties(ctx context.Context, input SetStorageServic marshalledProps, err := xml.Marshal(&input.Properties) if err != nil { - return resp, fmt.Errorf("marshalling request: %v", err) + return result, fmt.Errorf("marshalling request: %+v", err) } body := xml.Header + string(marshalledProps) req.Body = io.NopCloser(bytes.NewReader([]byte(body))) req.ContentLength = int64(len(body)) req.Header.Set("Content-Length", strconv.Itoa(len(body))) - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/resource_id.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/resource_id.go similarity index 97% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/resource_id.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/resource_id.go index 455319a233081..8acd0bb0ae74f 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/resource_id.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/resource_id.go @@ -6,7 +6,7 @@ import ( "strings" "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts" ) // GetResourceManagerResourceID returns the Resource Manager ID for the given Queue diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/version.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/version.go similarity index 80% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/version.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/version.go index 10937c5727d37..c22267eb6e7dc 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues/version.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues/version.go @@ -1,5 +1,5 @@ package queues // APIVersion is the version of the API used for all Storage API Operations -const apiVersion = "2020-08-04" +const apiVersion = "2023-11-03" const componentName = "queue/queues" diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/README.md b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/README.md new file mode 100644 index 0000000000000..06b519b894231 --- /dev/null +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/README.md @@ -0,0 +1,55 @@ +## Table Storage Entities SDK for API version 2023-11-03 + +This package allows you to interact with the Entities Table Storage API + +### Supported Authorizers + +* SharedKeyLite (Table) + +### Example Usage + +```go +package main + +import ( + "context" + "fmt" + + "github.com/hashicorp/go-azure-sdk/sdk/auth" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities" +) + +func Example() error { + accountName := "storageaccount1" + storageAccountKey := "ABC123...." + tableName := "mytable" + domainSuffix := "core.windows.net" + + auth, err := auth.NewSharedKeyAuthorizer(accountName, storageAccountKey, auth.SharedKeyTable) + if err != nil { + return fmt.Errorf("building SharedKey authorizer: %+v", err) + } + + entitiesClient, err := entities.NewWithBaseUri(fmt.Sprintf("https://%s.table.%s", accountName, domainSuffix)) + if err != nil { + return fmt.Errorf("building client for environment: %+v", err) + } + entitiesClient.Client.SetAuthorizer(auth) + + ctx := context.TODO() + input := entities.InsertEntityInput{ + PartitionKey: "abc", + RowKey: "123", + MetaDataLevel: entities.NoMetaData, + Entity: map[string]interface{}{ + "title": "Don't Kill My Vibe", + "artist": "Sigrid", + }, + } + if _, err := entitiesClient.Insert(ctx, tableName, input); err != nil { + return fmt.Errorf("Error creating Entity: %s", err) + } + + return nil +} +``` \ No newline at end of file diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/api.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/api.go new file mode 100644 index 0000000000000..bb0e9809e3c9d --- /dev/null +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/api.go @@ -0,0 +1,14 @@ +package entities + +import ( + "context" +) + +type StorageTableEntity interface { + Delete(ctx context.Context, tableName string, input DeleteEntityInput) (resp DeleteEntityResponse, err error) + Insert(ctx context.Context, tableName string, input InsertEntityInput) (resp InsertResponse, err error) + InsertOrReplace(ctx context.Context, tableName string, input InsertOrReplaceEntityInput) (resp InsertOrReplaceResponse, err error) + InsertOrMerge(ctx context.Context, tableName string, input InsertOrMergeEntityInput) (resp InsertOrMergeResponse, err error) + Query(ctx context.Context, tableName string, input QueryEntitiesInput) (resp QueryEntitiesResponse, err error) + Get(ctx context.Context, tableName string, input GetEntityInput) (resp GetEntityResponse, err error) +} diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/client.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/client.go new file mode 100644 index 0000000000000..e190af69d108c --- /dev/null +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/client.go @@ -0,0 +1,23 @@ +package entities + +import ( + "fmt" + + "github.com/hashicorp/go-azure-sdk/sdk/client/dataplane/storage" +) + +// Client is the base client for Table Storage Shares. +type Client struct { + Client *storage.Client +} + +func NewWithBaseUri(baseUri string) (*Client, error) { + baseClient, err := storage.NewStorageClient(baseUri, componentName, apiVersion) + if err != nil { + return nil, fmt.Errorf("building base client: %+v", err) + } + + return &Client{ + Client: baseClient, + }, nil +} diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/delete.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/delete.go new file mode 100644 index 0000000000000..61e7c712ac5e8 --- /dev/null +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/delete.go @@ -0,0 +1,84 @@ +package entities + +import ( + "context" + "fmt" + "net/http" + + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" +) + +type DeleteEntityInput struct { + // When inserting an entity into a table, you must specify values for the PartitionKey and RowKey system properties. + // Together, these properties form the primary key and must be unique within the table. + // Both the PartitionKey and RowKey values must be string values; each key value may be up to 64 KB in size. + // If you are using an integer value for the key value, you should convert the integer to a fixed-width string, + // because they are canonically sorted. For example, you should convert the value 1 to 0000001 to ensure proper sorting. + RowKey string + PartitionKey string +} + +type DeleteEntityResponse struct { + HttpResponse *http.Response +} + +// Delete deletes an existing entity in a table. +func (c Client) Delete(ctx context.Context, tableName string, input DeleteEntityInput) (result DeleteEntityResponse, err error) { + + if tableName == "" { + return result, fmt.Errorf("`tableName` cannot be an empty string") + } + + if input.PartitionKey == "" { + return result, fmt.Errorf("`input.PartitionKey` cannot be an empty string") + } + + if input.RowKey == "" { + return result, fmt.Errorf("`input.RowKey` cannot be an empty string") + } + + opts := client.RequestOptions{ + ContentType: "application/json", + ExpectedStatusCodes: []int{ + http.StatusNoContent, + }, + HttpMethod: http.MethodDelete, + OptionsObject: deleteEntitiesOptions{}, + Path: fmt.Sprintf("/%s(PartitionKey='%s', RowKey='%s')", tableName, input.PartitionKey, input.RowKey), + } + + req, err := c.Client.NewRequest(ctx, opts) + if err != nil { + err = fmt.Errorf("building request: %+v", err) + return + } + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } + if err != nil { + err = fmt.Errorf("executing request: %+v", err) + return + } + return +} + +type deleteEntitiesOptions struct{} + +func (d deleteEntitiesOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} + headers.Append("Accept", "application/json") + headers.Append("If-Match", "*") + return headers +} + +func (d deleteEntitiesOptions) ToOData() *odata.Query { + return nil +} + +func (d deleteEntitiesOptions) ToQuery() *client.QueryParams { + return nil +} diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/get.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/get.go new file mode 100644 index 0000000000000..daf428acdffa2 --- /dev/null +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/get.go @@ -0,0 +1,94 @@ +package entities + +import ( + "context" + "fmt" + "net/http" + + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" +) + +type GetEntityInput struct { + PartitionKey string + RowKey string + + // The Level of MetaData which should be returned + MetaDataLevel MetaDataLevel +} + +type GetEntityResponse struct { + HttpResponse *http.Response + + Entity map[string]interface{} +} + +// Get queries entities in a table and includes the $filter and $select options. +func (c Client) Get(ctx context.Context, tableName string, input GetEntityInput) (result GetEntityResponse, err error) { + if tableName == "" { + return result, fmt.Errorf("`tableName` cannot be an empty string") + } + + if input.PartitionKey == "" { + return result, fmt.Errorf("`input.PartitionKey` cannot be an empty string") + } + + if input.RowKey == "" { + return result, fmt.Errorf("`input.RowKey` cannot be an empty string") + } + + opts := client.RequestOptions{ + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodGet, + OptionsObject: getEntitiesOptions{ + MetaDataLevel: input.MetaDataLevel, + }, + Path: fmt.Sprintf("/%s(PartitionKey='%s', RowKey='%s')", tableName, input.PartitionKey, input.RowKey), + } + + req, err := c.Client.NewRequest(ctx, opts) + if err != nil { + err = fmt.Errorf("building request: %+v", err) + return + } + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + err = resp.Unmarshal(&result.Entity) + if err != nil { + err = fmt.Errorf("unmarshalling response: %+v", err) + return + } + } + if err != nil { + err = fmt.Errorf("executing request: %+v", err) + return + } + + return +} + +type getEntitiesOptions struct { + MetaDataLevel MetaDataLevel +} + +func (g getEntitiesOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} + headers.Append("Accept", fmt.Sprintf("application/json;odata=%s", g.MetaDataLevel)) + headers.Append("DataServiceVersion", "3.0;NetFx") + headers.Append("MaxDataServiceVersion", "3.0;NetFx") + return headers +} + +func (g getEntitiesOptions) ToOData() *odata.Query { + return nil +} + +func (g getEntitiesOptions) ToQuery() *client.QueryParams { + return nil +} diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/insert.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/insert.go new file mode 100644 index 0000000000000..1996ba8b9cef2 --- /dev/null +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/insert.go @@ -0,0 +1,104 @@ +package entities + +import ( + "context" + "fmt" + "net/http" + + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" +) + +type InsertEntityInput struct { + // The level of MetaData provided for this Entity + MetaDataLevel MetaDataLevel + + // The Entity which should be inserted, by default all values are strings + // To explicitly type a property, specify the appropriate OData data type by setting + // the m:type attribute within the property definition + Entity map[string]interface{} + + // When inserting an entity into a table, you must specify values for the PartitionKey and RowKey system properties. + // Together, these properties form the primary key and must be unique within the table. + // Both the PartitionKey and RowKey values must be string values; each key value may be up to 64 KB in size. + // If you are using an integer value for the key value, you should convert the integer to a fixed-width string, + // because they are canonically sorted. For example, you should convert the value 1 to 0000001 to ensure proper sorting. + RowKey string + PartitionKey string +} + +type InsertResponse struct { + HttpResponse *http.Response +} + +// Insert inserts a new entity into a table. +func (c Client) Insert(ctx context.Context, tableName string, input InsertEntityInput) (result InsertResponse, err error) { + if tableName == "" { + return result, fmt.Errorf("`tableName` cannot be an empty string") + } + + if input.PartitionKey == "" { + return result, fmt.Errorf("`input.PartitionKey` cannot be an empty string") + } + + if input.RowKey == "" { + return result, fmt.Errorf("`input.RowKey` cannot be an empty string") + } + + opts := client.RequestOptions{ + ContentType: "application/json", + ExpectedStatusCodes: []int{ + http.StatusNoContent, + }, + HttpMethod: http.MethodPost, + OptionsObject: insertOptions{ + MetaDataLevel: input.MetaDataLevel, + }, + Path: fmt.Sprintf("/%s", tableName), + } + + req, err := c.Client.NewRequest(ctx, opts) + if err != nil { + err = fmt.Errorf("building request: %+v", err) + return + } + + input.Entity["PartitionKey"] = input.PartitionKey + input.Entity["RowKey"] = input.RowKey + + err = req.Marshal(&input.Entity) + if err != nil { + return result, fmt.Errorf("marshalling request: %+v", err) + } + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } + if err != nil { + err = fmt.Errorf("executing request: %+v", err) + return + } + + return +} + +type insertOptions struct { + MetaDataLevel MetaDataLevel +} + +func (i insertOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} + headers.Append("Accept", fmt.Sprintf("application/json;odata=%s", i.MetaDataLevel)) + headers.Append("Prefer", "return-no-content") + return headers +} + +func (i insertOptions) ToOData() *odata.Query { + return nil +} + +func (i insertOptions) ToQuery() *client.QueryParams { + return nil +} diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/insert_or_merge.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/insert_or_merge.go new file mode 100644 index 0000000000000..8ec8191f6ea53 --- /dev/null +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/insert_or_merge.go @@ -0,0 +1,98 @@ +package entities + +import ( + "context" + "fmt" + "net/http" + + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" +) + +type InsertOrMergeEntityInput struct { + // The Entity which should be inserted, by default all values are strings + // To explicitly type a property, specify the appropriate OData data type by setting + // the m:type attribute within the property definition + Entity map[string]interface{} + + // When inserting an entity into a table, you must specify values for the PartitionKey and RowKey system properties. + // Together, these properties form the primary key and must be unique within the table. + // Both the PartitionKey and RowKey values must be string values; each key value may be up to 64 KB in size. + // If you are using an integer value for the key value, you should convert the integer to a fixed-width string, + // because they are canonically sorted. For example, you should convert the value 1 to 0000001 to ensure proper sorting. + RowKey string + PartitionKey string +} + +type InsertOrMergeResponse struct { + HttpResponse *http.Response +} + +// InsertOrMerge updates an existing entity or inserts a new entity if it does not exist in the table. +// Because this operation can insert or update an entity, it is also known as an upsert operation. +func (c Client) InsertOrMerge(ctx context.Context, tableName string, input InsertOrMergeEntityInput) (result InsertOrMergeResponse, err error) { + if tableName == "" { + return result, fmt.Errorf("`tableName` cannot be an empty string") + } + + if input.PartitionKey == "" { + return result, fmt.Errorf("`input.PartitionKey` cannot be an empty string") + } + + if input.RowKey == "" { + return result, fmt.Errorf("`input.RowKey` cannot be an empty string") + } + + opts := client.RequestOptions{ + ContentType: "application/json", + ExpectedStatusCodes: []int{ + http.StatusNoContent, + }, + HttpMethod: "MERGE", + OptionsObject: insertOrMergeOptions{}, + Path: fmt.Sprintf("/%s(PartitionKey='%s', RowKey='%s')", tableName, input.PartitionKey, input.RowKey), + } + + req, err := c.Client.NewRequest(ctx, opts) + if err != nil { + err = fmt.Errorf("building request: %+v", err) + return + } + + input.Entity["PartitionKey"] = input.PartitionKey + input.Entity["RowKey"] = input.RowKey + + err = req.Marshal(&input.Entity) + if err != nil { + return result, fmt.Errorf("marshalling request: %+v", err) + } + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } + if err != nil { + err = fmt.Errorf("executing request: %+v", err) + return + } + + return +} + +type insertOrMergeOptions struct{} + +func (i insertOrMergeOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} + headers.Append("Accept", "application/json") + headers.Append("Prefer", "return-no-content") + return headers +} + +func (i insertOrMergeOptions) ToOData() *odata.Query { + return nil +} + +func (i insertOrMergeOptions) ToQuery() *client.QueryParams { + return nil +} diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/insert_or_replace.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/insert_or_replace.go new file mode 100644 index 0000000000000..269437c06caec --- /dev/null +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/insert_or_replace.go @@ -0,0 +1,98 @@ +package entities + +import ( + "context" + "fmt" + "net/http" + + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" +) + +type InsertOrReplaceEntityInput struct { + // The Entity which should be inserted, by default all values are strings + // To explicitly type a property, specify the appropriate OData data type by setting + // the m:type attribute within the property definition + Entity map[string]interface{} + + // When inserting an entity into a table, you must specify values for the PartitionKey and RowKey system properties. + // Together, these properties form the primary key and must be unique within the table. + // Both the PartitionKey and RowKey values must be string values; each key value may be up to 64 KB in size. + // If you are using an integer value for the key value, you should convert the integer to a fixed-width string, + // because they are canonically sorted. For example, you should convert the value 1 to 0000001 to ensure proper sorting. + RowKey string + PartitionKey string +} + +type InsertOrReplaceResponse struct { + HttpResponse *http.Response +} + +// InsertOrReplace replaces an existing entity or inserts a new entity if it does not exist in the table. +// Because this operation can insert or update an entity, it is also known as an upsert operation. +func (c Client) InsertOrReplace(ctx context.Context, tableName string, input InsertOrReplaceEntityInput) (result InsertOrReplaceResponse, err error) { + if tableName == "" { + return result, fmt.Errorf("`tableName` cannot be an empty string") + } + + if input.PartitionKey == "" { + return result, fmt.Errorf("`input.PartitionKey` cannot be an empty string") + } + + if input.RowKey == "" { + return result, fmt.Errorf("`input.RowKey` cannot be an empty string") + } + + opts := client.RequestOptions{ + ContentType: "application/json", + ExpectedStatusCodes: []int{ + http.StatusNoContent, + }, + HttpMethod: "MERGE", + OptionsObject: insertOrReplaceOptions{}, + Path: fmt.Sprintf("/%s(PartitionKey='%s', RowKey='%s')", tableName, input.PartitionKey, input.RowKey), + } + + req, err := c.Client.NewRequest(ctx, opts) + if err != nil { + err = fmt.Errorf("building request: %+v", err) + return + } + + input.Entity["PartitionKey"] = input.PartitionKey + input.Entity["RowKey"] = input.RowKey + + err = req.Marshal(&input.Entity) + if err != nil { + return result, fmt.Errorf("marshalling request: %+v", err) + } + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } + if err != nil { + err = fmt.Errorf("executing request: %+v", err) + return + } + + return +} + +type insertOrReplaceOptions struct{} + +func (i insertOrReplaceOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} + headers.Append("Accept", "application/json") + headers.Append("Prefer", "return-no-content") + return headers +} + +func (i insertOrReplaceOptions) ToOData() *odata.Query { + return nil +} + +func (i insertOrReplaceOptions) ToQuery() *client.QueryParams { + return nil +} diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/models.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/models.go new file mode 100644 index 0000000000000..e3c6cccb59ce7 --- /dev/null +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/models.go @@ -0,0 +1,9 @@ +package entities + +type MetaDataLevel string + +var ( + NoMetaData MetaDataLevel = "nometadata" + MinimalMetaData MetaDataLevel = "minimalmetadata" + FullMetaData MetaDataLevel = "fullmetadata" +) diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/query.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/query.go new file mode 100644 index 0000000000000..57b411a55bf6d --- /dev/null +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/query.go @@ -0,0 +1,143 @@ +package entities + +import ( + "context" + "fmt" + "net/http" + "strconv" + "strings" + + "github.com/hashicorp/go-azure-sdk/sdk/client" + "github.com/hashicorp/go-azure-sdk/sdk/odata" +) + +type QueryEntitiesInput struct { + // An optional OData filter + Filter *string + + // An optional comma-separated + PropertyNamesToSelect *[]string + + // An optional OData top + Top *int + + PartitionKey string + RowKey string + + // The Level of MetaData which should be returned + MetaDataLevel MetaDataLevel + + // The Next Partition Key used to load data from a previous point + NextPartitionKey *string + + // The Next Row Key used to load data from a previous point + NextRowKey *string +} + +type QueryEntitiesResponse struct { + HttpResponse *http.Response + + NextPartitionKey string + NextRowKey string + + MetaData string `json:"odata.metadata,omitempty"` + Entities []map[string]interface{} `json:"value"` +} + +// Query queries entities in a table and includes the $filter and $select options. +func (c Client) Query(ctx context.Context, tableName string, input QueryEntitiesInput) (result QueryEntitiesResponse, err error) { + if tableName == "" { + return result, fmt.Errorf("`tableName` cannot be an empty string") + } + + additionalParameters := make([]string, 0) + if input.PartitionKey != "" { + additionalParameters = append(additionalParameters, "PartitionKey='%s'", input.PartitionKey) + } + + if input.RowKey != "" { + additionalParameters = append(additionalParameters, "RowKey='%s'", input.RowKey) + } + + path := fmt.Sprintf("/%s", tableName) + if len(additionalParameters) > 0 { + path += fmt.Sprintf("(%s)", strings.Join(additionalParameters, ",")) + } + + opts := client.RequestOptions{ + ContentType: "application/json", + ExpectedStatusCodes: []int{ + http.StatusOK, + }, + HttpMethod: http.MethodGet, + OptionsObject: queryOptions{ + input: input, + }, + Path: path, + } + + req, err := c.Client.NewRequest(ctx, opts) + if err != nil { + err = fmt.Errorf("building request: %+v", err) + return + } + + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + err = resp.Unmarshal(&result) + if err != nil { + err = fmt.Errorf("unmarshalling response: %+v", err) + return + } + } + if err != nil { + err = fmt.Errorf("executing request: %+v", err) + return + } + + return +} + +type queryOptions struct { + input QueryEntitiesInput +} + +func (q queryOptions) ToHeaders() *client.Headers { + headers := &client.Headers{} + headers.Append("Accept", fmt.Sprintf("application/json;odata=%s", q.input.MetaDataLevel)) + headers.Append("DataServiceVersion", "3.0;NetFx") + headers.Append("MaxDataServiceVersion", "3.0;NetFx") + return headers +} + +func (q queryOptions) ToOData() *odata.Query { + return nil +} + +func (q queryOptions) ToQuery() *client.QueryParams { + out := &client.QueryParams{} + + if q.input.Filter != nil { + out.Append("$filter", *q.input.Filter) + } + + if q.input.PropertyNamesToSelect != nil { + out.Append("$select", strings.Join(*q.input.PropertyNamesToSelect, ",")) + } + + if q.input.Top != nil { + out.Append("$top", strconv.Itoa(*q.input.Top)) + } + + if q.input.NextPartitionKey != nil { + out.Append("NextPartitionKey", *q.input.NextPartitionKey) + } + + if q.input.NextRowKey != nil { + out.Append("NextRowKey", *q.input.NextRowKey) + } + return out +} diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/resource_id.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/resource_id.go new file mode 100644 index 0000000000000..0403b5e640bc1 --- /dev/null +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/resource_id.go @@ -0,0 +1,122 @@ +package entities + +import ( + "fmt" + "net/url" + "strings" + + "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts" +) + +// TODO: update this to implement `resourceids.ResourceId` once +// https://github.com/hashicorp/go-azure-helpers/issues/187 is fixed +var _ resourceids.Id = EntityId{} + +type EntityId struct { + // AccountId specifies the ID of the Storage Account where this Entity exists. + AccountId accounts.AccountId + + // TableName specifies the name of the Table where this Entity exists. + TableName string + + // PartitionKey specifies the Partition Key for this Entity. + PartitionKey string + + // RowKey specifies the Row Key for this Entity. + RowKey string +} + +func NewEntityID(accountId accounts.AccountId, tableName, partitionKey, rowKey string) EntityId { + return EntityId{ + AccountId: accountId, + TableName: tableName, + PartitionKey: partitionKey, + RowKey: rowKey, + } +} + +func (b EntityId) ID() string { + return fmt.Sprintf("%s/%s(PartitionKey='%s',RowKey='%s')", b.AccountId.ID(), b.TableName, b.PartitionKey, b.RowKey) +} + +func (b EntityId) String() string { + components := []string{ + fmt.Sprintf("Partition Key %q", b.PartitionKey), + fmt.Sprintf("Row Key %q", b.RowKey), + fmt.Sprintf("Table Name %q", b.TableName), + fmt.Sprintf("Account %q", b.AccountId.String()), + } + return fmt.Sprintf("Entity (%s)", strings.Join(components, " / ")) +} + +// ParseEntityID parses `input` into a Entity ID using a known `domainSuffix` +func ParseEntityID(input, domainSuffix string) (*EntityId, error) { + // example: https://foo.table.core.windows.net/Bar1(PartitionKey='partition1',RowKey='row1') + if input == "" { + return nil, fmt.Errorf("`input` was empty") + } + + account, err := accounts.ParseAccountID(input, domainSuffix) + if err != nil { + return nil, fmt.Errorf("parsing account %q: %+v", input, err) + } + + if account.SubDomainType != accounts.TableSubDomainType { + return nil, fmt.Errorf("expected the subdomain type to be %q but got %q", string(accounts.TableSubDomainType), string(account.SubDomainType)) + } + + uri, err := url.Parse(input) + if err != nil { + return nil, fmt.Errorf("parsing %q as a uri: %+v", input, err) + } + + path := strings.TrimPrefix(uri.Path, "/") + segments := strings.Split(path, "/") + if len(segments) != 1 { + return nil, fmt.Errorf("expected the path to contain 1 segment but got %d", len(segments)) + } + + // Tables and Table Entities are similar with table being `table1` and entities + // being `table1(PartitionKey='samplepartition',RowKey='samplerow')` so we need to validate this is a table + key := strings.TrimPrefix(uri.Path, "/") + if !strings.Contains(key, "(") || !strings.HasSuffix(key, ")") { + return nil, fmt.Errorf("expected the path to be an entity name but got a table name %q", key) + } + + indexOfFirstBracket := strings.Index(key, "(") + tableName := key[0:indexOfFirstBracket] + componentString := key[indexOfFirstBracket:] + componentString = strings.TrimPrefix(componentString, "(") + componentString = strings.TrimSuffix(componentString, ")") + components := strings.Split(componentString, ",") + if len(components) != 2 { + return nil, fmt.Errorf("expected the path to be an entity name but got %q", key) + } + + partitionKey := parseValueFromKey(components[0], "PartitionKey") + rowKey := parseValueFromKey(components[1], "RowKey") + return &EntityId{ + AccountId: *account, + TableName: tableName, + PartitionKey: *partitionKey, + RowKey: *rowKey, + }, nil +} + +func parseValueFromKey(input, expectedKey string) *string { + components := strings.Split(input, "=") + if len(components) != 2 { + return nil + } + key := components[0] + value := components[1] + if key != expectedKey { + return nil + } + + // the value is surrounded in single quotes, remove those + value = strings.TrimPrefix(value, "'") + value = strings.TrimSuffix(value, "'") + return &value +} diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/version.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/version.go new file mode 100644 index 0000000000000..5eae649209e31 --- /dev/null +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities/version.go @@ -0,0 +1,4 @@ +package entities + +const apiVersion = "2023-11-03" +const componentName = "table/entities" diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/README.md b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/README.md similarity index 89% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/README.md rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/README.md index a6b5ee2a239fc..65a459f79dcd5 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/README.md +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/README.md @@ -1,4 +1,4 @@ -## Table Storage Tables SDK for API version 2020-08-04 +## Table Storage Tables SDK for API version 2023-11-03 This package allows you to interact with the Tables Table Storage API @@ -16,7 +16,7 @@ import ( "fmt" "github.com/hashicorp/go-azure-sdk/sdk/auth" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables" ) func Example() error { diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/acl_get.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/acl_get.go similarity index 75% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/acl_get.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/acl_get.go index d927d38f9c900..3f2f2a18692f6 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/acl_get.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/acl_get.go @@ -10,16 +10,17 @@ import ( ) type GetACLResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response SignedIdentifiers []SignedIdentifier `xml:"SignedIdentifier"` } // GetACL returns the Access Control List for the specified Table -func (c Client) GetACL(ctx context.Context, tableName string) (resp GetACLResponse, err error) { +func (c Client) GetACL(ctx context.Context, tableName string) (result GetACLResponse, err error) { if tableName == "" { - return resp, fmt.Errorf("`tableName` cannot be an empty string") + err = fmt.Errorf("`tableName` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -38,21 +39,22 @@ func (c Client) GetACL(ctx context.Context, tableName string) (resp GetACLRespon return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + err = resp.Unmarshal(&result) + if err != nil { + err = fmt.Errorf("unmarshalling response: %+v", err) + return + } + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return } - if resp.HttpResponse != nil { - if resp.HttpResponse.Body != nil { - err = resp.HttpResponse.Unmarshal(&resp) - if err != nil { - return resp, fmt.Errorf("unmarshalling response body: %v", err) - } - } - } - return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/acl_set.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/acl_set.go similarity index 80% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/acl_set.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/acl_set.go index 9ff4ad0e0a1eb..9749bd062c5fa 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/acl_set.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/acl_set.go @@ -17,13 +17,14 @@ type setAcl struct { } type SetACLResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // SetACL sets the specified Access Control List for the specified Table -func (c Client) SetACL(ctx context.Context, tableName string, acls []SignedIdentifier) (resp SetACLResponse, err error) { +func (c Client) SetACL(ctx context.Context, tableName string, acls []SignedIdentifier) (result SetACLResponse, err error) { if tableName == "" { - return resp, fmt.Errorf("`tableName` cannot be an empty string") + err = fmt.Errorf("`tableName` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -44,10 +45,15 @@ func (c Client) SetACL(ctx context.Context, tableName string, acls []SignedIdent err = req.Marshal(setAcl{SignedIdentifiers: acls}) if err != nil { - return resp, fmt.Errorf("marshalling request: %+v", err) + err = fmt.Errorf("marshalling request: %+v", err) + return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/api.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/api.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/api.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/api.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/client.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/client.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/client.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/client.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/create.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/create.go similarity index 81% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/create.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/create.go index feeebe40052f5..6adfd5ab5e365 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/create.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/create.go @@ -14,13 +14,14 @@ type createTableRequest struct { } type CreateTableResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // Create creates a new table in the storage account. -func (c Client) Create(ctx context.Context, tableName string) (resp CreateTableResponse, err error) { +func (c Client) Create(ctx context.Context, tableName string) (result CreateTableResponse, err error) { if tableName == "" { - return resp, fmt.Errorf("`tableName` cannot be an empty string") + err = fmt.Errorf("`tableName` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -41,10 +42,14 @@ func (c Client) Create(ctx context.Context, tableName string) (resp CreateTableR err = req.Marshal(&createTableRequest{TableName: tableName}) if err != nil { - return resp, fmt.Errorf("marshalling request") + return result, fmt.Errorf("marshalling request") } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/delete.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/delete.go similarity index 81% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/delete.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/delete.go index 3a2817f482824..b1fab65b30c0d 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/delete.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/delete.go @@ -10,13 +10,14 @@ import ( ) type DeleteTableResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // Delete deletes the specified table and any data it contains. -func (c Client) Delete(ctx context.Context, tableName string) (resp DeleteTableResponse, err error) { +func (c Client) Delete(ctx context.Context, tableName string) (result DeleteTableResponse, err error) { if tableName == "" { - return resp, fmt.Errorf("`tableName` cannot be an empty string") + err = fmt.Errorf("`tableName` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -35,7 +36,11 @@ func (c Client) Delete(ctx context.Context, tableName string) (resp DeleteTableR return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/exists.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/exists.go similarity index 80% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/exists.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/exists.go index 1497695cf03fd..efd922e2a8cab 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/exists.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/exists.go @@ -10,13 +10,14 @@ import ( ) type TableExistsResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response } // Exists checks that the specified table exists -func (c Client) Exists(ctx context.Context, tableName string) (resp TableExistsResponse, err error) { +func (c Client) Exists(ctx context.Context, tableName string) (result TableExistsResponse, err error) { if tableName == "" { - return resp, fmt.Errorf("`tableName` cannot be an empty string") + err = fmt.Errorf("`tableName` cannot be an empty string") + return } opts := client.RequestOptions{ @@ -37,10 +38,15 @@ func (c Client) Exists(ctx context.Context, tableName string) (resp TableExistsR err = req.Marshal(&createTableRequest{TableName: tableName}) if err != nil { - return resp, fmt.Errorf("marshalling request") + err = fmt.Errorf("marshalling request") + return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/models.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/models.go similarity index 100% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/models.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/models.go diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/query.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/query.go similarity index 82% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/query.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/query.go index 9a15de8d0fa7e..4cc07ead352e8 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/query.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/query.go @@ -10,7 +10,7 @@ import ( ) type GetResponse struct { - HttpResponse *client.Response + HttpResponse *http.Response MetaData string `json:"odata.metadata,omitempty"` Tables []GetResultItem `json:"value"` @@ -21,7 +21,7 @@ type QueryInput struct { } // Query returns a list of tables under the specified account. -func (c Client) Query(ctx context.Context, input QueryInput) (resp GetResponse, err error) { +func (c Client) Query(ctx context.Context, input QueryInput) (result GetResponse, err error) { opts := client.RequestOptions{ ExpectedStatusCodes: []int{ @@ -40,21 +40,22 @@ func (c Client) Query(ctx context.Context, input QueryInput) (resp GetResponse, return } - resp.HttpResponse, err = req.Execute(ctx) + var resp *client.Response + resp, err = req.Execute(ctx) + if resp != nil { + result.HttpResponse = resp.Response + + err = resp.Unmarshal(&result) + if err != nil { + err = fmt.Errorf("unmarshalling response: %+v", err) + return + } + } if err != nil { err = fmt.Errorf("executing request: %+v", err) return } - if resp.HttpResponse != nil { - if resp.HttpResponse.Body != nil { - err = resp.HttpResponse.Unmarshal(&resp) - if err != nil { - return resp, fmt.Errorf("unmarshalling response: %v", err) - } - } - } - return } diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/resource_id.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/resource_id.go similarity index 97% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/resource_id.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/resource_id.go index 2dbc4c948c5b8..8c5072f0b316a 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/resource_id.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/resource_id.go @@ -6,7 +6,7 @@ import ( "strings" "github.com/hashicorp/go-azure-helpers/resourcemanager/resourceids" - "github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts" + "github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts" ) // GetResourceManagerResourceID returns the Resource ID for the given Table diff --git a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/version.go b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/version.go similarity index 62% rename from vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/version.go rename to vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/version.go index 3e0363fc361eb..63c317fdfa2c7 100644 --- a/vendor/github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables/version.go +++ b/vendor/github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables/version.go @@ -1,4 +1,4 @@ package tables -const apiVersion = "2020-08-04" +const apiVersion = "2023-11-03" const componentName = "table/tables" diff --git a/vendor/modules.txt b/vendor/modules.txt index 1f27d843b4f9d..1f1697d7378aa 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1256,16 +1256,18 @@ github.com/sergi/go-diff/diffmatchpatch # github.com/tombuildsstuff/giovanni v0.24.0 ## explicit; go 1.21 github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/accounts -github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/blobs -github.com/tombuildsstuff/giovanni/storage/2020-08-04/blob/containers -github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/filesystems -github.com/tombuildsstuff/giovanni/storage/2020-08-04/datalakestore/paths -github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/directories -github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/files -github.com/tombuildsstuff/giovanni/storage/2020-08-04/file/shares -github.com/tombuildsstuff/giovanni/storage/2020-08-04/queue/queues github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/entities -github.com/tombuildsstuff/giovanni/storage/2020-08-04/table/tables +github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/accounts +github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/blobs +github.com/tombuildsstuff/giovanni/storage/2023-11-03/blob/containers +github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/filesystems +github.com/tombuildsstuff/giovanni/storage/2023-11-03/datalakestore/paths +github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/directories +github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/files +github.com/tombuildsstuff/giovanni/storage/2023-11-03/file/shares +github.com/tombuildsstuff/giovanni/storage/2023-11-03/queue/queues +github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/entities +github.com/tombuildsstuff/giovanni/storage/2023-11-03/table/tables github.com/tombuildsstuff/giovanni/storage/accesscontrol github.com/tombuildsstuff/giovanni/storage/internal/metadata # github.com/tombuildsstuff/kermit v0.20240122.1123108 diff --git a/website/docs/d/storage_share.html.markdown b/website/docs/d/storage_share.html.markdown index 20763c76e730f..d4e0bbbdda16e 100644 --- a/website/docs/d/storage_share.html.markdown +++ b/website/docs/d/storage_share.html.markdown @@ -10,6 +10,8 @@ description: |- Use this data source to access information about an existing File Share. +~> **Note on Authentication** Shared Key authentication will always be used for this data source, as AzureAD authentication is not supported by the Storage API for files. + ## Example Usage ```hcl diff --git a/website/docs/r/storage_container.html.markdown b/website/docs/r/storage_container.html.markdown index 33465c9183f42..2136d1f4fdcad 100644 --- a/website/docs/r/storage_container.html.markdown +++ b/website/docs/r/storage_container.html.markdown @@ -47,6 +47,8 @@ The following arguments are supported: * `container_access_type` - (Optional) The Access Level configured for this Container. Possible values are `blob`, `container` or `private`. Defaults to `private`. +~> **Note** When updating `container_access_type` for an existing storage container resource, Shared Key authentication will always be used, as AzureAD authentication is not supported. + * `metadata` - (Optional) A mapping of MetaData for this Container. All metadata keys should be lowercase. ## Attributes Reference diff --git a/website/docs/r/storage_share.html.markdown b/website/docs/r/storage_share.html.markdown index e79dc16d0f6dd..7fd0544df73de 100644 --- a/website/docs/r/storage_share.html.markdown +++ b/website/docs/r/storage_share.html.markdown @@ -10,7 +10,9 @@ description: |- Manages a File Share within Azure Storage. -~> **Note:** The storage share supports two storage tiers: premium and standard. Standard file shares are created in general purpose (GPv1 or GPv2) storage accounts and premium file shares are created in FileStorage storage accounts. For further information, refer to the section "What storage tiers are supported in Azure Files?" of [documentation](https://docs.microsoft.com/azure/storage/files/storage-files-faq#general). +~> **Note** The storage share supports two storage tiers: premium and standard. Standard file shares are created in general purpose (GPv1 or GPv2) storage accounts and premium file shares are created in FileStorage storage accounts. For further information, refer to the section "What storage tiers are supported in Azure Files?" of [documentation](https://docs.microsoft.com/azure/storage/files/storage-files-faq#general). + +~> **Note on Authentication** Shared Key authentication will always be used for this resource, as AzureAD authentication is not supported by the Storage API for files. ## Example Usage diff --git a/website/docs/r/storage_share_directory.html.markdown b/website/docs/r/storage_share_directory.html.markdown index e758c74abe461..8cba5456992a8 100644 --- a/website/docs/r/storage_share_directory.html.markdown +++ b/website/docs/r/storage_share_directory.html.markdown @@ -33,9 +33,8 @@ resource "azurerm_storage_share" "example" { } resource "azurerm_storage_share_directory" "example" { - name = "example" - share_name = azurerm_storage_share.example.name - storage_account_name = azurerm_storage_account.example.name + name = "example" + storage_share_id = azurerm_storage_share.example.id } ``` @@ -45,9 +44,7 @@ The following arguments are supported: * `name` - (Required) The name (or path) of the Directory that should be created within this File Share. Changing this forces a new resource to be created. -* `share_name` - (Required) The name of the File Share where this Directory should be created. Changing this forces a new resource to be created. - -* `storage_account_name` - (Required) The name of the Storage Account within which the File Share is located. Changing this forces a new resource to be created. +* `storage_share_id` - (Required) The Storage Share ID in which this file will be placed into. Changing this forces a new resource to be created. * `metadata` - (Optional) A mapping of metadata to assign to this Directory.