Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

r/storagegateway_gateway - add support for smb_security_strategy #13563

Merged
merged 9 commits into from
Aug 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 53 additions & 19 deletions aws/resource_aws_storagegateway_gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ func resourceAwsStorageGatewayGateway() *schema.Resource {
Optional: true,
Computed: true,
ForceNew: true,
ValidateFunc: validation.IsIPv4Address,
ConflictsWith: []string{"activation_key"},
},
"gateway_name": {
Expand Down Expand Up @@ -139,6 +140,12 @@ func resourceAwsStorageGatewayGateway() *schema.Resource {
Optional: true,
ValidateFunc: validateArn,
},
"smb_security_strategy": {
Type: schema.TypeString,
Optional: true,
Computed: true,
ValidateFunc: validation.StringInSlice(storagegateway.SMBSecurityStrategy_Values(), false),
},
},
}
}
Expand Down Expand Up @@ -171,7 +178,7 @@ func resourceAwsStorageGatewayGatewayCreate(d *schema.ResourceData, meta interfa
log.Printf("[DEBUG] Creating HTTP request: %s", requestURL)
request, err := http.NewRequest("GET", requestURL, nil)
if err != nil {
return fmt.Errorf("error creating HTTP request: %s", err)
return fmt.Errorf("error creating HTTP request: %w", err)
}

var response *http.Response
Expand All @@ -186,7 +193,7 @@ func resourceAwsStorageGatewayGatewayCreate(d *schema.ResourceData, meta interfa
return resource.RetryableError(errMessage)
}

return resource.NonRetryableError(fmt.Errorf("error making HTTP request: %s", err))
return resource.NonRetryableError(fmt.Errorf("error making HTTP request: %w", err))
}

for _, retryableStatusCode := range []int{504} {
Expand All @@ -203,7 +210,7 @@ func resourceAwsStorageGatewayGatewayCreate(d *schema.ResourceData, meta interfa
response, err = client.Do(request)
}
if err != nil {
return fmt.Errorf("error retrieving activation key from IP Address (%s): %s", gatewayIpAddress, err)
return fmt.Errorf("error retrieving activation key from IP Address (%s): %w", gatewayIpAddress, err)
}

log.Printf("[DEBUG] Received HTTP response: %#v", response)
Expand All @@ -213,7 +220,7 @@ func resourceAwsStorageGatewayGatewayCreate(d *schema.ResourceData, meta interfa

redirectURL, err := response.Location()
if err != nil {
return fmt.Errorf("error extracting HTTP Location header: %s", err)
return fmt.Errorf("error extracting HTTP Location header: %w", err)
}

activationKey = redirectURL.Query().Get("activationKey")
Expand Down Expand Up @@ -242,13 +249,13 @@ func resourceAwsStorageGatewayGatewayCreate(d *schema.ResourceData, meta interfa
log.Printf("[DEBUG] Activating Storage Gateway Gateway: %s", input)
output, err := conn.ActivateGateway(input)
if err != nil {
return fmt.Errorf("error activating Storage Gateway Gateway: %s", err)
return fmt.Errorf("error activating Storage Gateway Gateway: %w", err)
}

d.SetId(aws.StringValue(output.GatewayARN))

if _, err := WaitForStorageGatewayGatewayConnected(conn, d.Id(), d.Timeout(schema.TimeoutCreate)); err != nil {
return fmt.Errorf("error waiting for Storage Gateway Gateway activation: %s", err)
return fmt.Errorf("error waiting for Storage Gateway Gateway activation: %w", err)
}

if v, ok := d.GetOk("smb_active_directory_settings"); ok && len(v.([]interface{})) > 0 {
Expand All @@ -264,7 +271,7 @@ func resourceAwsStorageGatewayGatewayCreate(d *schema.ResourceData, meta interfa
log.Printf("[DEBUG] Storage Gateway Gateway %q joining Active Directory domain: %s", d.Id(), m["domain_name"].(string))
_, err := conn.JoinDomain(input)
if err != nil {
return fmt.Errorf("error joining Active Directory domain: %s", err)
return fmt.Errorf("error joining Active Directory domain: %w", err)
}
}

Expand All @@ -277,7 +284,7 @@ func resourceAwsStorageGatewayGatewayCreate(d *schema.ResourceData, meta interfa
log.Printf("[DEBUG] Storage Gateway Gateway %q setting SMB guest password", d.Id())
_, err := conn.SetSMBGuestPassword(input)
if err != nil {
return fmt.Errorf("error setting SMB guest password: %s", err)
return fmt.Errorf("error setting SMB guest password: %w", err)
}
}

Expand All @@ -290,7 +297,20 @@ func resourceAwsStorageGatewayGatewayCreate(d *schema.ResourceData, meta interfa
log.Printf("[DEBUG] Storage Gateway Gateway %q setting CloudWatch Log Group", input)
_, err := conn.UpdateGatewayInformation(input)
if err != nil {
return fmt.Errorf("error setting CloudWatch Log Group: %s", err)
return fmt.Errorf("error setting CloudWatch Log Group: %w", err)
}
}

if v, ok := d.GetOk("smb_security_strategy"); ok {
input := &storagegateway.UpdateSMBSecurityStrategyInput{
GatewayARN: aws.String(d.Id()),
SMBSecurityStrategy: aws.String(v.(string)),
}

log.Printf("[DEBUG] Storage Gateway Gateway %q setting SMB Security Strategy", input)
_, err := conn.UpdateSMBSecurityStrategy(input)
if err != nil {
return fmt.Errorf("error setting SMB Security Strategy: %w", err)
}
}

Expand All @@ -315,11 +335,11 @@ func resourceAwsStorageGatewayGatewayRead(d *schema.ResourceData, meta interface
d.SetId("")
return nil
}
return fmt.Errorf("error reading Storage Gateway Gateway: %s", err)
return fmt.Errorf("error reading Storage Gateway Gateway: %w", err)
}

if err := d.Set("tags", keyvaluetags.StoragegatewayKeyValueTags(output.Tags).IgnoreAws().IgnoreConfig(ignoreTagsConfig).Map()); err != nil {
return fmt.Errorf("error setting tags: %s", err)
return fmt.Errorf("error setting tags: %w", err)
}

smbSettingsInput := &storagegateway.DescribeSMBSettingsInput{
Expand All @@ -334,7 +354,7 @@ func resourceAwsStorageGatewayGatewayRead(d *schema.ResourceData, meta interface
d.SetId("")
return nil
}
return fmt.Errorf("error reading Storage Gateway SMB Settings: %s", err)
return fmt.Errorf("error reading Storage Gateway SMB Settings: %w", err)
}

// The Storage Gateway API currently provides no way to read this value
Expand All @@ -361,7 +381,7 @@ func resourceAwsStorageGatewayGatewayRead(d *schema.ResourceData, meta interface
// to simplify schema and difference logic
if smbSettingsOutput == nil || aws.StringValue(smbSettingsOutput.DomainName) == "" {
if err := d.Set("smb_active_directory_settings", []interface{}{}); err != nil {
return fmt.Errorf("error setting smb_active_directory_settings: %s", err)
return fmt.Errorf("error setting smb_active_directory_settings: %w", err)
}
} else {
m := map[string]interface{}{
Expand All @@ -381,7 +401,7 @@ func resourceAwsStorageGatewayGatewayRead(d *schema.ResourceData, meta interface
m["username"] = configM["username"]
}
if err := d.Set("smb_active_directory_settings", []map[string]interface{}{m}); err != nil {
return fmt.Errorf("error setting smb_active_directory_settings: %s", err)
return fmt.Errorf("error setting smb_active_directory_settings: %w", err)
}
}

Expand All @@ -398,6 +418,7 @@ func resourceAwsStorageGatewayGatewayRead(d *schema.ResourceData, meta interface
// We allow Terraform to passthrough the configuration value into the state
d.Set("tape_drive_type", d.Get("tape_drive_type").(string))
d.Set("cloudwatch_log_group_arn", output.CloudWatchLogGroupARN)
d.Set("smb_security_strategy", smbSettingsOutput.SMBSecurityStrategy)

return nil
}
Expand All @@ -416,14 +437,14 @@ func resourceAwsStorageGatewayGatewayUpdate(d *schema.ResourceData, meta interfa
log.Printf("[DEBUG] Updating Storage Gateway Gateway: %s", input)
_, err := conn.UpdateGatewayInformation(input)
if err != nil {
return fmt.Errorf("error updating Storage Gateway Gateway: %s", err)
return fmt.Errorf("error updating Storage Gateway Gateway: %w", err)
}
}

if d.HasChange("tags") {
o, n := d.GetChange("tags")
if err := keyvaluetags.StoragegatewayUpdateTags(conn, d.Get("arn").(string), o, n); err != nil {
return fmt.Errorf("error updating tags: %s", err)
return fmt.Errorf("error updating tags: %w", err)
}
}

Expand All @@ -441,7 +462,7 @@ func resourceAwsStorageGatewayGatewayUpdate(d *schema.ResourceData, meta interfa
log.Printf("[DEBUG] Storage Gateway Gateway %q joining Active Directory domain: %s", d.Id(), m["domain_name"].(string))
_, err := conn.JoinDomain(input)
if err != nil {
return fmt.Errorf("error joining Active Directory domain: %s", err)
return fmt.Errorf("error joining Active Directory domain: %w", err)
}
}

Expand All @@ -454,7 +475,20 @@ func resourceAwsStorageGatewayGatewayUpdate(d *schema.ResourceData, meta interfa
log.Printf("[DEBUG] Storage Gateway Gateway %q setting SMB guest password", d.Id())
_, err := conn.SetSMBGuestPassword(input)
if err != nil {
return fmt.Errorf("error setting SMB guest password: %s", err)
return fmt.Errorf("error setting SMB guest password: %w", err)
}
}

if d.HasChange("smb_security_strategy") {
input := &storagegateway.UpdateSMBSecurityStrategyInput{
GatewayARN: aws.String(d.Id()),
SMBSecurityStrategy: aws.String(d.Get("smb_security_strategy").(string)),
}

log.Printf("[DEBUG] Storage Gateway Gateway %q updating SMB Security Strategy", input)
_, err := conn.UpdateSMBSecurityStrategy(input)
if err != nil {
return fmt.Errorf("error updating SMB Security Strategy: %w", err)
}
}

Expand All @@ -474,7 +508,7 @@ func resourceAwsStorageGatewayGatewayDelete(d *schema.ResourceData, meta interfa
if isAWSErrStorageGatewayGatewayNotFound(err) {
return nil
}
return fmt.Errorf("error deleting Storage Gateway Gateway: %s", err)
return fmt.Errorf("error deleting Storage Gateway Gateway: %w", err)
}

return nil
Expand Down
73 changes: 71 additions & 2 deletions aws/resource_aws_storagegateway_gateway_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func init() {
func testSweepStorageGatewayGateways(region string) error {
client, err := sharedClientForRegion(region)
if err != nil {
return fmt.Errorf("error getting client: %s", err)
return fmt.Errorf("error getting client: %w", err)
}
conn := client.(*AWSClient).storagegatewayconn

Expand Down Expand Up @@ -57,7 +57,7 @@ func testSweepStorageGatewayGateways(region string) error {
log.Printf("[WARN] Skipping Storage Gateway Gateway sweep for %s: %s", region, err)
return nil
}
return fmt.Errorf("Error retrieving Storage Gateway Gateways: %s", err)
return fmt.Errorf("Error retrieving Storage Gateway Gateways: %w", err)
}
return nil
}
Expand All @@ -84,6 +84,7 @@ func TestAccAWSStorageGatewayGateway_GatewayType_Cached(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "medium_changer_type", ""),
resource.TestCheckResourceAttr(resourceName, "smb_active_directory_settings.#", "0"),
resource.TestCheckResourceAttr(resourceName, "smb_guest_password", ""),
resource.TestCheckResourceAttr(resourceName, "smb_security_strategy", ""),
resource.TestCheckResourceAttr(resourceName, "tape_drive_type", ""),
),
},
Expand Down Expand Up @@ -435,6 +436,62 @@ func TestAccAWSStorageGatewayGateway_SmbGuestPassword(t *testing.T) {
})
}

func TestAccAWSStorageGatewayGateway_SMBSecurityStrategy(t *testing.T) {
var gateway storagegateway.DescribeGatewayInformationOutput
rName := acctest.RandomWithPrefix("tf-acc-test")
resourceName := "aws_storagegateway_gateway.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSStorageGatewayGatewayDestroy,
Steps: []resource.TestStep{
{
Config: testAccAWSStorageGatewayGatewayConfigSMBSecurityStrategy(rName, "ClientSpecified"),
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSStorageGatewayGatewayExists(resourceName, &gateway),
resource.TestCheckResourceAttr(resourceName, "smb_security_strategy", "ClientSpecified"),
),
},
{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"activation_key", "gateway_ip_address"},
},
{
Config: testAccAWSStorageGatewayGatewayConfigSMBSecurityStrategy(rName, "MandatorySigning"),
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSStorageGatewayGatewayExists(resourceName, &gateway),
resource.TestCheckResourceAttr(resourceName, "smb_security_strategy", "MandatorySigning"),
),
},
},
})
}

func TestAccAWSStorageGatewayGateway_disappears(t *testing.T) {
var gateway storagegateway.DescribeGatewayInformationOutput
rName := acctest.RandomWithPrefix("tf-acc-test")
resourceName := "aws_storagegateway_gateway.test"

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckAWSStorageGatewayGatewayDestroy,
Steps: []resource.TestStep{
{
Config: testAccAWSStorageGatewayGatewayConfig_GatewayType_Cached(rName),
Check: resource.ComposeTestCheckFunc(
testAccCheckAWSStorageGatewayGatewayExists(resourceName, &gateway),
testAccCheckResourceDisappears(testAccProvider, resourceAwsStorageGatewayGateway(), resourceName),
),
ExpectNonEmptyPlan: true,
},
},
})
}

func testAccCheckAWSStorageGatewayGatewayDestroy(s *terraform.State) error {
conn := testAccProvider.Meta().(*AWSClient).storagegatewayconn

Expand Down Expand Up @@ -844,6 +901,18 @@ resource "aws_storagegateway_gateway" "test" {
`, rName, smbGuestPassword)
}

func testAccAWSStorageGatewayGatewayConfigSMBSecurityStrategy(rName, strategy string) string {
return testAccAWSStorageGateway_FileGatewayBase(rName) + fmt.Sprintf(`
resource "aws_storagegateway_gateway" "test" {
gateway_ip_address = aws_instance.test.public_ip
gateway_name = %q
gateway_timezone = "GMT"
gateway_type = "FILE_S3"
smb_security_strategy = %q
}
`, rName, strategy)
}

func testAccAWSStorageGatewayGatewayConfigTags1(rName, tagKey1, tagValue1 string) string {
return testAccAWSStorageGateway_TapeAndVolumeGatewayBase(rName) + fmt.Sprintf(`
resource "aws_storagegateway_gateway" "test" {
Expand Down
1 change: 1 addition & 0 deletions website/docs/r/storagegateway_gateway.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ The following arguments are supported:
* `medium_changer_type` - (Optional) Type of medium changer to use for tape gateway. Terraform cannot detect drift of this argument. Valid values: `STK-L700`, `AWS-Gateway-VTL`.
* `smb_active_directory_settings` - (Optional) Nested argument with Active Directory domain join information for Server Message Block (SMB) file shares. Only valid for `FILE_S3` gateway type. Must be set before creating `ActiveDirectory` authentication SMB file shares. More details below.
* `smb_guest_password` - (Optional) Guest password for Server Message Block (SMB) file shares. Only valid for `FILE_S3` gateway type. Must be set before creating `GuestAccess` authentication SMB file shares. Terraform can only detect drift of the existence of a guest password, not its actual value from the gateway. Terraform can however update the password with changing the argument.
* `smb_security_strategy` - (Optional) Specifies the type of security strategy. Valid values are: `ClientSpecified`, `MandatorySigning`, and `MandatoryEncryption`. See [Setting a Security Level for Your Gateway](https://docs.aws.amazon.com/storagegateway/latest/userguide/managing-gateway-file.html#security-strategy) for more information.
* `tape_drive_type` - (Optional) Type of tape drive to use for tape gateway. Terraform cannot detect drift of this argument. Valid values: `IBM-ULT3580-TD5`.
* `tags` - (Optional) Key-value map of resource tags

Expand Down