forked from hashicorp/terraform-provider-aws
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge remote-tracking branch 'gazoakley/new_sechub_resources' into v2…
….58.0-custom
- Loading branch information
Showing
6 changed files
with
307 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,123 @@ | ||
package aws | ||
|
||
import ( | ||
"fmt" | ||
"log" | ||
|
||
"github.com/aws/aws-sdk-go/aws" | ||
"github.com/aws/aws-sdk-go/service/securityhub" | ||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" | ||
) | ||
|
||
func resourceAwsSecurityHubInviteAccepter() *schema.Resource { | ||
return &schema.Resource{ | ||
Create: resourceAwsSecurityHubInviteAccepterCreate, | ||
Read: resourceAwsSecurityHubInviteAccepterRead, | ||
Delete: resourceAwsSecurityHubInviteAccepterDelete, | ||
Importer: &schema.ResourceImporter{ | ||
State: schema.ImportStatePassthrough, | ||
}, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
"master_id": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
ForceNew: true, | ||
}, | ||
|
||
"invitation_id": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func resourceAwsSecurityHubInviteAccepterCreate(d *schema.ResourceData, meta interface{}) error { | ||
conn := meta.(*AWSClient).securityhubconn | ||
log.Print("[DEBUG] Accepting Security Hub invitation") | ||
|
||
invitationId, err := resourceAwsSecurityHubInviteAccepterGetInvitationId(conn, d.Get("master_id").(string)) | ||
|
||
if err != nil { | ||
return err | ||
} | ||
|
||
_, err = conn.AcceptInvitation(&securityhub.AcceptInvitationInput{ | ||
InvitationId: aws.String(invitationId), | ||
MasterId: aws.String(d.Get("master_id").(string)), | ||
}) | ||
|
||
if err != nil { | ||
return fmt.Errorf("Error accepting Security Hub invitation: %s", err) | ||
} | ||
|
||
d.SetId("securityhub-invitation-accepter") | ||
|
||
return resourceAwsSecurityHubInviteAccepterRead(d, meta) | ||
} | ||
|
||
func resourceAwsSecurityHubInviteAccepterGetInvitationId(conn *securityhub.SecurityHub, masterId string) (string, error) { | ||
log.Printf("[DEBUG] Getting InvitationId for MasterId %s", masterId) | ||
|
||
resp, err := conn.ListInvitations(&securityhub.ListInvitationsInput{}) | ||
|
||
if err != nil { | ||
return "", fmt.Errorf("Error listing Security Hub invitations: %s", err) | ||
} | ||
|
||
for _, invitation := range resp.Invitations { | ||
log.Printf("[DEBUG] Invitation: %s", invitation) | ||
if *invitation.AccountId == masterId { | ||
return *invitation.InvitationId, nil | ||
} | ||
} | ||
|
||
return "", fmt.Errorf("Cannot find InvitationId for MasterId %s", masterId) | ||
} | ||
|
||
func resourceAwsSecurityHubInviteAccepterRead(d *schema.ResourceData, meta interface{}) error { | ||
conn := meta.(*AWSClient).securityhubconn | ||
log.Print("[DEBUG] Reading Security Hub master account") | ||
|
||
resp, err := conn.GetMasterAccount(&securityhub.GetMasterAccountInput{}) | ||
|
||
if err != nil { | ||
if isAWSErr(err, securityhub.ErrCodeResourceNotFoundException, "") { | ||
log.Print("[WARN] Security Hub master account not found, removing from state") | ||
d.SetId("") | ||
return nil | ||
} | ||
return err | ||
} | ||
|
||
master := resp.Master | ||
|
||
if master == nil { | ||
log.Print("[WARN] Security Hub master account not found, removing from state") | ||
d.SetId("") | ||
return nil | ||
} | ||
|
||
d.Set("invitation_id", master.InvitationId) | ||
d.Set("master_id", master.AccountId) | ||
|
||
return nil | ||
} | ||
|
||
func resourceAwsSecurityHubInviteAccepterDelete(d *schema.ResourceData, meta interface{}) error { | ||
conn := meta.(*AWSClient).securityhubconn | ||
log.Print("[DEBUG] Disassociating from Security Hub master account") | ||
|
||
_, err := conn.DisassociateFromMasterAccount(&securityhub.DisassociateFromMasterAccountInput{}) | ||
|
||
if err != nil { | ||
if isAWSErr(err, "BadRequestException", "The request is rejected because the current account is not associated to a master account") { | ||
log.Print("[WARN] Security Hub account is not a member account") | ||
return nil | ||
} | ||
return err | ||
} | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
package aws | ||
|
||
import ( | ||
"fmt" | ||
"testing" | ||
|
||
"github.com/aws/aws-sdk-go/aws" | ||
"github.com/aws/aws-sdk-go/service/securityhub" | ||
"github.com/hashicorp/terraform-plugin-sdk/helper/resource" | ||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema" | ||
"github.com/hashicorp/terraform-plugin-sdk/terraform" | ||
) | ||
|
||
func TestAccAWSSecurityHubInviteAccepter_basic(t *testing.T) { | ||
var providers []*schema.Provider | ||
resourceName := "aws_securityhub_invite_accepter.example" | ||
|
||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { | ||
testAccPreCheck(t) | ||
testAccAlternateAccountPreCheck(t) | ||
testAccAccountEmailPreCheck(t) | ||
}, | ||
ProviderFactories: testAccProviderFactories(&providers), | ||
CheckDestroy: testAccCheckAWSSecurityHubInviteAccepterDestroy, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: testAccAWSSecurityHubInviteAccepterConfig_basic(testAccGetAccountEmail()), | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccCheckAWSSecurityHubInviteAccepterExists(resourceName), | ||
), | ||
}, | ||
{ | ||
Config: testAccAWSSecurityHubInviteAccepterConfig_basic(testAccGetAccountEmail()), | ||
ResourceName: resourceName, | ||
ImportState: true, | ||
ImportStateVerify: true, | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func testAccCheckAWSSecurityHubInviteAccepterExists(resourceName string) resource.TestCheckFunc { | ||
return func(s *terraform.State) error { | ||
_, ok := s.RootModule().Resources[resourceName] | ||
if !ok { | ||
return fmt.Errorf("Not found: %s", resourceName) | ||
} | ||
|
||
conn := testAccProvider.Meta().(*AWSClient).securityhubconn | ||
|
||
resp, err := conn.GetMasterAccount(&securityhub.GetMasterAccountInput{}) | ||
|
||
if err != nil { | ||
return err | ||
} | ||
|
||
if resp == nil || resp.Master == nil || aws.StringValue(resp.Master.AccountId) == "" { | ||
return fmt.Errorf("Security Hub master account found for: %s", resourceName) | ||
} | ||
|
||
return nil | ||
} | ||
} | ||
|
||
func testAccCheckAWSSecurityHubInviteAccepterDestroy(s *terraform.State) error { | ||
conn := testAccProvider.Meta().(*AWSClient).securityhubconn | ||
|
||
for _, rs := range s.RootModule().Resources { | ||
if rs.Type != "aws_securityhub_invite_accepter" { | ||
continue | ||
} | ||
|
||
resp, err := conn.GetMasterAccount(&securityhub.GetMasterAccountInput{}) | ||
|
||
if err != nil { | ||
if isAWSErr(err, securityhub.ErrCodeResourceNotFoundException, "") { | ||
continue | ||
} | ||
return err | ||
} | ||
|
||
if resp == nil || resp.Master == nil || aws.StringValue(resp.Master.AccountId) == "" { | ||
continue | ||
} | ||
|
||
return fmt.Errorf("Security Hub master account still configured: %s", aws.StringValue(resp.Master.AccountId)) | ||
} | ||
return nil | ||
} | ||
|
||
func testAccAWSSecurityHubInviteAccepterConfig_basic(email string) string { | ||
return testAccAlternateAccountProviderConfig() + fmt.Sprintf(` | ||
resource "aws_securityhub_account" "example" { | ||
provider = "aws.alternate" | ||
} | ||
resource "aws_securityhub_member" "example" { | ||
provider = "aws.alternate" | ||
depends_on = [aws_securityhub_account.example] | ||
account_id = data.aws_caller_identity.accepter.account_id | ||
email = "%s" | ||
invite = true | ||
} | ||
data "aws_caller_identity" "accepter" {} | ||
resource "aws_securityhub_account" "accepter" {} | ||
resource "aws_securityhub_invite_accepter" "example" { | ||
depends_on = [aws_securityhub_account.accepter] | ||
master_id = aws_securityhub_member.example.master_id | ||
} | ||
`, email) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
--- | ||
subcategory: "Security Hub" | ||
layout: "aws" | ||
page_title: "AWS: aws_securityhub_invite_accepter" | ||
description: |- | ||
Accepts a Security Hub invitation. | ||
--- | ||
|
||
# aws_securityhub_invite_accepter | ||
|
||
-> **Note:** AWS accounts can only be associated with a single Security Hub master account. Destroying this resource will disassociate the member account from the master account. | ||
|
||
Accepts a Security Hub invitation. | ||
|
||
## Example Usage | ||
|
||
```hcl | ||
resource "aws_securityhub_account" "example" {} | ||
resource "aws_securityhub_member" "example" { | ||
account_id = "123456789012" | ||
email = "[email protected]" | ||
invite = true | ||
} | ||
resource "aws_securityhub_account" "invitee" { | ||
provider = "aws.invitee" | ||
} | ||
resource "aws_securityhub_invite_accepter" "invitee" { | ||
provider = "aws.invitee" | ||
depends_on = [aws_securityhub_account.accepter] | ||
master_id = aws_securityhub_member.example.master_id | ||
} | ||
``` | ||
|
||
## Argument Reference | ||
|
||
The following arguments are supported: | ||
|
||
* `master_id` - (Required) The account ID of the master Security Hub account whose invitation you're accepting. | ||
|
||
## Attributes Reference | ||
|
||
The following attributes are exported in addition to the arguments listed above: | ||
|
||
* `id` - Returns `securityhub-invite-accepter`. | ||
|
||
## Import | ||
|
||
Security Hub invite acceptance can be imported using the word `securityhub-invite-accepter`, e.g. | ||
|
||
``` | ||
$ terraform import aws_securityhub_invite_acceptor.example securityhub-invite-accepter | ||
``` |