Skip to content

Commit

Permalink
New Resource: aws_storagegateway_cache
Browse files Browse the repository at this point in the history
  • Loading branch information
bflad committed Jul 27, 2018
1 parent 34a7ab1 commit db9b9b1
Show file tree
Hide file tree
Showing 5 changed files with 344 additions and 0 deletions.
1 change: 1 addition & 0 deletions aws/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -585,6 +585,7 @@ func Provider() terraform.ResourceProvider {
"aws_ssm_patch_group": resourceAwsSsmPatchGroup(),
"aws_ssm_parameter": resourceAwsSsmParameter(),
"aws_ssm_resource_data_sync": resourceAwsSsmResourceDataSync(),
"aws_storagegateway_cache": resourceAwsStorageGatewayCache(),
"aws_storagegateway_gateway": resourceAwsStorageGatewayGateway(),
"aws_storagegateway_nfs_file_share": resourceAwsStorageGatewayNfsFileShare(),
"aws_storagegateway_upload_buffer": resourceAwsStorageGatewayUploadBuffer(),
Expand Down
131 changes: 131 additions & 0 deletions aws/resource_aws_storagegateway_cache.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
package aws

import (
"fmt"
"log"
"strings"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/arn"
"github.com/aws/aws-sdk-go/service/storagegateway"
"github.com/hashicorp/terraform/helper/schema"
)

func resourceAwsStorageGatewayCache() *schema.Resource {
return &schema.Resource{
Create: resourceAwsStorageGatewayCacheCreate,
Read: resourceAwsStorageGatewayCacheRead,
Delete: schema.Noop,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},

Schema: map[string]*schema.Schema{
"disk_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"gateway_arn": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validateArn,
},
},
}
}

func resourceAwsStorageGatewayCacheCreate(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).storagegatewayconn

diskID := d.Get("disk_id").(string)
gatewayARN := d.Get("gateway_arn").(string)

input := &storagegateway.AddCacheInput{
DiskIds: []*string{aws.String(diskID)},
GatewayARN: aws.String(gatewayARN),
}

log.Printf("[DEBUG] Adding Storage Gateway cache: %s", input)
_, err := conn.AddCache(input)
if err != nil {
return fmt.Errorf("error adding Storage Gateway cache: %s", err)
}

d.SetId(fmt.Sprintf("%s:%s", gatewayARN, diskID))

return resourceAwsStorageGatewayCacheRead(d, meta)
}

func resourceAwsStorageGatewayCacheRead(d *schema.ResourceData, meta interface{}) error {
conn := meta.(*AWSClient).storagegatewayconn

gatewayARN, diskID, err := decodeStorageGatewayID(d.Id())
if err != nil {
return err
}

input := &storagegateway.DescribeCacheInput{
GatewayARN: aws.String(gatewayARN),
}

log.Printf("[DEBUG] Reading Storage Gateway cache: %s", input)
output, err := conn.DescribeCache(input)
if err != nil {
if isAWSErrStorageGatewayGatewayNotFound(err) {
log.Printf("[WARN] Storage Gateway cache %q not found - removing from state", d.Id())
d.SetId("")
return nil
}
return fmt.Errorf("error reading Storage Gateway cache: %s", err)
}

if output == nil || len(output.DiskIds) == 0 {
log.Printf("[WARN] Storage Gateway cache %q not found - removing from state", d.Id())
d.SetId("")
return nil
}

found := false
for _, existingDiskID := range output.DiskIds {
if aws.StringValue(existingDiskID) == diskID {
found = true
break
}
}

if !found {
log.Printf("[WARN] Storage Gateway cache %q not found - removing from state", d.Id())
d.SetId("")
return nil
}

d.Set("disk_id", diskID)
d.Set("gateway_arn", gatewayARN)

return nil
}

func decodeStorageGatewayID(id string) (string, string, error) {
// id = arn:aws:storagegateway:us-east-1:123456789012:gateway/sgw-12345678:pci-0000:03:00.0-scsi-0:0:0:0
idFormatErr := fmt.Errorf("expected ID in form of GatewayARN:DiskId, received: %s", id)
gatewayARNAndDisk, err := arn.Parse(id)
if err != nil {
return "", "", idFormatErr
}
// gatewayARNAndDisk.Resource = gateway/sgw-12345678:pci-0000:03:00.0-scsi-0:0:0:0
resourceParts := strings.SplitN(gatewayARNAndDisk.Resource, ":", 2)
if len(resourceParts) != 2 {
return "", "", idFormatErr
}
// resourceParts = ["gateway/sgw-12345678", "pci-0000:03:00.0-scsi-0:0:0:0"]
gatewayARN := &arn.ARN{
AccountID: gatewayARNAndDisk.AccountID,
Partition: gatewayARNAndDisk.Partition,
Region: gatewayARNAndDisk.Region,
Service: gatewayARNAndDisk.Service,
Resource: resourceParts[0],
}
return gatewayARN.String(), resourceParts[1], nil
}
165 changes: 165 additions & 0 deletions aws/resource_aws_storagegateway_cache_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
package aws

import (
"fmt"
"regexp"
"testing"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/storagegateway"
"github.com/hashicorp/terraform/helper/acctest"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
)

func TestDecodeStorageGatewayCacheID(t *testing.T) {
var testCases = []struct {
Input string
ExpectedGatewayARN string
ExpectedDiskID string
ErrCount int
}{
{
Input: "arn:aws:storagegateway:us-east-1:123456789012:gateway/sgw-12345678:pci-0000:03:00.0-scsi-0:0:0:0",
ExpectedGatewayARN: "arn:aws:storagegateway:us-east-1:123456789012:gateway/sgw-12345678",
ExpectedDiskID: "pci-0000:03:00.0-scsi-0:0:0:0",
ErrCount: 0,
},
{
Input: "sgw-12345678:pci-0000:03:00.0-scsi-0:0:0:0",
ErrCount: 1,
},
{
Input: "example:pci-0000:03:00.0-scsi-0:0:0:0",
ErrCount: 1,
},
{
Input: "arn:aws:storagegateway:us-east-1:123456789012:gateway/sgw-12345678",
ErrCount: 1,
},
{
Input: "pci-0000:03:00.0-scsi-0:0:0:0",
ErrCount: 1,
},
{
Input: "gateway/sgw-12345678",
ErrCount: 1,
},
{
Input: "sgw-12345678",
ErrCount: 1,
},
}

for _, tc := range testCases {
gatewayARN, diskID, err := decodeStorageGatewayID(tc.Input)
if tc.ErrCount == 0 && err != nil {
t.Fatalf("expected %q not to trigger an error, received: %s", tc.Input, err)
}
if tc.ErrCount > 0 && err == nil {
t.Fatalf("expected %q to trigger an error", tc.Input)
}
if gatewayARN != tc.ExpectedGatewayARN {
t.Fatalf("expected %q to return Gateway ARN %q, received: %s", tc.Input, tc.ExpectedGatewayARN, gatewayARN)
}
if diskID != tc.ExpectedDiskID {
t.Fatalf("expected %q to return Disk ID %q, received: %s", tc.Input, tc.ExpectedDiskID, diskID)
}
}
}

func TestAccAWSStorageGatewayCache_Basic(t *testing.T) {
rName := acctest.RandomWithPrefix("tf-acc-test")
resourceName := "aws_storagegateway_cache.test"

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
// Storage Gateway API does not support removing caches
// CheckDestroy: testAccCheckAWSStorageGatewayCacheDestroy,
Steps: []resource.TestStep{
{
Config: testAccAWSStorageGatewayCacheConfig_Basic(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSStorageGatewayCacheExists(resourceName),
resource.TestCheckResourceAttrSet(resourceName, "disk_id"),
resource.TestMatchResourceAttr(resourceName, "gateway_arn", regexp.MustCompile(`^arn:[^:]+:storagegateway:[^:]+:[^:]+:gateway/sgw-.+$`)),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

func testAccCheckAWSStorageGatewayCacheExists(resourceName string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[resourceName]
if !ok {
return fmt.Errorf("Not found: %s", resourceName)
}

conn := testAccProvider.Meta().(*AWSClient).storagegatewayconn

gatewayARN, diskID, err := decodeStorageGatewayID(rs.Primary.ID)
if err != nil {
return err
}

input := &storagegateway.DescribeCacheInput{
GatewayARN: aws.String(gatewayARN),
}

output, err := conn.DescribeCache(input)

if err != nil {
return fmt.Errorf("error reading Storage Gateway cache: %s", err)
}

if output == nil || len(output.DiskIds) == 0 {
return fmt.Errorf("Storage Gateway cache %q not found", rs.Primary.ID)
}

for _, existingDiskID := range output.DiskIds {
if aws.StringValue(existingDiskID) == diskID {
return nil
}
}

return fmt.Errorf("Storage Gateway cache %q not found", rs.Primary.ID)
}
}

func testAccAWSStorageGatewayCacheConfig_Basic(rName string) string {
return testAccAWSStorageGatewayGatewayConfig_GatewayType_FileS3(rName) + fmt.Sprintf(`
resource "aws_ebs_volume" "test" {
availability_zone = "${aws_instance.test.availability_zone}"
size = "10"
type = "gp2"
tags {
Name = %q
}
}
resource "aws_volume_attachment" "test" {
device_name = "/dev/xvdb"
force_detach = true
instance_id = "${aws_instance.test.id}"
volume_id = "${aws_ebs_volume.test.id}"
}
data "aws_storagegateway_local_disk" "test" {
disk_path = "${aws_volume_attachment.test.device_name}"
gateway_arn = "${aws_storagegateway_gateway.test.arn}"
}
resource "aws_storagegateway_cache" "test" {
disk_id = "${data.aws_storagegateway_local_disk.test.id}"
gateway_arn = "${aws_storagegateway_gateway.test.arn}"
}
`, rName)
}
4 changes: 4 additions & 0 deletions website/aws.erb
Original file line number Diff line number Diff line change
Expand Up @@ -2140,6 +2140,10 @@
<a href="#">Storage Gateway Resources</a>
<ul class="nav nav-visible">

<li<%= sidebar_current("docs-aws-resource-storagegateway-cache") %>>
<a href="/docs/providers/aws/r/storagegateway_cache.html">aws_storagegateway_cache</a>
</li>

<li<%= sidebar_current("docs-aws-resource-storagegateway-gateway") %>>
<a href="/docs/providers/aws/r/storagegateway_gateway.html">aws_storagegateway_gateway</a>
</li>
Expand Down
43 changes: 43 additions & 0 deletions website/docs/r/storagegateway_cache.html.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
layout: "aws"
page_title: "AWS: aws_storagegateway_cache"
sidebar_current: "docs-aws-resource-storagegateway-cache"
description: |-
Manages an AWS Storage Gateway cache
---

# aws_storagegateway_cache

Manages an AWS Storage Gateway cache.

~> **NOTE:** The Storage Gateway API provides no method to remove a cache disk. Destroying this Terraform resource does not perform any Storage Gateway actions.

## Example Usage

```hcl
resource "aws_storagegateway_cache" "example" {
disk_id = "${data.aws_storagegateway_local_disk.example.id}"
gateway_arn = "${aws_storagegateway_gateway.example.arn}"
}
```

## Argument Reference

The following arguments are supported:

* `disk_id` - (Required) Local disk identifier. For example, `pci-0000:03:00.0-scsi-0:0:0:0`.
* `gateway_arn` - (Required) The Amazon Resource Name (ARN) of the gateway.

## Attribute Reference

In addition to all arguments above, the following attributes are exported:

* `id` - Combined gateway Amazon Resource Name (ARN) and local disk identifier.

## Import

`aws_storagegateway_cache` can be imported by using the gateway Amazon Resource Name (ARN) and local disk identifier separated with a colon (`:`), e.g.

```
$ terraform import aws_storagegateway_cache.example arn:aws:storagegateway:us-east-1:123456789012:gateway/sgw-12345678:pci-0000:03:00.0-scsi-0:0:0:0
```

0 comments on commit db9b9b1

Please sign in to comment.