Merge branch 'f-oracle-compute' into f-add-ip-address-associaitons

This commit is contained in:
Matthew Frahry 2017-04-06 10:48:39 -06:00 committed by GitHub
commit 4bfd0fd15b
9 changed files with 525 additions and 28 deletions

View File

@ -0,0 +1,29 @@
package opc
import (
"testing"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
)
func TestAccOPCStorageVolumeSnapshot_importBasic(t *testing.T) {
resourceName := "opc_compute_storage_volume_snapshot.test"
rInt := acctest.RandInt()
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: opcResourceCheck(resourceName, testAccCheckStorageVolumeSnapshotDestroyed),
Steps: []resource.TestStep{
{
Config: testAccStorageVolumeSnapshot_basic(rInt),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

View File

@ -50,28 +50,29 @@ func Provider() terraform.ResourceProvider {
},
ResourcesMap: map[string]*schema.Resource{
"opc_compute_ip_network": resourceOPCIPNetwork(),
"opc_compute_acl": resourceOPCACL(),
"opc_compute_image_list": resourceOPCImageList(),
"opc_compute_image_list_entry": resourceOPCImageListEntry(),
"opc_compute_instance": resourceInstance(),
"opc_compute_ip_address_reservation": resourceOPCIPAddressReservation(),
"opc_compute_ip_association": resourceOPCIPAssociation(),
"opc_compute_ip_network_exchange": resourceOPCIPNetworkExchange(),
"opc_compute_ip_reservation": resourceOPCIPReservation(),
"opc_compute_route": resourceOPCRoute(),
"opc_compute_security_application": resourceOPCSecurityApplication(),
"opc_compute_security_association": resourceOPCSecurityAssociation(),
"opc_compute_security_ip_list": resourceOPCSecurityIPList(),
"opc_compute_security_list": resourceOPCSecurityList(),
"opc_compute_security_rule": resourceOPCSecurityRule(),
"opc_compute_sec_rule": resourceOPCSecRule(),
"opc_compute_ssh_key": resourceOPCSSHKey(),
"opc_compute_storage_volume": resourceOPCStorageVolume(),
"opc_compute_vnic_set": resourceOPCVNICSet(),
"opc_compute_security_protocol": resourceOPCSecurityProtocol(),
"opc_compute_ip_address_prefix_set": resourceOPCIPAddressPrefixSet(),
"opc_compute_ip_address_association": resourceOPCIPAddressAssociation(),
"opc_compute_ip_network": resourceOPCIPNetwork(),
"opc_compute_acl": resourceOPCACL(),
"opc_compute_image_list": resourceOPCImageList(),
"opc_compute_image_list_entry": resourceOPCImageListEntry(),
"opc_compute_instance": resourceInstance(),
"opc_compute_ip_address_reservation": resourceOPCIPAddressReservation(),
"opc_compute_ip_association": resourceOPCIPAssociation(),
"opc_compute_ip_network_exchange": resourceOPCIPNetworkExchange(),
"opc_compute_ip_reservation": resourceOPCIPReservation(),
"opc_compute_route": resourceOPCRoute(),
"opc_compute_security_application": resourceOPCSecurityApplication(),
"opc_compute_security_association": resourceOPCSecurityAssociation(),
"opc_compute_security_ip_list": resourceOPCSecurityIPList(),
"opc_compute_security_list": resourceOPCSecurityList(),
"opc_compute_security_rule": resourceOPCSecurityRule(),
"opc_compute_sec_rule": resourceOPCSecRule(),
"opc_compute_ssh_key": resourceOPCSSHKey(),
"opc_compute_storage_volume": resourceOPCStorageVolume(),
"opc_compute_storage_volume_snapshot": resourceOPCStorageVolumeSnapshot(),
"opc_compute_vnic_set": resourceOPCVNICSet(),
"opc_compute_security_protocol": resourceOPCSecurityProtocol(),
"opc_compute_ip_address_prefix_set": resourceOPCIPAddressPrefixSet(),
"opc_compute_ip_address_association": resourceOPCIPAddressAssociation(),
},
ConfigureFunc: providerConfigure,

View File

@ -42,6 +42,26 @@ func resourceOPCStorageVolume() *schema.Resource {
}, true),
},
"snapshot": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
Computed: true,
},
"snapshot_id": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},
"snapshot_account": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
"bootable": {
Type: schema.TypeList,
Optional: true,
@ -128,7 +148,19 @@ func resourceOPCStorageVolumeCreate(d *schema.ResourceData, meta interface{}) er
Tags: getStringList(d, "tags"),
}
expandOPCStorageVolumeOptionalFields(d, input)
expandOPCStorageVolumeOptionalFields(d, &input)
if v, ok := d.GetOk("snapshot"); ok {
input.Snapshot = v.(string)
}
if v, ok := d.GetOk("snapshot_account"); ok {
input.SnapshotAccount = v.(string)
}
if v, ok := d.GetOk("snapshot_id"); ok {
input.SnapshotID = v.(string)
}
info, err := client.CreateStorageVolume(&input)
if err != nil {
@ -188,6 +220,9 @@ func resourceOPCStorageVolumeRead(d *schema.ResourceData, meta interface{}) erro
d.Set("name", result.Name)
d.Set("description", result.Description)
d.Set("storage", result.Properties[0])
d.Set("snapshot", result.Snapshot)
d.Set("snapshot_id", result.SnapshotID)
d.Set("snapshot_account", result.SnapshotAccount)
size, err := strconv.Atoi(result.Size)
if err != nil {
return err
@ -220,11 +255,11 @@ func resourceOPCStorageVolumeDelete(d *schema.ResourceData, meta interface{}) er
return nil
}
func expandOPCStorageVolumeOptionalFields(d *schema.ResourceData, input compute.CreateStorageVolumeInput) {
value, exists := d.GetOk("bootable")
input.Bootable = exists
if exists {
configs := value.([]interface{})
func expandOPCStorageVolumeOptionalFields(d *schema.ResourceData, input *compute.CreateStorageVolumeInput) {
bootValue, bootExists := d.GetOk("bootable")
input.Bootable = bootExists
if bootExists {
configs := bootValue.([]interface{})
config := configs[0].(map[string]interface{})
input.ImageList = config["image_list"].(string)

View File

@ -0,0 +1,230 @@
package opc
import (
"fmt"
"strconv"
"github.com/hashicorp/go-oracle-terraform/compute"
"github.com/hashicorp/terraform/helper/schema"
)
func resourceOPCStorageVolumeSnapshot() *schema.Resource {
return &schema.Resource{
Create: resourceOPCStorageVolumeSnapshotCreate,
Read: resourceOPCStorageVolumeSnapshotRead,
Delete: resourceOPCStorageVolumeSnapshotDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Schema: map[string]*schema.Schema{
// Required Attributes
"volume_name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
// Optional Attributes
"description": {
Type: schema.TypeString,
Optional: true,
ForceNew: true,
},
// Optional, but also computed if unspecified
"name": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ForceNew: true,
},
"parent_volume_bootable": {
Type: schema.TypeBool,
Optional: true,
ForceNew: true,
Default: false,
},
"collocated": {
Type: schema.TypeBool,
Optional: true,
Default: false,
ForceNew: true,
},
"tags": tagsForceNewSchema(),
// Computed Attributes
"account": {
Type: schema.TypeString,
Computed: true,
},
"machine_image_name": {
Type: schema.TypeString,
Computed: true,
},
"size": {
Type: schema.TypeString,
Computed: true,
},
"property": {
Type: schema.TypeString,
Computed: true,
},
"platform": {
Type: schema.TypeString,
Computed: true,
},
"snapshot_timestamp": {
Type: schema.TypeString,
Computed: true,
},
"snapshot_id": {
Type: schema.TypeString,
Computed: true,
},
"start_timestamp": {
Type: schema.TypeString,
Computed: true,
},
"status": {
Type: schema.TypeString,
Computed: true,
},
"status_detail": {
Type: schema.TypeString,
Computed: true,
},
"status_timestamp": {
Type: schema.TypeString,
Computed: true,
},
"uri": {
Type: schema.TypeString,
Computed: true,
},
},
}
}
func resourceOPCStorageVolumeSnapshotCreate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).StorageVolumeSnapshots()
// Get required attribute
input := &compute.CreateStorageVolumeSnapshotInput{
Volume: d.Get("volume_name").(string),
}
if v, ok := d.GetOk("description"); ok {
input.Description = v.(string)
}
if v, ok := d.GetOk("name"); ok {
input.Name = v.(string)
}
// Convert parent_volume_bootable to string
bootable := d.Get("parent_volume_bootable").(bool)
if bootable {
input.ParentVolumeBootable = "true"
}
collocated := d.Get("collocated").(bool)
if collocated {
input.Property = compute.SnapshotPropertyCollocated
}
tags := getStringList(d, "tags")
if len(tags) > 0 {
input.Tags = tags
}
info, err := client.CreateStorageVolumeSnapshot(input)
if err != nil {
return fmt.Errorf("Error creating snapshot '%s': %v", input.Name, err)
}
d.SetId(info.Name)
return resourceOPCStorageVolumeSnapshotRead(d, meta)
}
func resourceOPCStorageVolumeSnapshotRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).StorageVolumeSnapshots()
name := d.Id()
input := &compute.GetStorageVolumeSnapshotInput{
Name: name,
}
result, err := client.GetStorageVolumeSnapshot(input)
if err != nil {
if compute.WasNotFoundError(err) {
d.SetId("")
return nil
}
return fmt.Errorf("Error reading storage volume snapshot '%s': %v", name, err)
}
d.Set("volume_name", result.Volume)
d.Set("description", result.Description)
d.Set("name", result.Name)
d.Set("property", result.Property)
d.Set("platform", result.Platform)
d.Set("account", result.Account)
d.Set("machine_image_name", result.MachineImageName)
d.Set("size", result.Size)
d.Set("snapshot_timestamp", result.SnapshotTimestamp)
d.Set("snapshot_id", result.SnapshotID)
d.Set("start_timestamp", result.StartTimestamp)
d.Set("status", result.Status)
d.Set("status_detail", result.StatusDetail)
d.Set("status_timestamp", result.StatusTimestamp)
d.Set("uri", result.URI)
bootable, err := strconv.ParseBool(result.ParentVolumeBootable)
if err != nil {
return fmt.Errorf("Error converting parent volume to boolean: %v", err)
}
d.Set("parent_volume_bootable", bootable)
if result.Property != compute.SnapshotPropertyCollocated {
d.Set("collocated", false)
} else {
d.Set("collocated", true)
}
if err := setStringList(d, "tags", result.Tags); err != nil {
return err
}
return nil
}
func resourceOPCStorageVolumeSnapshotDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*compute.Client).StorageVolumeSnapshots()
name := d.Id()
input := &compute.DeleteStorageVolumeSnapshotInput{
Name: name,
}
if err := client.DeleteStorageVolumeSnapshot(input); err != nil {
return fmt.Errorf("Error deleting storage volume snapshot '%s': %v", name, err)
}
return nil
}

View File

@ -0,0 +1,88 @@
package opc
import (
"fmt"
"testing"
"github.com/hashicorp/go-oracle-terraform/compute"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
)
func TestAccOPCStorageVolumeSnapshot_basic(t *testing.T) {
snapshotName := "opc_compute_storage_volume_snapshot.test"
rInt := acctest.RandInt()
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: opcResourceCheck(snapshotName, testAccCheckStorageVolumeSnapshotDestroyed),
Steps: []resource.TestStep{
{
Config: testAccStorageVolumeSnapshot_basic(rInt),
Check: resource.ComposeTestCheckFunc(opcResourceCheck(snapshotName, testAccCheckStorageVolumeSnapshotExists),
resource.TestCheckResourceAttr(snapshotName, "name", fmt.Sprintf("test-acc-stor-vol-%d", rInt)),
resource.TestCheckResourceAttr(snapshotName, "parent_volume_bootable", "false"),
resource.TestCheckResourceAttr(snapshotName, "collocated", "true"),
resource.TestCheckResourceAttr(snapshotName, "size", "5"),
),
},
},
})
}
func testAccCheckStorageVolumeSnapshotExists(state *OPCResourceState) error {
client := state.Client.StorageVolumeSnapshots()
snapshotName := state.Attributes["name"]
input := &compute.GetStorageVolumeSnapshotInput{
Name: snapshotName,
}
info, err := client.GetStorageVolumeSnapshot(input)
if err != nil {
return fmt.Errorf("Error retrieving state of snapshot '%s': %v", snapshotName, err)
}
if info == nil {
return fmt.Errorf("No info found for snapshot '%s'", snapshotName)
}
return nil
}
func testAccCheckStorageVolumeSnapshotDestroyed(state *OPCResourceState) error {
client := state.Client.StorageVolumeSnapshots()
snapshotName := state.Attributes["name"]
input := &compute.GetStorageVolumeSnapshotInput{
Name: snapshotName,
}
info, err := client.GetStorageVolumeSnapshot(input)
if err != nil {
return fmt.Errorf("Error retrieving state of snapshot '%s': %v", snapshotName, err)
}
if info != nil {
return fmt.Errorf("Snapshot '%s' still exists", snapshotName)
}
return nil
}
func testAccStorageVolumeSnapshot_basic(rInt int) string {
return fmt.Sprintf(`
resource "opc_compute_storage_volume" "foo" {
name = "test-acc-stor-vol-%d"
description = "testAccStorageVolumeSnapshot_basic"
size = 5
}
resource "opc_compute_storage_volume_snapshot" "test" {
name = "test-acc-stor-vol-%d"
description = "storage volume snapshot"
collocated = true
volume_name = "${opc_compute_storage_volume.foo.name}"
}
`, rInt, rInt)
}

View File

@ -116,6 +116,29 @@ func TestAccOPCStorageVolume_Bootable(t *testing.T) {
})
}
func TestAccOPCStorageVolume_FromSnapshot(t *testing.T) {
volumeResourceName := "opc_compute_storage_volume.test"
rInt := acctest.RandInt()
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: opcResourceCheck(volumeResourceName, testAccCheckStorageVolumeDestroyed),
Steps: []resource.TestStep{
{
Config: testAccStorageVolumeFromSnapshot(rInt),
Check: resource.ComposeTestCheckFunc(
opcResourceCheck(volumeResourceName, testAccCheckStorageVolumeExists),
resource.TestCheckResourceAttr(volumeResourceName, "name", fmt.Sprintf("test-acc-stor-vol-final-%d", rInt)),
resource.TestCheckResourceAttrSet(volumeResourceName, "snapshot"),
resource.TestCheckResourceAttrSet(volumeResourceName, "snapshot_id"),
resource.TestCheckResourceAttr(volumeResourceName, "size", "5"),
),
},
},
})
}
func testAccCheckStorageVolumeExists(state *OPCResourceState) error {
sv := state.Client.StorageVolumes()
volumeName := state.Attributes["name"]
@ -204,3 +227,29 @@ resource "opc_compute_storage_volume" "test" {
size = 2048
}
`
func testAccStorageVolumeFromSnapshot(rInt int) string {
return fmt.Sprintf(`
// Initial Storage Volume to create snapshot with
resource "opc_compute_storage_volume" "foo" {
name = "test-acc-stor-vol-%d"
description = "Acc Test intermediary storage volume for snapshot"
size = 5
}
resource "opc_compute_storage_volume_snapshot" "foo" {
description = "testing-acc"
name = "test-acc-stor-snapshot-%d"
collocated = true
volume_name = "${opc_compute_storage_volume.foo.name}"
}
// Create storage volume from snapshot
resource "opc_compute_storage_volume" "test" {
name = "test-acc-stor-vol-final-%d"
description = "storage volume from snapshot"
size = 5
snapshot_id = "${opc_compute_storage_volume_snapshot.foo.snapshot_id}"
}
`, rInt, rInt, rInt)
}

View File

@ -51,6 +51,9 @@ The following arguments are supported:
* `storage_type` - (Optional) - The Type of Storage to provision. Possible values are `/oracle/public/storage/latency` or `/oracle/public/storage/default`. Defaults to `/oracle/public/storage/default`.
* `bootable` - (Optional) A `bootable` block as defined below.
* `tags` - (Optional) Comma-separated strings that tag the storage volume.
* `snapshot` - (Optional) Name of the storage volume snapshot if this storage volume is a clone.
* `snapshot_account` - (Optional) Account of the parent snapshot from which the storage volume is restored.
* `snapshot_id` - (Optional) Id of the parent snapshot from which the storage volume is restored or cloned.
`bootable` supports the following:
* `image_list` - (Required) Defines an image list.

View File

@ -0,0 +1,59 @@
---
layout: "opc"
page_title: "Oracle: opc_compute_storage_volume_snapshot"
sidebar_current: "docs-opc-resource-storage-volume-snapshot"
description: |-
Creates and manages a storage volume snapshot in an OPC identity domain.
---
# opc\_compute\_storage\_volume_snapshot
The ``opc_compute_storage_volume_snapshot`` resource creates and manages a storage volume snapshot in an OPC identity domain.
## Example Usage
```
resource "opc_compute_storage_volume_snapshot" "test" {
name = "storageVolume1"
description = "Description for the Storage Volume"
tags = ["bar", "foo"]
collocated = true
volume_name = "${opc_compute_storage_volume.foo.name}"
}
```
## Argument Reference
The following arguments are supported:
* `volume_name` (Required) The name of the storage volume to create the snapshot from.
* `description` (Optional) The description of the storage volume snapshot.
* `name` (Optional) The name of the storage volume snapshot. Will be generated if unspecified.
* `parent_volume_bootable` (Optional) A string value of whether or not the parent volume is 'bootable' or not. Defaults to `"false"`.
* `collocated` (Optional) Boolean specifying whether the snapshot is collocated or remote. Defaults to `false`.
* `tags` - (Optional) Comma-separated strings that tag the storage volume.
## Attributes Reference
In addition to the attributes above, the following attributes are exported:
* `account` - Account to use for snapshots.
* `machine_image_name` - The name of the machine image that's used in the boot volume from which this snapshot is taken.
* `size` - The size of the snapshot in GB.
* `property` - Where the snapshot is stored, whether collocated, or in the Oracle Storage Cloud Service instance.
* `platform` - The OS platform this snapshot is compatible with
* `snapshot_timestamp` - Timestamp of the storage snapshot, generated by storage server. The snapshot will contain data written to the original volume before this time.
* `snapshot_id` - The Oracle ID of the snapshot.
* `start_timestamp` - Timestamp when the snapshot was started.
* `status` - Status of the snapshot.
* `status_detail` - Details about the latest state of the storage volume snapshot.
* `status_timestamp` - Indicates the time that the current view of the storage volume snapshot was generated.
* `uri` - Uniform Resource Identifier
## Import
Storage Volume Snapshot's can be imported using the `resource name`, e.g.
```
terraform import opc_compute_storage_volume_snapshot.volume1 example
```

View File

@ -85,6 +85,9 @@
<li<%= sidebar_current("docs-opc-resource-storage-volume") %>>
<a href="/docs/providers/opc/r/opc_compute_storage_volume.html">opc_compute_storage_volume</a>
</li>
<li<%= sidebar_current("docs-opc-resource-storage-volume-snapshot") %>>
<a href="/docs/providers/opc/r/opc_compute_storage_volume_snapshot.html">opc_compute_storage_volume_snapshot</a>
</li>
<li<%= sidebar_current("docs-opc-resource-vnic-set") %>>
<a href="/docs/providers/opc/r/opc_compute_vnic_set.html">opc_compute_vnic_set</a>
</li>