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

feat: New Relic Insights alert channel resource #73

Merged
merged 10 commits into from
Feb 19, 2021
7 changes: 7 additions & 0 deletions examples/resource_lacework_alert_channel_newrelic/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
provider "lacework" {}

resource "lacework_alert_channel_newrelic" "example" {
name = "My New Relic Insights Channel Alert Example"
account_id = 2338053
insert_key = "x-xx-xxxxxxxxxxxxxxxxxx"
}
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,8 @@ github.com/lacework/go-sdk v0.2.19-0.20210211001048-e41422624b52 h1:XgcQ1sTXFRqq
github.com/lacework/go-sdk v0.2.19-0.20210211001048-e41422624b52/go.mod h1:yiEjWVHT4TjkZZ1pa9eS8fIfnnoVuzj1VNTIVEIsSKE=
github.com/lacework/go-sdk v0.2.20-0.20210216214810-cac9fc27f696 h1:jd6J6ZjehkBH0MuO9Ttz7jyqTAcC2et5DxM4hV7LI28=
github.com/lacework/go-sdk v0.2.20-0.20210216214810-cac9fc27f696/go.mod h1:yiEjWVHT4TjkZZ1pa9eS8fIfnnoVuzj1VNTIVEIsSKE=
github.com/lacework/go-sdk v0.2.20-0.20210219030740-d7242b84a525 h1:AWsfiGWpdtokfQDuGNhtP6oylCNDEVUaT5febFcJk30=
github.com/lacework/go-sdk v0.2.20-0.20210219030740-d7242b84a525/go.mod h1:yiEjWVHT4TjkZZ1pa9eS8fIfnnoVuzj1VNTIVEIsSKE=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
Expand Down
1 change: 1 addition & 0 deletions lacework/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ func Provider() terraform.ResourceProvider {
"lacework_alert_channel_gcp_pub_sub": resourceLaceworkAlertChannelGcpPubSub(),
"lacework_alert_channel_jira_cloud": resourceLaceworkAlertChannelJiraCloud(),
"lacework_alert_channel_jira_server": resourceLaceworkAlertChannelJiraServer(),
"lacework_alert_channel_newrelic": resourceLaceworkAlertChannelNewRelic(),
"lacework_alert_channel_pagerduty": resourceLaceworkAlertChannelPagerDuty(),
"lacework_alert_channel_microsoft_teams": resourceLaceworkAlertChannelMicrosoftTeams(),
"lacework_alert_channel_slack": resourceLaceworkAlertChannelSlack(),
Expand Down
215 changes: 215 additions & 0 deletions lacework/resource_lacework_alert_channel_newrelic.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
package lacework

import (
"fmt"
"log"

"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/lacework/go-sdk/api"
)

func resourceLaceworkAlertChannelNewRelic() *schema.Resource {
return &schema.Resource{
Create: resourceLaceworkAlertChannelNewRelicCreate,
Read: resourceLaceworkAlertChannelNewRelicRead,
Update: resourceLaceworkAlertChannelNewRelicUpdate,
Delete: resourceLaceworkAlertChannelNewRelicDelete,

Importer: &schema.ResourceImporter{
State: importLaceworkIntegration,
},

Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
},
"intg_guid": {
Type: schema.TypeString,
Computed: true,
},
"enabled": {
Type: schema.TypeBool,
Optional: true,
Default: true,
},
"account_id": {
Type: schema.TypeInt,
Required: true,
},
"insert_key": {
Type: schema.TypeString,
Required: true,
},
"created_or_updated_time": {
Type: schema.TypeString,
Computed: true,
},
"created_or_updated_by": {
Type: schema.TypeString,
Computed: true,
},
"type_name": {
Type: schema.TypeString,
Computed: true,
},
"org_level": {
Type: schema.TypeBool,
Computed: true,
},
},
}
}

func resourceLaceworkAlertChannelNewRelicCreate(d *schema.ResourceData, meta interface{}) error {
var (
lacework = meta.(*api.Client)
relic = api.NewNewRelicAlertChannel(d.Get("name").(string),
api.NewRelicChannelData{
AccountID: d.Get("account_id").(int),
InsertKey: d.Get("insert_key").(string),
},
)
)
if !d.Get("enabled").(bool) {
relic.Enabled = 0
}

log.Printf("[INFO] Creating %s integration with data:\n%+v\n", api.NewRelicChannelIntegration, relic)
response, err := lacework.Integrations.CreateNewRelicAlertChannel(relic)
if err != nil {
return err
}

log.Println("[INFO] Verifying server response data")
err = validateNewRelicAlertChannelResponse(&response)
if err != nil {
return err
}

integration := response.Data[0]
d.SetId(integration.IntgGuid)
d.Set("name", integration.Name)
d.Set("intg_guid", integration.IntgGuid)
d.Set("enabled", integration.Enabled == 1)
d.Set("created_or_updated_time", integration.CreatedOrUpdatedTime)
d.Set("created_or_updated_by", integration.CreatedOrUpdatedBy)
d.Set("type_name", integration.TypeName)
d.Set("org_level", integration.IsOrg == 1)

log.Printf("[INFO] Created %s integration with guid: %v\n", api.NewRelicChannelIntegration, integration.IntgGuid)
return nil
}

func resourceLaceworkAlertChannelNewRelicRead(d *schema.ResourceData, meta interface{}) error {
lacework := meta.(*api.Client)

log.Printf("[INFO] Reading %s integration with guid: %v\n", api.NewRelicChannelIntegration, d.Id())
response, err := lacework.Integrations.GetNewRelicAlertChannel(d.Id())
if err != nil {
return err
}

for _, integration := range response.Data {
if integration.IntgGuid == d.Id() {
d.Set("name", integration.Name)
d.Set("intg_guid", integration.IntgGuid)
d.Set("enabled", integration.Enabled == 1)
d.Set("created_or_updated_time", integration.CreatedOrUpdatedTime)
d.Set("created_or_updated_by", integration.CreatedOrUpdatedBy)
d.Set("type_name", integration.TypeName)
d.Set("org_level", integration.IsOrg == 1)
d.Set("account_id", integration.Data.AccountID)
d.Set("insert_key", integration.Data.InsertKey)

log.Printf("[INFO] Read %s integration with guid: %v\n",
api.NewRelicChannelIntegration, integration.IntgGuid)
return nil
}
}

d.SetId("")
return nil
}

func resourceLaceworkAlertChannelNewRelicUpdate(d *schema.ResourceData, meta interface{}) error {
var (
lacework = meta.(*api.Client)
relic = api.NewNewRelicAlertChannel(d.Get("name").(string),
api.NewRelicChannelData{
AccountID: d.Get("account_id").(int),
InsertKey: d.Get("insert_key").(string),
},
)
)

if !d.Get("enabled").(bool) {
relic.Enabled = 0
}

relic.IntgGuid = d.Id()

log.Printf("[INFO] Updating %s integration with data:\n%+v\n", api.NewRelicChannelIntegration, relic)
response, err := lacework.Integrations.UpdateNewRelicAlertChannel(relic)
if err != nil {
return err
}

log.Println("[INFO] Verifying server response data")
err = validateNewRelicAlertChannelResponse(&response)
if err != nil {
return err
}

integration := response.Data[0]
d.Set("name", integration.Name)
d.Set("intg_guid", integration.IntgGuid)
d.Set("enabled", integration.Enabled == 1)
d.Set("created_or_updated_time", integration.CreatedOrUpdatedTime)
d.Set("created_or_updated_by", integration.CreatedOrUpdatedBy)
d.Set("type_name", integration.TypeName)
d.Set("org_level", integration.IsOrg == 1)

log.Printf("[INFO] Updated %s integration with guid: %v\n", api.NewRelicChannelIntegration, d.Id())
return nil
}

func resourceLaceworkAlertChannelNewRelicDelete(d *schema.ResourceData, meta interface{}) error {
lacework := meta.(*api.Client)

log.Printf("[INFO] Deleting %s integration with guid: %v\n", api.NewRelicChannelIntegration, d.Id())
_, err := lacework.Integrations.Delete(d.Id())
if err != nil {
return err
}

log.Printf("[INFO] Deleted %s integration with guid: %v\n", api.NewRelicChannelIntegration, d.Id())
return nil
}

func validateNewRelicAlertChannelResponse(response *api.NewRelicAlertChannelResponse) error {
if len(response.Data) == 0 {
msg := `
Unable to read sever response data. (empty 'data' field)

This was an unexpected behavior, verify that your integration has been
created successfully and report this issue to support@lacework.net
`
return fmt.Errorf(msg)
}

if len(response.Data) > 1 {
msg := `
There is more that one integration inside the server response data.

List of integrations:
`
for _, integration := range response.Data {
msg = msg + fmt.Sprintf("\t%s: %s\n", integration.IntgGuid, integration.Name)
}
msg = msg + unexpectedBehaviorMsg()
return fmt.Errorf(msg)
}

return nil
}
141 changes: 141 additions & 0 deletions lacework/resource_lacework_alert_channel_newrelic_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
package lacework

import (
"fmt"
"os"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/terraform"
"github.com/lacework/go-sdk/api"
)

const (
testAccAlertChannelNewRelicResourceType = "lacework_alert_channel_newrelic"
testAccAlertChannelNewRelicResourceName = "example"

testAccAlertChannelNewRelicAccountID = "ACCOUNT_ID"
testAccAlertChannelNewRelicInsertKey = "INSERT_KEY"
)

func TestAccAlertChannelNewRelic(t *testing.T) {
resourceTypeAndName := fmt.Sprintf("%s.%s",
testAccAlertChannelNewRelicResourceType,
testAccAlertChannelNewRelicResourceName,
)

resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
testAccAlertChannelNewRelicEnvVarsPreCheck(t)
},
Providers: testAccProviders,
CheckDestroy: testAccCheckAlertChannelNewRelicDestroy,
Steps: []resource.TestStep{
{
Config: testAccAlertChannelNewRelicConfig(
true,
),
Check: resource.ComposeTestCheckFunc(
testAccCheckAlertChannelNewRelicExists(resourceTypeAndName),
resource.TestCheckResourceAttr(resourceTypeAndName, "enabled", "true"),
),
},
{
Config: testAccAlertChannelNewRelicConfig(
false,
),
Check: resource.ComposeTestCheckFunc(
testAccCheckAlertChannelNewRelicExists(resourceTypeAndName),
resource.TestCheckResourceAttr(resourceTypeAndName, "enabled", "false"),
),
},
},
})
}

func testAccCheckAlertChannelNewRelicDestroy(s *terraform.State) error {
lacework := testAccProvider.Meta().(*api.Client)

for _, rs := range s.RootModule().Resources {
if rs.Type != testAccAlertChannelNewRelicResourceType {
continue
}

response, err := lacework.Integrations.GetNewRelicAlertChannel(rs.Primary.ID)
if err != nil {
return err
}

for _, integration := range response.Data {
if integration.IntgGuid == rs.Primary.ID {
return fmt.Errorf(
"the %s integration (%s) still exists",
api.NewRelicChannelIntegration, rs.Primary.ID,
)
}
}
}

return nil
}

func testAccCheckAlertChannelNewRelicExists(resourceTypeAndName string) resource.TestCheckFunc {
return func(s *terraform.State) error {
lacework := testAccProvider.Meta().(*api.Client)

rs, ok := s.RootModule().Resources[resourceTypeAndName]
if !ok {
return fmt.Errorf("resource (%s) not found", resourceTypeAndName)
}

if rs.Primary.ID == "" {
return fmt.Errorf("resource (%s) ID not set", resourceTypeAndName)
}

response, err := lacework.Integrations.GetNewRelicAlertChannel(rs.Primary.ID)
if err != nil {
return err
}

if len(response.Data) < 1 {
return fmt.Errorf("the %s integration (%s) doesn't exist",
api.NewRelicChannelIntegration, rs.Primary.ID)
}

for _, integration := range response.Data {
if integration.IntgGuid == rs.Primary.ID {
return nil
}
}

return fmt.Errorf("the %s integration (%s) doesn't exist",
api.NewRelicChannelIntegration, rs.Primary.ID)
}
}

func testAccAlertChannelNewRelicEnvVarsPreCheck(t *testing.T) {
if v := os.Getenv(testAccAlertChannelNewRelicAccountID); v == "" {
t.Fatalf("%s must be set for acceptance tests", testAccAlertChannelNewRelicAccountID)
}
if v := os.Getenv(testAccAlertChannelNewRelicInsertKey); v == "" {
t.Fatalf("%s must be set for acceptance tests", testAccAlertChannelNewRelicInsertKey)
}
}

func testAccAlertChannelNewRelicConfig(enabled bool) string {
return fmt.Sprintf(`
resource "%s" "%s" {
name = "integration test"
enabled = %t
account_id = "%s"
insert_key = "%s"
}
`,
testAccAlertChannelNewRelicResourceType,
testAccAlertChannelNewRelicResourceName,
enabled,
os.Getenv(testAccAlertChannelNewRelicAccountID),
os.Getenv(testAccAlertChannelNewRelicInsertKey),
)
}
Loading