Skip to content

Commit

Permalink
Merge pull request #21 from imperva/matt/wait-on-connect-disconnect
Browse files Browse the repository at this point in the history
Wait for connect/disconnect to update asset
  • Loading branch information
mattJsonar authored Oct 30, 2024
2 parents f293db8 + 6effb13 commit 536721c
Show file tree
Hide file tree
Showing 17 changed files with 974 additions and 324 deletions.
2 changes: 1 addition & 1 deletion GNUmakefile
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ test: fmtcheck
xargs -t -n4 go test $(TESTARGS) -timeout=30s -parallel=4

testacc: fmtcheck
TF_ACC=1 go test $(TEST) -v $(TESTARGS) -timeout 120m
TF_ACC=1 go test $(TEST) -v $(TESTARGS) -timeout 120m -parallel=4

vet:
@echo "go vet ."
Expand Down
26 changes: 13 additions & 13 deletions dsfhub/provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,18 @@ var testAccProviderConfigure sync.Once
func init() {
testAccProvider = Provider()
testAccProviders = map[string]*schema.Provider{
"dsf": testAccProvider,
"dsfhub": testAccProvider,
}
}

//func TestProvider(t *testing.T) {
// log.Printf("======================== BEGIN TEST ========================")
// log.Printf("[DEBUG] Running test TestProvider")
// if err := Provider().InternalValidate(); err != nil {
// log.Printf("[INFO] err: %s \n", err)
// t.Fatalf("err: %s", err)
// }
//}
func TestProvider(t *testing.T) {
log.Printf("======================== BEGIN TEST ========================")
log.Printf("[DEBUG] Running test TestProvider")
if err := Provider().InternalValidate(); err != nil {
log.Printf("[INFO] err: %s \n", err)
t.Fatalf("err: %s", err)
}
}

func TestProvider_impl(t *testing.T) {
var _ *schema.Provider = Provider()
Expand All @@ -38,12 +38,12 @@ func testAccPreCheck(t *testing.T) {
log.Printf("======================== BEGIN TEST ========================")
log.Printf("[INFO] Running test testAccPreCheck \n")
testAccProviderConfigure.Do(func() {
if v := os.Getenv("DSF_TOKEN"); v == "" {
t.Fatal("DSF_TOKEN must be set for acceptance tests")
if v := os.Getenv("DSFHUB_TOKEN"); v == "" {
t.Fatal("DSFHUB_TOKEN must be set for acceptance tests")
}

if v := os.Getenv("DSF_HOST"); v == "" {
t.Fatal("DSF_HOST must be set for acceptance tests")
if v := os.Getenv("DSFHUB_HOST"); v == "" {
t.Fatal("DSFHUB_HOST must be set for acceptance tests")
}

err := testAccProvider.Configure(context.Background(), terraform.NewResourceConfigRaw(nil))
Expand Down
61 changes: 38 additions & 23 deletions dsfhub/resource_cloud_account.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,21 @@ package dsfhub

import (
"bytes"
"context"
"fmt"
"log"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
)

func resourceCloudAccount() *schema.Resource {
return &schema.Resource{
Create: resourceCloudAccountCreate,
Read: resourceCloudAccountRead,
Update: resourceCloudAccountUpdate,
Delete: resourceCloudAccountDelete,
CreateContext: resourceCloudAccountCreateContext,
ReadContext: resourceCloudAccountReadContext,
UpdateContext: resourceCloudAccountUpdateContext,
DeleteContext: resourceCloudAccountDeleteContext,
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},
Expand Down Expand Up @@ -109,14 +111,13 @@ func resourceCloudAccount() *schema.Resource {
Description: "The Access key ID of AWS secret access key used to authenticate",
Optional: true,
Default: nil,
Computed: true,
},
"access_key": {
Type: schema.TypeString,
Description: "The Secret access key used to authenticate",
Optional: true,
Default: nil,
Computed: true,
Required: false,
},
"amazon_secret": {
Type: schema.TypeSet,
Expand Down Expand Up @@ -161,7 +162,6 @@ func resourceCloudAccount() *schema.Resource {
Description: "This is also referred to as the Client ID and it’s the unique identifier for the registered application being used to execute Python SDK commands against Azure’s API services. You can find this number under Azure Active Directory -> App Registrations -> Owned Applications",
Optional: true,
Default: nil,
Computed: true,
},
"auth_mechanism": {
Type: schema.TypeString,
Expand Down Expand Up @@ -339,7 +339,8 @@ func resourceCloudAccount() *schema.Resource {
Description: "The Secret access key used to authenticate",
Required: false,
Optional: true,
Default: false,
Default: nil,
Sensitive: true,
},
"ssl": {
Type: schema.TypeBool,
Expand Down Expand Up @@ -496,31 +497,36 @@ func resourceCloudAccount() *schema.Resource {
}
}

func resourceCloudAccountCreate(d *schema.ResourceData, m interface{}) error {
func resourceCloudAccountCreateContext(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
client := m.(*Client)
if isOk, err := checkResourceRequiredFields(requiredCloudAccountJson, ignoreCloudAccountParamsByServerType, d); !isOk {
return err
return diag.FromErr(err)
}

// check provided fields against schema
cloudAccount := ResourceWrapper{}
serverType := d.Get("server_type").(string)
createResource(&cloudAccount, serverType, d)

// create resource
log.Printf("[INFO] Creating CloudAccount for serverType: %s and gatewayId: %s gatewayId: \n", serverType, cloudAccount.Data.GatewayID)
createCloudAccountResponse, err := client.CreateCloudAccount(cloudAccount)

if err != nil {
log.Printf("[ERROR] adding CloudAccount for serverType: %s and gatewayId: %s | err: %s", serverType, cloudAccount.Data.GatewayID, err)
return err
return diag.FromErr(err)
}

// set ID
cloudAccountId := createCloudAccountResponse.Data.AssetData.AssetID
d.SetId(cloudAccountId)

// Set the rest of the state from the resource read
return resourceCloudAccountRead(d, m)
resourceCloudAccountReadContext(ctx, d, m)

return nil
}

func resourceCloudAccountRead(d *schema.ResourceData, m interface{}) error {
func resourceCloudAccountReadContext(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
client := m.(*Client)
cloudAccountId := d.Id()

Expand All @@ -530,7 +536,7 @@ func resourceCloudAccountRead(d *schema.ResourceData, m interface{}) error {

if err != nil {
log.Printf("[ERROR] Reading cloudAccountReadResponse with cloudAccountId: %s | err: %s\n", cloudAccountId, err)
return err
return diag.FromErr(err)
}

if cloudAccountReadResponse != nil {
Expand All @@ -546,7 +552,9 @@ func resourceCloudAccountRead(d *schema.ResourceData, m interface{}) error {
d.Set("asset_id", cloudAccountReadResponse.Data.AssetData.AssetID)
d.Set("asset_source", cloudAccountReadResponse.Data.AssetData.AssetSource)
d.Set("available_regions", cloudAccountReadResponse.Data.AssetData.AvailableRegions)
d.Set("credential_endpoint", cloudAccountReadResponse.Data.AssetData.CredentialsEndpoint)
if cloudAccountReadResponse.Data.AssetData.CredentialsEndpoint != "" {
d.Set("credential_endpoint", cloudAccountReadResponse.Data.AssetData.CredentialsEndpoint)
}
d.Set("criticality", cloudAccountReadResponse.Data.AssetData.Criticality)
d.Set("gateway_id", cloudAccountReadResponse.Data.GatewayID)
d.Set("jsonar_uid", cloudAccountReadResponse.Data.AssetData.JsonarUID)
Expand Down Expand Up @@ -642,38 +650,45 @@ func resourceCloudAccountRead(d *schema.ResourceData, m interface{}) error {

connections.Add(connection)
}
d.Set("ca_connection", connections)
d.Set("asset_connection", connections)

log.Printf("[INFO] Finished reading CloudAccount with cloudAccountId: %s\n", cloudAccountId)

return nil
}

func resourceCloudAccountUpdate(d *schema.ResourceData, m interface{}) error {
func resourceCloudAccountUpdateContext(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
client := m.(*Client)

// check provided fields against schema
cloudAccountId := d.Id()
if isOk, err := checkResourceRequiredFields(requiredCloudAccountJson, ignoreCloudAccountParamsByServerType, d); !isOk {
return err
return diag.FromErr(err)
}

// convert provided fields into API payload
cloudAccount := ResourceWrapper{}
serverType := d.Get("server_type").(string)
createResource(&cloudAccount, serverType, d)

// update resource
log.Printf("[INFO] Updating CloudAccount for serverType: %s and gatewayId: %s assetId: %s\n", cloudAccount.Data.ServerType, cloudAccount.Data.GatewayID, cloudAccount.Data.AssetData.AssetID)
_, err := client.UpdateCloudAccount(cloudAccountId, cloudAccount)

if err != nil {
log.Printf("[ERROR] Updating CloudAccount for serverType: %s and gatewayId: %s assetId: %s | err:%s\n", cloudAccount.Data.ServerType, cloudAccount.Data.GatewayID, cloudAccount.Data.AssetData.AssetID, err)
return err
return diag.FromErr(err)
}

// set ID
d.SetId(cloudAccountId)

// Set the rest of the state from the resource read
return resourceCloudAccountRead(d, m)
resourceCloudAccountReadContext(ctx, d, m)

return nil
}

func resourceCloudAccountDelete(d *schema.ResourceData, m interface{}) error {
func resourceCloudAccountDeleteContext(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
client := m.(*Client)
cloudAccountId := d.Id()

Expand Down
53 changes: 22 additions & 31 deletions dsfhub/resource_cloud_account_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,36 +3,40 @@ package dsfhub
import (
"fmt"
"log"
"os"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
)

const cloudAccountResourceName = "cloud_account"
const cloudAccountType = "aws"
const cloudAccountResourceTypeAndName = cloudAccountResourceName + "." + cloudAccountType
func TestAccDSFCloudAccount_Aws(t *testing.T) {
gatewayId := os.Getenv("GATEWAY_ID")
if gatewayId == "" {
t.Skip("GATEWAY_ID environment variable must be set")
}

const (
assetId = "arn:aws:iam::123456789012"
resourceName = "aws-cloud-account"
)

func TestAccCloudAccount_basic(t *testing.T) {
log.Printf("======================== BEGIN TEST ========================")
log.Printf("[INFO] Running test TestAccCloudAccount_basic \n")
resource.Test(t, resource.TestCase{
resourceTypeAndName := fmt.Sprintf("%s.%s", dsfCloudAccountResourceType, resourceName)

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCloudAccountDestroy,
Steps: []resource.TestStep{
{Config: testAccDSFCloudAccountConfig_Aws(resourceName, gatewayId, assetId, "default")},
{Config: testAccDSFCloudAccountConfig_Aws(resourceName, gatewayId, assetId, "iam_role")},
// {Config: testAccDSFCloudAccountConfig_Aws(resourceName, gatewayId, assetId, "key")}, //TODO: fix "key" failing refresh
{Config: testAccDSFCloudAccountConfig_Aws(resourceName, gatewayId, assetId, "profile")},
// validate import
{
Config: testAccCheckCloudAccountConfigBasic(t),
Check: resource.ComposeTestCheckFunc(
testCheckCloudAccountExists(cloudAccountResourceName),
resource.TestCheckResourceAttr(cloudAccountResourceTypeAndName, cloudAccountResourceName, cloudAccountType),
),
},
{
ResourceName: cloudAccountResourceTypeAndName,
ResourceName: resourceTypeAndName,
ImportState: true,
ImportStateVerify: true,
ImportStateIdFunc: testAccCloudAccountId,
},
},
})
Expand All @@ -41,7 +45,7 @@ func TestAccCloudAccount_basic(t *testing.T) {
func testAccCloudAccountId(state *terraform.State) (string, error) {
log.Printf("[INFO] Running test testAccCloudAccountId \n")
for _, rs := range state.RootModule().Resources {
if rs.Type != cloudAccountType {
if rs.Type != dsfCloudAccountResourceType {
continue
}
return fmt.Sprintf("%s", rs.Primary.ID), nil
Expand Down Expand Up @@ -69,24 +73,11 @@ func testCheckCloudAccountExists(dataSourceId string) resource.TestCheckFunc {
}
}

func testAccCheckCloudAccountConfigBasic(t *testing.T) string {
log.Printf("[INFO] Running test testAccCheckCloudAccountConfigBasic \n")
return fmt.Sprintf(`
resource "%s" "my_test_data_source" {
admin_email = "%s"
arn = "%s"
asset_display_name = "%s"
gateway_id = %s
server_host_name = "%s"
server_type = "%s"
}`, cloudAccountResourceName, testAdminEmail, testArn, testAssetDisplayName, testGatewayId, testServerHostName, testDSServerType)
}

func testAccCloudAccountDestroy(state *terraform.State) error {
log.Printf("[INFO] Running test testAccCloudAccountDestroy \n")
client := testAccProvider.Meta().(*Client)
for _, res := range state.RootModule().Resources {
if res.Type != "dsf_data_source" {
if res.Type != "dsfhub_data_source" {
continue
}
cloudAccountId := res.Primary.ID
Expand Down
53 changes: 53 additions & 0 deletions dsfhub/resource_cloud_account_test_data.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package dsfhub

import "fmt"

// Output a terraform config for an AWS cloud account resource.
//
// Supports all authentication mechanisms: "key", "profile", "iam_role", and
// "default".
func testAccDSFCloudAccountConfig_Aws(resourceName string, gatewayId string, assetId string, authMechanism string) string {
var assetConnectionBlock string

if authMechanism == "key" {
assetConnectionBlock = fmt.Sprintf(`
asset_connection {
access_id = "my-access-id"
auth_mechanism = "` + authMechanism + `"
reason = "default"
region = "us-east-1"
secret_key = "my-secret-key"
}
`)
} else if authMechanism == "profile" {
assetConnectionBlock = fmt.Sprintf(`
asset_connection {
auth_mechanism = "` + authMechanism + `"
reason = "default"
region = "us-east-2"
username = "dsfhubuser"
}
`)
} else {
assetConnectionBlock = fmt.Sprintf(`
asset_connection {
auth_mechanism = "` + authMechanism + `"
reason = "default"
region = "us-west-1"
}
`)
}

return fmt.Sprintf(`
resource "`+dsfCloudAccountResourceType+`" "%[1]s" {
server_type = "AWS"
admin_email = "`+testAdminEmail+`"
arn = "%[3]s"
asset_display_name = "%[3]s"
asset_id = "%[3]s"
gateway_id = "%[2]s"
`+assetConnectionBlock+`
}`, resourceName, gatewayId, assetId)
}
Loading

0 comments on commit 536721c

Please sign in to comment.