Azure blob contents can be copied from an existing blob (#8126)
- adds "source_uri" field - "source_uri" expects the URI to an existing blob that you have access to - it can be in a different storage account, or in the Azure File service - the docs have been updated to reflect the change Signed-off-by: Dan Wendorf <dwendorf@pivotal.io>
This commit is contained in:
parent
598b940e1c
commit
ec42a98cb2
|
@ -46,7 +46,7 @@ func resourceArmStorageBlob() *schema.Resource {
|
||||||
},
|
},
|
||||||
"type": {
|
"type": {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Required: true,
|
Optional: true,
|
||||||
ForceNew: true,
|
ForceNew: true,
|
||||||
ValidateFunc: validateArmStorageBlobType,
|
ValidateFunc: validateArmStorageBlobType,
|
||||||
},
|
},
|
||||||
|
@ -58,9 +58,16 @@ func resourceArmStorageBlob() *schema.Resource {
|
||||||
ValidateFunc: validateArmStorageBlobSize,
|
ValidateFunc: validateArmStorageBlobSize,
|
||||||
},
|
},
|
||||||
"source": {
|
"source": {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
Optional: true,
|
Optional: true,
|
||||||
ForceNew: true,
|
ForceNew: true,
|
||||||
|
ConflictsWith: []string{"source_uri"},
|
||||||
|
},
|
||||||
|
"source_uri": {
|
||||||
|
Type: schema.TypeString,
|
||||||
|
Optional: true,
|
||||||
|
ForceNew: true,
|
||||||
|
ConflictsWith: []string{"source"},
|
||||||
},
|
},
|
||||||
"url": {
|
"url": {
|
||||||
Type: schema.TypeString,
|
Type: schema.TypeString,
|
||||||
|
@ -144,34 +151,41 @@ func resourceArmStorageBlobCreate(d *schema.ResourceData, meta interface{}) erro
|
||||||
name := d.Get("name").(string)
|
name := d.Get("name").(string)
|
||||||
blobType := d.Get("type").(string)
|
blobType := d.Get("type").(string)
|
||||||
cont := d.Get("storage_container_name").(string)
|
cont := d.Get("storage_container_name").(string)
|
||||||
|
sourceUri := d.Get("source_uri").(string)
|
||||||
|
|
||||||
log.Printf("[INFO] Creating blob %q in storage account %q", name, storageAccountName)
|
log.Printf("[INFO] Creating blob %q in storage account %q", name, storageAccountName)
|
||||||
switch strings.ToLower(blobType) {
|
if sourceUri != "" {
|
||||||
case "block":
|
if err := blobClient.CopyBlob(cont, name, sourceUri); err != nil {
|
||||||
if err := blobClient.CreateBlockBlob(cont, name); err != nil {
|
|
||||||
return fmt.Errorf("Error creating storage blob on Azure: %s", err)
|
return fmt.Errorf("Error creating storage blob on Azure: %s", err)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
switch strings.ToLower(blobType) {
|
||||||
|
case "block":
|
||||||
|
if err := blobClient.CreateBlockBlob(cont, name); err != nil {
|
||||||
|
return fmt.Errorf("Error creating storage blob on Azure: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
source := d.Get("source").(string)
|
source := d.Get("source").(string)
|
||||||
if source != "" {
|
if source != "" {
|
||||||
parallelism := d.Get("parallelism").(int)
|
parallelism := d.Get("parallelism").(int)
|
||||||
attempts := d.Get("attempts").(int)
|
attempts := d.Get("attempts").(int)
|
||||||
if err := resourceArmStorageBlobBlockUploadFromSource(cont, name, source, blobClient, parallelism, attempts); err != nil {
|
if err := resourceArmStorageBlobBlockUploadFromSource(cont, name, source, blobClient, parallelism, attempts); err != nil {
|
||||||
return fmt.Errorf("Error creating storage blob on Azure: %s", err)
|
return fmt.Errorf("Error creating storage blob on Azure: %s", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
case "page":
|
||||||
case "page":
|
source := d.Get("source").(string)
|
||||||
source := d.Get("source").(string)
|
if source != "" {
|
||||||
if source != "" {
|
parallelism := d.Get("parallelism").(int)
|
||||||
parallelism := d.Get("parallelism").(int)
|
attempts := d.Get("attempts").(int)
|
||||||
attempts := d.Get("attempts").(int)
|
if err := resourceArmStorageBlobPageUploadFromSource(cont, name, source, blobClient, parallelism, attempts); err != nil {
|
||||||
if err := resourceArmStorageBlobPageUploadFromSource(cont, name, source, blobClient, parallelism, attempts); err != nil {
|
return fmt.Errorf("Error creating storage blob on Azure: %s", err)
|
||||||
return fmt.Errorf("Error creating storage blob on Azure: %s", err)
|
}
|
||||||
}
|
} else {
|
||||||
} else {
|
size := int64(d.Get("size").(int))
|
||||||
size := int64(d.Get("size").(int))
|
if err := blobClient.PutPageBlob(cont, name, size, map[string]string{}); err != nil {
|
||||||
if err := blobClient.PutPageBlob(cont, name, size, map[string]string{}); err != nil {
|
return fmt.Errorf("Error creating storage blob on Azure: %s", err)
|
||||||
return fmt.Errorf("Error creating storage blob on Azure: %s", err)
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -257,6 +257,41 @@ func TestAccAzureRMStorageBlobPage_source(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAccAzureRMStorageBlob_source_uri(t *testing.T) {
|
||||||
|
ri := acctest.RandInt()
|
||||||
|
rs1 := strings.ToLower(acctest.RandString(11))
|
||||||
|
sourceBlob, err := ioutil.TempFile("", "")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Failed to create local source blob file")
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = io.CopyN(sourceBlob, rand.Reader, 25*1024*1024)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Failed to write random test to source blob")
|
||||||
|
}
|
||||||
|
|
||||||
|
err = sourceBlob.Close()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Failed to close source blob")
|
||||||
|
}
|
||||||
|
|
||||||
|
config := fmt.Sprintf(testAccAzureRMStorageBlob_source_uri, ri, rs1, sourceBlob.Name())
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
Providers: testAccProviders,
|
||||||
|
CheckDestroy: testCheckAzureRMStorageBlobDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
resource.TestStep{
|
||||||
|
Config: config,
|
||||||
|
Check: resource.ComposeTestCheckFunc(
|
||||||
|
testCheckAzureRMStorageBlobMatchesFile("azurerm_storage_blob.destination", storage.BlobTypeBlock, sourceBlob.Name()),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func testCheckAzureRMStorageBlobExists(name string) resource.TestCheckFunc {
|
func testCheckAzureRMStorageBlobExists(name string) resource.TestCheckFunc {
|
||||||
return func(s *terraform.State) error {
|
return func(s *terraform.State) error {
|
||||||
|
|
||||||
|
@ -500,3 +535,51 @@ resource "azurerm_storage_blob" "source" {
|
||||||
attempts = 3
|
attempts = 3
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
|
var testAccAzureRMStorageBlob_source_uri = `
|
||||||
|
resource "azurerm_resource_group" "test" {
|
||||||
|
name = "acctestrg-%d"
|
||||||
|
location = "westus"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "azurerm_storage_account" "source" {
|
||||||
|
name = "acctestacc%s"
|
||||||
|
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||||
|
location = "westus"
|
||||||
|
account_type = "Standard_LRS"
|
||||||
|
|
||||||
|
tags {
|
||||||
|
environment = "staging"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "azurerm_storage_container" "source" {
|
||||||
|
name = "source"
|
||||||
|
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||||
|
storage_account_name = "${azurerm_storage_account.source.name}"
|
||||||
|
container_access_type = "blob"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "azurerm_storage_blob" "source" {
|
||||||
|
name = "source.vhd"
|
||||||
|
|
||||||
|
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||||
|
storage_account_name = "${azurerm_storage_account.source.name}"
|
||||||
|
storage_container_name = "${azurerm_storage_container.source.name}"
|
||||||
|
|
||||||
|
type = "block"
|
||||||
|
source = "%s"
|
||||||
|
parallelism = 4
|
||||||
|
attempts = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "azurerm_storage_blob" "destination" {
|
||||||
|
name = "destination.vhd"
|
||||||
|
|
||||||
|
resource_group_name = "${azurerm_resource_group.test.name}"
|
||||||
|
storage_account_name = "${azurerm_storage_account.source.name}"
|
||||||
|
storage_container_name = "${azurerm_storage_container.source.name}"
|
||||||
|
|
||||||
|
source_uri = "${azurerm_storage_blob.source.url}"
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
|
@ -58,11 +58,15 @@ The following arguments are supported:
|
||||||
|
|
||||||
* `storage_container_name` - (Required) The name of the storage container in which this blob should be created.
|
* `storage_container_name` - (Required) The name of the storage container in which this blob should be created.
|
||||||
|
|
||||||
* `type` - (Required) The type of the storage blob to be created. One of either `block` or `page`.
|
* `type` - (Optional) The type of the storage blob to be created. One of either `block` or `page`. When not copying from an existing blob,
|
||||||
|
this becomes required.
|
||||||
|
|
||||||
* `size` - (Optional) Used only for `page` blobs to specify the size in bytes of the blob to be created. Must be a multiple of 512. Defaults to 0.
|
* `size` - (Optional) Used only for `page` blobs to specify the size in bytes of the blob to be created. Must be a multiple of 512. Defaults to 0.
|
||||||
|
|
||||||
* `source` - (Optional) An absolute path to a file on the local system
|
* `source` - (Optional) An absolute path to a file on the local system. Cannot be defined if `source_uri` is defined.
|
||||||
|
|
||||||
|
* `source_uri` - (Optional) The URI of an existing blob, or a file in the Azure File service, to use as the source contents
|
||||||
|
for the blob to be created. Changing this forces a new resource to be created. Cannot be defined if `source` is defined.
|
||||||
|
|
||||||
* `parallelism` - (Optional) The number of workers per CPU core to run for concurrent uploads. Defaults to `8`.
|
* `parallelism` - (Optional) The number of workers per CPU core to run for concurrent uploads. Defaults to `8`.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue