From 9062ddded331f2d72bb9d475e3f6632197508c29 Mon Sep 17 00:00:00 2001 From: Jake Champlin Date: Wed, 5 Apr 2017 16:40:05 -0400 Subject: [PATCH] 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 --- builtin/providers/opc/resource_instance.go | 48 +++++++++++++----- .../providers/opc/resource_instance_test.go | 50 ++++++++++++++++++- .../providers/opc/resource_storage_volume.go | 2 +- .../go-oracle-terraform/compute/instances.go | 13 +++++ vendor/vendor.json | 6 +-- .../opc/r/opc_compute_instance.html.markdown | 22 ++++++++ ...mpute_ip_address_reservation.html.markdown | 4 +- .../opc_compute_ip_association.html.markdown | 4 +- .../opc_compute_ip_reservation.html.markdown | 4 +- .../opc_compute_storage_volume.html.markdown | 2 +- 10 files changed, 130 insertions(+), 25 deletions(-) diff --git a/builtin/providers/opc/resource_instance.go b/builtin/providers/opc/resource_instance.go index 0d509db25..2744edd5a 100644 --- a/builtin/providers/opc/resource_instance.go +++ b/builtin/providers/opc/resource_instance.go @@ -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) +} diff --git a/builtin/providers/opc/resource_instance_test.go b/builtin/providers/opc/resource_instance_test.go index 00bb66e7e..36b214db4 100644 --- a/builtin/providers/opc/resource_instance_test.go +++ b/builtin/providers/opc/resource_instance_test.go @@ -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) +} diff --git a/builtin/providers/opc/resource_storage_volume.go b/builtin/providers/opc/resource_storage_volume.go index 4f7e90260..9d5a2b13d 100644 --- a/builtin/providers/opc/resource_storage_volume.go +++ b/builtin/providers/opc/resource_storage_volume.go @@ -51,7 +51,7 @@ func resourceOPCStorageVolume() *schema.Resource { Schema: map[string]*schema.Schema{ "image_list": { Type: schema.TypeString, - Optional: true, + Required: true, ForceNew: true, }, diff --git a/vendor/github.com/hashicorp/go-oracle-terraform/compute/instances.go b/vendor/github.com/hashicorp/go-oracle-terraform/compute/instances.go index b697b36e3..7368e9ba2 100644 --- a/vendor/github.com/hashicorp/go-oracle-terraform/compute/instances.go +++ b/vendor/github.com/hashicorp/go-oracle-terraform/compute/instances.go @@ -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 +} diff --git a/vendor/vendor.json b/vendor/vendor.json index ed725ac15..63c77ed33 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -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=", diff --git a/website/source/docs/providers/opc/r/opc_compute_instance.html.markdown b/website/source/docs/providers/opc/r/opc_compute_instance.html.markdown index 56b6240c4..1198cf7ee 100644 --- a/website/source/docs/providers/opc/r/opc_compute_instance.html.markdown +++ b/website/source/docs/providers/opc/r/opc_compute_instance.html.markdown @@ -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: diff --git a/website/source/docs/providers/opc/r/opc_compute_ip_address_reservation.html.markdown b/website/source/docs/providers/opc/r/opc_compute_ip_address_reservation.html.markdown index 00f0befd9..2f95c3523 100644 --- a/website/source/docs/providers/opc/r/opc_compute_ip_address_reservation.html.markdown +++ b/website/source/docs/providers/opc/r/opc_compute_ip_address_reservation.html.markdown @@ -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 diff --git a/website/source/docs/providers/opc/r/opc_compute_ip_association.html.markdown b/website/source/docs/providers/opc/r/opc_compute_ip_association.html.markdown index a148875ff..0890dbfdb 100644 --- a/website/source/docs/providers/opc/r/opc_compute_ip_association.html.markdown +++ b/website/source/docs/providers/opc/r/opc_compute_ip_association.html.markdown @@ -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 diff --git a/website/source/docs/providers/opc/r/opc_compute_ip_reservation.html.markdown b/website/source/docs/providers/opc/r/opc_compute_ip_reservation.html.markdown index f937e03f9..1201fe9cc 100644 --- a/website/source/docs/providers/opc/r/opc_compute_ip_reservation.html.markdown +++ b/website/source/docs/providers/opc/r/opc_compute_ip_reservation.html.markdown @@ -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 diff --git a/website/source/docs/providers/opc/r/opc_compute_storage_volume.html.markdown b/website/source/docs/providers/opc/r/opc_compute_storage_volume.html.markdown index 103f48eea..7fa308ff5 100644 --- a/website/source/docs/providers/opc/r/opc_compute_storage_volume.html.markdown +++ b/website/source/docs/providers/opc/r/opc_compute_storage_volume.html.markdown @@ -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