Skip to content

Commit

Permalink
azurerm_storage_blob - Page blob supports source_content
Browse files Browse the repository at this point in the history
  • Loading branch information
magodo committed Dec 11, 2023
1 parent 2d48f47 commit 799fc3a
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 1 deletion.
18 changes: 17 additions & 1 deletion internal/services/storage/blobs.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ func (sbu BlobUpload) Create(ctx context.Context) error {
return sbu.copy(ctx)
}
if sbu.SourceContent != "" {
return fmt.Errorf("`source_content` cannot be specified for a Page blob")
return sbu.uploadPageBlobFromContent(ctx)
}
if sbu.Source != "" {
return sbu.uploadPageBlob(ctx)
Expand Down Expand Up @@ -185,6 +185,22 @@ func (sbu BlobUpload) createEmptyPageBlob(ctx context.Context) error {
return nil
}

func (sbu BlobUpload) uploadPageBlobFromContent(ctx context.Context) error {
tmpFile, err := os.CreateTemp(os.TempDir(), "upload-")
if err != nil {
return fmt.Errorf("creating temporary file: %s", err)
}
defer os.Remove(tmpFile.Name())

if _, err = tmpFile.Write([]byte(sbu.SourceContent)); err != nil {
return fmt.Errorf("writing Source Content to Temp File: %s", err)
}
defer tmpFile.Close()

sbu.Source = tmpFile.Name()
return sbu.uploadPageBlob(ctx)
}

func (sbu BlobUpload) uploadPageBlob(ctx context.Context) error {
if sbu.Size != 0 {
return fmt.Errorf("`size` cannot be set for an uploaded page blob")
Expand Down
10 changes: 10 additions & 0 deletions internal/services/storage/storage_blob_resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package storage

import (
"context"
"fmt"
"log"
"strings"
Expand Down Expand Up @@ -151,6 +152,15 @@ func resourceStorageBlob() *pluginsdk.Resource {

"metadata": MetaDataComputedSchema(),
},

CustomizeDiff: func(ctx context.Context, diff *pluginsdk.ResourceDiff, i interface{}) error {
if content := diff.Get("source_content"); content != "" && diff.Get("type") == "Page" {
if len(content.(string))%512 != 0 {
return fmt.Errorf(`"source" must be aligned to 512-byte boundary for "type" set to "Page"`)
}
}
return nil
},
}
}

Expand Down
46 changes: 46 additions & 0 deletions internal/services/storage/storage_blob_resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"crypto/rand"
"fmt"
"os"
"regexp"
"testing"

"github.com/hashicorp/terraform-provider-azurerm/internal/acceptance"
Expand Down Expand Up @@ -389,6 +390,32 @@ func TestAccStorageBlob_pageFromLocalFile(t *testing.T) {
})
}

func TestAccStorageBlob_pageFromInlineContent(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_storage_blob", "test")
r := StorageBlobResource{}

data.ResourceTest(t, r, []acceptance.TestStep{
{
Config: r.pageFromInlineContent(data, 512),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.ImportStep("parallelism", "size", "source_content", "type"),
{
Config: r.pageFromInlineContent(data, 1024),
Check: acceptance.ComposeTestCheckFunc(
check.That(data.ResourceName).ExistsInAzure(r),
),
},
data.ImportStep("parallelism", "size", "source_content", "type"),
{
Config: r.pageFromInlineContent(data, 511),
ExpectError: regexp.MustCompile(`"source" must be aligned to 512-byte boundary for "type" set to "Page"`),
},
})
}

func TestAccStorageBlob_requiresImport(t *testing.T) {
data := acceptance.BuildTestData(t, "azurerm_storage_blob", "test")
r := StorageBlobResource{}
Expand Down Expand Up @@ -950,6 +977,25 @@ resource "azurerm_storage_blob" "test" {
`, template, fileName)
}

func (r StorageBlobResource) pageFromInlineContent(data acceptance.TestData, length int) string {
template := r.template(data, "private")
return fmt.Sprintf(`
%s
provider "azurerm" {
features {}
}
resource "azurerm_storage_blob" "test" {
name = "rick.morty"
storage_account_name = azurerm_storage_account.test.name
storage_container_name = azurerm_storage_container.test.name
type = "Page"
source_content = join("", [for i in range(0, %d) : "a"])
}
`, template, length)
}

func (r StorageBlobResource) requiresImport(data acceptance.TestData) string {
template := r.blockFromPublicBlob(data)
return fmt.Sprintf(`
Expand Down

0 comments on commit 799fc3a

Please sign in to comment.