Skip to content

Commit

Permalink
New Resource: azurerm_snapshot
Browse files Browse the repository at this point in the history
  • Loading branch information
tombuildsstuff committed Oct 12, 2017
1 parent 629bb72 commit deb0a4b
Show file tree
Hide file tree
Showing 7 changed files with 914 additions and 6 deletions.
22 changes: 16 additions & 6 deletions azurerm/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ type ArmClient struct {
imageClient compute.ImagesClient

diskClient disk.DisksClient
snapshotsClient disk.SnapshotsClient
cosmosDBClient cosmosdb.DatabaseAccountsClient
automationAccountClient automation.AccountClient
automationRunbookClient automation.RunbookClient
Expand Down Expand Up @@ -354,12 +355,6 @@ func (c *Config) getArmClient() (*ArmClient, error) {
cdb.Sender = sender
client.cosmosDBClient = cdb

dkc := disk.NewDisksClientWithBaseURI(endpoint, c.SubscriptionID)
setUserAgent(&dkc.Client)
dkc.Authorizer = auth
dkc.Sender = sender
client.diskClient = dkc

img := compute.NewImagesClientWithBaseURI(endpoint, c.SubscriptionID)
setUserAgent(&img.Client)
img.Authorizer = auth
Expand Down Expand Up @@ -656,6 +651,7 @@ func (c *Config) getArmClient() (*ArmClient, error) {

client.registerAuthentication(endpoint, graphEndpoint, c.SubscriptionID, c.TenantID, auth, graphAuth, sender)
client.registerDatabases(endpoint, c.SubscriptionID, auth, sender)
client.registerDisks(endpoint, c.SubscriptionID, auth, sender)
client.registerKeyVaultClients(endpoint, c.SubscriptionID, auth, keyVaultAuth, sender)

return &client, nil
Expand Down Expand Up @@ -758,6 +754,20 @@ func (c *ArmClient) registerDatabases(endpoint, subscriptionId string, auth auto
c.sqlServersClient = sqlSrvClient
}

func (c *ArmClient) registerDisks(endpoint, subscriptionId string, auth autorest.Authorizer, sender autorest.Sender) {
diskClient := disk.NewDisksClientWithBaseURI(endpoint, subscriptionId)
setUserAgent(&diskClient.Client)
diskClient.Authorizer = auth
diskClient.Sender = sender
c.diskClient = diskClient

snapshotsClient := disk.NewSnapshotsClientWithBaseURI(endpoint, subscriptionId)
setUserAgent(&snapshotsClient.Client)
snapshotsClient.Authorizer = auth
snapshotsClient.Sender = sender
c.snapshotsClient = snapshotsClient
}

func (c *ArmClient) registerKeyVaultClients(endpoint, subscriptionId string, auth autorest.Authorizer, keyVaultAuth autorest.Authorizer, sender autorest.Sender) {
keyVaultClient := keyvault.NewVaultsClientWithBaseURI(endpoint, subscriptionId)
setUserAgent(&keyVaultClient.Client)
Expand Down
53 changes: 53 additions & 0 deletions azurerm/import_arm_snapshot_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package azurerm

import (
"testing"

"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
)

func TestAccAzureRMSnapshot_import(t *testing.T) {
resourceName := "azurerm_snapshot.test"
ri := acctest.RandInt()
config := testAccAzureRMSnapshot_fromManagedDisk(ri, testLocation())

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testCheckAzureRMSnapshotDestroy,
Steps: []resource.TestStep{
{
Config: config,
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func TestAccAzureRMSnapshot_importEncryption(t *testing.T) {
resourceName := "azurerm_snapshot.test"
ri := acctest.RandInt()
rs := acctest.RandString(4)
config := testAccAzureRMSnapshot_encryption(ri, rs, testLocation())

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testCheckAzureRMSnapshotDestroy,
Steps: []resource.TestStep{
{
Config: config,
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}
1 change: 1 addition & 0 deletions azurerm/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ func Provider() terraform.ResourceProvider {
"azurerm_servicebus_queue": resourceArmServiceBusQueue(),
"azurerm_servicebus_subscription": resourceArmServiceBusSubscription(),
"azurerm_servicebus_topic": resourceArmServiceBusTopic(),
"azurerm_snapshot": resourceArmSnapshot(),
"azurerm_sql_database": resourceArmSqlDatabase(),
"azurerm_sql_elasticpool": resourceArmSqlElasticPool(),
"azurerm_sql_firewall_rule": resourceArmSqlFirewallRule(),
Expand Down
239 changes: 239 additions & 0 deletions azurerm/resource_arm_snapshot.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,239 @@
package azurerm

import (
"fmt"
"log"
"regexp"

"github.com/Azure/azure-sdk-for-go/arm/disk"
"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/helper/validation"
"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
)

func resourceArmSnapshot() *schema.Resource {
return &schema.Resource{
Create: resourceArmSnapshotCreateUpdate,
Read: resourceArmSnapshotRead,
Update: resourceArmSnapshotCreateUpdate,
Delete: resourceArmSnapshotDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},

// TODO: this wants an associated Data Source

Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validateSnapshotName,
},

"location": locationSchema(),

"resource_group_name": resourceGroupNameSchema(),

"create_option": {
Type: schema.TypeString,
Required: true,
ValidateFunc: validation.StringInSlice([]string{
string(disk.Copy),
string(disk.Import),
}, true),
DiffSuppressFunc: ignoreCaseDiffSuppressFunc,
},

"source_uri": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},

"source_resource_id": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},

"storage_account_id": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},

"disk_size_gb": {
Type: schema.TypeInt,
Optional: true,
Computed: true,
},

"encryption_settings": encryptionSettingsSchema(),

"tags": tagsSchema(),
},
}
}

func resourceArmSnapshotCreateUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*ArmClient).snapshotsClient

name := d.Get("name").(string)
resourceGroup := d.Get("resource_group_name").(string)
location := azureRMNormalizeLocation(d.Get("location").(string))
createOption := d.Get("create_option").(string)
tags := d.Get("tags").(map[string]interface{})

properties := disk.Snapshot{
Location: utils.String(location),
Properties: &disk.Properties{
CreationData: &disk.CreationData{
CreateOption: disk.CreateOption(createOption),
},
},
Tags: expandTags(tags),
}

if v, ok := d.GetOk("source_uri"); ok {
properties.Properties.CreationData.SourceURI = utils.String(v.(string))
}

if v, ok := d.GetOk("source_resource_id"); ok {
properties.Properties.CreationData.SourceResourceID = utils.String(v.(string))
}

if v, ok := d.GetOk("storage_account_id"); ok {
properties.Properties.CreationData.StorageAccountID = utils.String(v.(string))
}

diskSizeGB := d.Get("disk_size_gb").(int)
if diskSizeGB > 0 {
properties.Properties.DiskSizeGB = utils.Int32(int32(diskSizeGB))
}

if v, ok := d.GetOk("encryption_settings"); ok {
encryptionSettings := v.([]interface{})
settings := encryptionSettings[0].(map[string]interface{})
properties.EncryptionSettings = expandManagedDiskEncryptionSettings(settings)
}

_, createErr := client.CreateOrUpdate(resourceGroup, name, properties, make(chan struct{}))
err := <-createErr
if err != nil {
return err
}

resp, err := client.Get(resourceGroup, name)
if err != nil {
return err
}

d.SetId(*resp.ID)

return resourceArmSnapshotRead(d, meta)
}

func resourceArmSnapshotRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*ArmClient).snapshotsClient

id, err := parseAzureResourceID(d.Id())
if err != nil {
return err
}

resourceGroup := id.ResourceGroup
name := id.Path["snapshots"]

resp, err := client.Get(resourceGroup, name)
if err != nil {
if utils.ResponseWasNotFound(resp.Response) {
log.Printf("[INFO] Error reading Snapshot %q - removing from state", d.Id())
d.SetId("")
return nil
}

return fmt.Errorf("Error making Read request on Snapshot %q: %+v", name, err)
}

d.Set("name", resp.Name)
d.Set("location", azureRMNormalizeLocation(*resp.Location))
d.Set("resource_group_name", resourceGroup)

if props := resp.Properties; props != nil {

if data := props.CreationData; data != nil {
d.Set("create_option", string(data.CreateOption))

if data.SourceURI != nil {
d.Set("source_uri", data.SourceURI)
}

if data.SourceResourceID != nil {
d.Set("source_resource_id", data.SourceResourceID)
}

if data.StorageAccountID != nil {
d.Set("storage_account_id", *data.StorageAccountID)
}
}

if props.DiskSizeGB != nil {
d.Set("disk_size_gb", int(*props.DiskSizeGB))
}

if props.EncryptionSettings != nil {
d.Set("encryption_settings", flattenManagedDiskEncryptionSettings(props.EncryptionSettings))
}
}

flattenAndSetTags(d, resp.Tags)

return nil
}

func resourceArmSnapshotDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*ArmClient).snapshotsClient

id, err := parseAzureResourceID(d.Id())
if err != nil {
return err
}

resourceGroup := id.ResourceGroup
name := id.Path["snapshots"]

deleteResp, deleteErr := client.Delete(resourceGroup, name, make(chan struct{}))
resp := <-deleteResp
err = <-deleteErr
if err != nil {
if utils.ResponseWasNotFound(resp.Response) {
return nil
}

return fmt.Errorf("Error making Read request on Snapshot %q: %+v", name, err)
}

if err != nil {
return fmt.Errorf("Error deleting Snapshot: %+v", err)
}

return nil
}

func validateSnapshotName(v interface{}, k string) (ws []string, errors []error) {
// a-z, A-Z, 0-9 and _. The max name length is 80
value := v.(string)

r, _ := regexp.Compile("^[A-Za-z0-9_]+$")
if !r.MatchString(value) {
errors = append(errors, fmt.Errorf("Snapshot Names can only contain alphanumeric characters and underscores."))
}

length := len(value)
if length > 80 {
errors = append(errors, fmt.Errorf("Snapshot Name can be up to 80 characters, currently %d.", length))
}

return
}
Loading

0 comments on commit deb0a4b

Please sign in to comment.