Add Storage Volumes to instances

- Adds storage volumes to instances
- Updates go-oracle-terraform vendor
- Adds clarification between ip/shared network in docs
- make 'bootable.image_list' a required parameter in the storage_volume resource
- Add storage volume test + docs
This commit is contained in:
Jake Champlin 2017-04-05 16:40:05 -04:00
parent d05af76607
commit 9062ddded3
No known key found for this signature in database
GPG Key ID: DC31F41958EF4AC2
10 changed files with 130 additions and 25 deletions

View File

@ -11,6 +11,7 @@ import (
"github.com/hashicorp/go-oracle-terraform/compute"
"github.com/hashicorp/terraform/helper/hashcode"
"github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/helper/validation"
)
func resourceInstance() *schema.Resource {
@ -232,9 +233,10 @@ func resourceInstance() *schema.Resource {
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"index": {
Type: schema.TypeInt,
Required: true,
ForceNew: true,
Type: schema.TypeInt,
Required: true,
ForceNew: true,
ValidateFunc: validation.IntBetween(1, 10),
},
"volume": {
Type: schema.TypeString,
@ -337,7 +339,7 @@ func resourceInstance() *schema.Resource {
Computed: true,
},
"vcable_id": {
"vcable": {
Type: schema.TypeString,
Computed: true,
},
@ -401,8 +403,10 @@ func resourceInstanceCreate(d *schema.ResourceData, meta interface{}) error {
input.SSHKeys = sshKeys
}
// TODO Add storage things
//storage := getStorageAttachments(d)
storage := getStorageAttachments(d)
if len(storage) > 0 {
input.Storage = storage
}
if tags := getStringList(d, "tags"); len(tags) > 0 {
input.Tags = tags
@ -476,7 +480,9 @@ func updateInstanceAttributes(d *schema.ResourceData, instance *compute.Instance
return err
}
// TODO Set Storage
if err := readStorageAttachments(d, instance.Storage); err != nil {
return err
}
if err := setStringList(d, "tags", instance.Tags); err != nil {
return err
@ -512,7 +518,7 @@ func updateInstanceAttributes(d *schema.ResourceData, instance *compute.Instance
return err
}
d.Set("vcable_id", instance.VCableID)
d.Set("vcable", instance.VCableID)
d.Set("virtio", instance.Virtio)
d.Set("vnc_address", instance.VNC)
@ -537,10 +543,8 @@ func resourceInstanceDelete(d *schema.ResourceData, meta interface{}) error {
return nil
}
// TODO Uncomment this when working on storage
/*
func getStorageAttachments(d *schema.ResourceData) []compute.StorageAttachment {
storageAttachments := []compute.StorageAttachment{}
func getStorageAttachments(d *schema.ResourceData) []compute.StorageAttachmentInput {
storageAttachments := []compute.StorageAttachmentInput{}
storage := d.Get("storage").(*schema.Set)
for _, i := range storage.List() {
attrs := i.(map[string]interface{})
@ -550,7 +554,7 @@ func getStorageAttachments(d *schema.ResourceData) []compute.StorageAttachment {
})
}
return storageAttachments
}*/
}
// Parses instance_attributes from a string to a map[string]interface and returns any errors.
func getInstanceAttributes(d *schema.ResourceData) (map[string]interface{}, error) {
@ -895,3 +899,21 @@ func readNetworkInterfaces(d *schema.ResourceData, ifaces map[string]compute.Net
return d.Set("networking_info", result)
}
// Flattens the returned slice of storage attachments to a map
func readStorageAttachments(d *schema.ResourceData, attachments []compute.StorageAttachment) error {
result := make([]map[string]interface{}, 0)
if attachments == nil || len(attachments) == 0 {
return d.Set("storage", nil)
}
for _, attachment := range attachments {
res := make(map[string]interface{})
res["index"] = attachment.Index
res["volume"] = attachment.StorageVolumeName
res["name"] = attachment.Name
result = append(result, res)
}
return d.Set("storage", result)
}

View File

@ -61,7 +61,7 @@ func TestAccOPCInstance_sharedNetworking(t *testing.T) {
resource.TestCheckResourceAttr(resName, "reverse_dns", "true"),
resource.TestCheckResourceAttr(resName, "state", "running"),
resource.TestCheckResourceAttr(resName, "tags.#", "2"),
resource.TestCheckResourceAttrSet(resName, "vcable_id"),
resource.TestCheckResourceAttrSet(resName, "vcable"),
resource.TestCheckResourceAttr(resName, "virtio", "false"),
// Check Data Source to validate networking attributes
@ -117,6 +117,26 @@ func TestAccOPCInstance_ipNetwork(t *testing.T) {
})
}
func TestAccOPCInstance_storage(t *testing.T) {
resName := "opc_compute_instance.test"
rInt := acctest.RandInt()
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccOPCCheckInstanceDestroy,
Steps: []resource.TestStep{
{
Config: testAccInstanceStorage(rInt),
Check: resource.ComposeTestCheckFunc(
testAccOPCCheckInstanceExists,
resource.TestCheckResourceAttr(resName, "storage.#", "2"),
),
},
},
})
}
func testAccOPCCheckInstanceExists(s *terraform.State) error {
client := testAccProvider.Meta().(*compute.Client).Instances()
@ -227,3 +247,31 @@ data "opc_compute_network_interface" "test" {
}
`, rInt, rInt, rInt)
}
func testAccInstanceStorage(rInt int) string {
return fmt.Sprintf(`
resource "opc_compute_storage_volume" "foo" {
name = "acc-test-instance-%d"
size = 1
}
resource "opc_compute_storage_volume" "bar" {
name = "acc-test-instance-2-%d"
size = 1
}
resource "opc_compute_instance" "test" {
name = "acc-test-instance-%d"
label = "TestAccOPCInstance_basic"
shape = "oc3"
image_list = "/oracle/public/oel_6.7_apaas_16.4.5_1610211300"
storage {
volume = "${opc_compute_storage_volume.foo.name}"
index = 1
}
storage {
volume = "${opc_compute_storage_volume.bar.name}"
index = 2
}
}`, rInt, rInt, rInt)
}

View File

@ -51,7 +51,7 @@ func resourceOPCStorageVolume() *schema.Resource {
Schema: map[string]*schema.Schema{
"image_list": {
Type: schema.TypeString,
Optional: true,
Required: true,
ForceNew: true,
},

View File

@ -365,6 +365,7 @@ func (c *InstancesClient) GetInstance(input *GetInstanceInput) (*InstanceInfo, e
responseBody.SSHKeys = sshKeyNames
responseBody.Networking = c.unqualifyNetworking(responseBody.Networking)
responseBody.Storage = c.unqualifyStorage(responseBody.Storage)
return &responseBody, nil
}
@ -538,3 +539,15 @@ func (c *InstancesClient) unqualifyNat(nat []string) []string {
}
return unQualifiedNats
}
func (c *InstancesClient) unqualifyStorage(attachments []StorageAttachment) []StorageAttachment {
unqAttachments := []StorageAttachment{}
for _, v := range attachments {
if v.StorageVolumeName != "" {
v.StorageVolumeName = c.getUnqualifiedName(v.StorageVolumeName)
}
unqAttachments = append(unqAttachments, v)
}
return unqAttachments
}

6
vendor/vendor.json vendored
View File

@ -1970,10 +1970,10 @@
"revision": "d30f09973e19c1dfcd120b2d9c4f168e68d6b5d5"
},
{
"checksumSHA1": "Sqz9+8frdOIkyK/v4IjjInZAp4Y=",
"checksumSHA1": "QKusHEboSl00AnORqkjv0gZEhqw=",
"path": "github.com/hashicorp/go-oracle-terraform/compute",
"revision": "98fdaf3c4bde245e21947487ba722c3d0abaccb2",
"revisionTime": "2017-03-29T21:19:34Z"
"revision": "15f277fb824b7af18c6bef8d30d84174154f989b",
"revisionTime": "2017-04-05T20:02:51Z"
},
{
"checksumSHA1": "DzK7lYwHt5Isq5Zf73cnQqBO2LI=",

View File

@ -37,6 +37,10 @@ resource "opc_compute_instance" "test_instance" {
vnic = "testing-vnic-name"
shared_network = false
}
storage {
volume = "${opc_compute_storage_volume.foo.name}"
index = 1
}
}
```
@ -60,6 +64,8 @@ The following arguments are supported:
* `networking_info` - (Optional) Information pertaining to an individual network interface to be created and attached to the instance. See [Networking Info](#networking-info) below for more information.
* `storage` - (Optional) Information pertaining to an individual storage attachment to be created during instance creation. Please see [Storage Attachments](#storage-attachments) below for more information.
* `reverse_dns` - (Optional) If set to `true` (default), then reverse DNS records are created. If set to `false`, no reverse DNS records are created.
* `ssh_keys` - (Optional) A list of the names of the SSH Keys that can be used to log into the instance.
@ -127,6 +133,22 @@ The following attributes are supported:
* `vnic` - (Optional, IP Network Only) The name of the vNIC created for the IP Network.
* `vnic_sets` - (Optional, IP Network Only) The array of vNIC Sets the interface was added to.
## Storage Attachments
Each Storage Attachment config manages a single storage attachment that is created _during instance creation_.
This means that any storage attachments created during instance creation cannot be detached from the instance.
Use the `resource_storage_attachment` resource to manage storage attachments for instances if you wish to detach the
storage volumes at a later date.
The following attributes are supported:
* `index` - (Required) The Index number of the volume attachment. `1` is the boot volume for the instance. Values `1-10` allowed.
* `volume` - (Required) The name of the storage volume to attach to the instance.
In addition to the above attributes, the following attributes are exported for a storage volume
* `name` - Name of the storage volume attachment.
## Attributes Reference
In addition to the attributes listed above, the following attributes are exported:

View File

@ -3,12 +3,12 @@ layout: "opc"
page_title: "Oracle: opc_compute_ip_address_reservation"
sidebar_current: "docs-opc-resource-ip-address-reservation"
description: |-
Creates and manages an IP address reservation in an OPC identity domain.
Creates and manages an IP address reservation in an OPC identity domain for an IP Network.
---
# opc\_compute\_ip\_address\_reservation
The ``opc_compute_ip_address_reservation`` resource creates and manages an IP address reservation in an OPC identity domain.
The ``opc_compute_ip_address_reservation`` resource creates and manages an IP address reservation in an OPC identity domain, for an IP Network.
## Example Usage

View File

@ -3,13 +3,13 @@ layout: "opc"
page_title: "Oracle: opc_compute_ip_association"
sidebar_current: "docs-opc-resource-ip-association"
description: |-
Creates and manages an IP association in an OPC identity domain.
Creates and manages an IP association in an OPC identity domain for the Shared Network.
---
# opc\_compute\_ip\_association
The ``opc_compute_ip_association`` resource creates and manages an association between an IP address and an instance in
an OPC identity domain.
an OPC identity domain, for the Shared Network.
## Example Usage

View File

@ -3,12 +3,12 @@ layout: "opc"
page_title: "Oracle: opc_compute_ip_reservation"
sidebar_current: "docs-opc-resource-ip-reservation"
description: |-
Creates and manages an IP reservation in an OPC identity domain.
Creates and manages an IP reservation in an OPC identity domain for the Shared Network.
---
# opc\_compute\_ip\_reservation
The ``opc_compute_ip_reservation`` resource creates and manages an IP reservation in an OPC identity domain.
The ``opc_compute_ip_reservation`` resource creates and manages an IP reservation in an OPC identity domain for the Shared Network.
## Example Usage

View File

@ -53,7 +53,7 @@ The following arguments are supported:
* `tags` - (Optional) Comma-separated strings that tag the storage volume.
`bootable` supports the following:
* `image_list` - (Optional) Defines an image list.
* `image_list` - (Required) Defines an image list.
* `image_list_entry` - (Optional) Defines an image list entry.
## Attributes Reference