Skip to content

Commit

Permalink
feat: New Cisco Webex alert channel resource (#69)
Browse files Browse the repository at this point in the history
Signed-off-by: Darren Murray <darren.murray@lacework.net>
  • Loading branch information
dmurray-lacework committed May 27, 2021
1 parent ecf7dea commit 2c43802
Show file tree
Hide file tree
Showing 14 changed files with 627 additions and 4 deletions.
6 changes: 6 additions & 0 deletions examples/resource_lacework_alert_channel_cisco_webex/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
provider "lacework" {}

resource "lacework_alert_channel_cisco_webex" "example" {
name = "My Cisco Webex Channel Alert Example"
webhook_url = "https://webexapis.com/v1/webhooks/incoming/api-token"
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ require (
github.com/hashicorp/terraform-plugin-test v1.4.3 // indirect
github.com/hashicorp/terraform-svchost v0.0.0-20191119180714-d2e4933b9136 // indirect
github.com/hashicorp/yamux v0.0.0-20200609203250-aecfd211c9ce // indirect
github.com/lacework/go-sdk v0.2.19-0.20210211001048-e41422624b52
github.com/lacework/go-sdk v0.2.20-0.20210216214810-cac9fc27f696
github.com/mattn/go-colorable v0.1.7 // indirect
github.com/mitchellh/cli v1.1.1 // indirect
github.com/mitchellh/go-homedir v1.1.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,8 @@ github.com/lacework/go-sdk v0.2.18-0.20210205172138-8298022367d9 h1:MPyhrKjrilbc
github.com/lacework/go-sdk v0.2.18-0.20210205172138-8298022367d9/go.mod h1:yiEjWVHT4TjkZZ1pa9eS8fIfnnoVuzj1VNTIVEIsSKE=
github.com/lacework/go-sdk v0.2.19-0.20210211001048-e41422624b52 h1:XgcQ1sTXFRqqVQTGKWOK+7H0bs0u5dMnJEwszzOCRFw=
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/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 @@ -50,6 +50,7 @@ func Provider() terraform.ResourceProvider {
"lacework_agent_access_token": resourceLaceworkAgentAccessToken(),
"lacework_alert_channel_aws_cloudwatch": resourceLaceworkAlertChannelAwsCloudWatch(),
"lacework_alert_channel_aws_s3": resourceLaceworkAlertChannelAwsS3(),
"lacework_alert_channel_cisco_webex": resourceLaceworkAlertChannelCiscoWebex(),
"lacework_alert_channel_datadog": resourceLaceworkAlertChannelDatadog(),
"lacework_alert_channel_gcp_pub_sub": resourceLaceworkAlertChannelGcpPubSub(),
"lacework_alert_channel_jira_cloud": resourceLaceworkAlertChannelJiraCloud(),
Expand Down
208 changes: 208 additions & 0 deletions lacework/resource_lacework_alert_channel_cisco_webex.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
package lacework

import (
"fmt"
"log"

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

func resourceLaceworkAlertChannelCiscoWebex() *schema.Resource {
return &schema.Resource{
Create: resourceLaceworkAlertChannelCiscoWebexCreate,
Read: resourceLaceworkAlertChannelCiscoWebexRead,
Update: resourceLaceworkAlertChannelCiscoWebexUpdate,
Delete: resourceLaceworkAlertChannelCiscoWebexDelete,

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,
},
"webhook_url": {
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 resourceLaceworkAlertChannelCiscoWebexCreate(d *schema.ResourceData, meta interface{}) error {
var (
lacework = meta.(*api.Client)
webex = api.NewCiscoWebexAlertChannel(d.Get("name").(string),
api.CiscoWebexChannelData{
WebhookURL: d.Get("webhook_url").(string),
},
)
)
if !d.Get("enabled").(bool) {
webex.Enabled = 0
}

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

log.Println("[INFO] Verifying server response data")
err = validateCiscoWebexAlertChannelResponse(&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.CiscoWebexChannelIntegration, integration.IntgGuid)
return nil
}

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

log.Printf("[INFO] Reading %s integration with guid: %v\n", api.CiscoWebexChannelIntegration, d.Id())
response, err := lacework.Integrations.GetCiscoWebexAlertChannel(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("webhook_url", integration.Data.WebhookURL)

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

d.SetId("")
return nil
}

func resourceLaceworkAlertChannelCiscoWebexUpdate(d *schema.ResourceData, meta interface{}) error {
var (
lacework = meta.(*api.Client)
webex = api.NewCiscoWebexAlertChannel(d.Get("name").(string),
api.CiscoWebexChannelData{
WebhookURL: d.Get("webhook_url").(string),
},
)
)

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

webex.IntgGuid = d.Id()

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

log.Println("[INFO] Verifying server response data")
err = validateCiscoWebexAlertChannelResponse(&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.CiscoWebexChannelIntegration, d.Id())
return nil
}

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

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

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

func validateCiscoWebexAlertChannelResponse(response *api.CiscoWebexAlertChannelResponse) 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
}
135 changes: 135 additions & 0 deletions lacework/resource_lacework_alert_channel_cisco_webex_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
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 (
testAccAlertChannelCiscoWebexResourceType = "lacework_alert_channel_cisco_webex"
testAccAlertChannelCiscoWebexResourceName = "example"

testAccAlertChannelCiscoWebexWebhookURL = "WEBHOOK"
)

func TestAccAlertChannelCiscoWebex(t *testing.T) {
resourceTypeAndName := fmt.Sprintf("%s.%s",
testAccAlertChannelCiscoWebexResourceType,
testAccAlertChannelCiscoWebexResourceName,
)

resource.Test(t, resource.TestCase{
PreCheck: func() {
testAccPreCheck(t)
testAccAlertChannelCiscoWebexEnvVarsPreCheck(t)
},
Providers: testAccProviders,
CheckDestroy: testAccCheckAlertChannelCiscoWebexDestroy,
Steps: []resource.TestStep{
{
Config: testAccAlertChannelCiscoWebexConfig(
true,
),
Check: resource.ComposeTestCheckFunc(
testAccCheckAlertChannelCiscoWebexExists(resourceTypeAndName),
resource.TestCheckResourceAttr(resourceTypeAndName, "enabled", "true"),
),
},
{
Config: testAccAlertChannelCiscoWebexConfig(
false,
),
Check: resource.ComposeTestCheckFunc(
testAccCheckAlertChannelCiscoWebexExists(resourceTypeAndName),
resource.TestCheckResourceAttr(resourceTypeAndName, "enabled", "false"),
),
},
},
})
}

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

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

response, err := lacework.Integrations.GetCiscoWebexAlertChannel(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.CiscoWebexChannelIntegration, rs.Primary.ID,
)
}
}
}

return nil
}

func testAccCheckAlertChannelCiscoWebexExists(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.GetCiscoWebexAlertChannel(rs.Primary.ID)
if err != nil {
return err
}

if len(response.Data) < 1 {
return fmt.Errorf("the %s integration (%s) doesn't exist",
api.CiscoWebexChannelIntegration, 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.CiscoWebexChannelIntegration, rs.Primary.ID)
}
}

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

func testAccAlertChannelCiscoWebexConfig(enabled bool) string {
return fmt.Sprintf(`
resource "%s" "%s" {
name = "integration test"
enabled = %t
webhook_url = "%s"
}
`,
testAccAlertChannelCiscoWebexResourceType,
testAccAlertChannelCiscoWebexResourceName,
enabled,
os.Getenv(testAccAlertChannelCiscoWebexWebhookURL),
)
}
9 changes: 9 additions & 0 deletions vendor/github.com/lacework/go-sdk/api/client.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 2c43802

Please sign in to comment.