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 ServiceNow alert channel resource #63

Merged
merged 2 commits into from
Jan 28, 2021
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
8 changes: 8 additions & 0 deletions examples/resource_lacework_alert_channel_service_now/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
provider "lacework" {}

resource "lacework_alert_channel_service_now" "example" {
name = "Service Now Channel Alert Example"
instance_url = "snow-lacework.com"
username = "snow-user"
password = "snow-pass"
}
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.15
github.com/lacework/go-sdk v0.2.16
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 @@ -358,6 +358,8 @@ github.com/lacework/go-sdk v0.2.14 h1:Jem7vu3JQYHCuvoTaI/z8DNmp8zkLkQ9bvBN70M9IL
github.com/lacework/go-sdk v0.2.14/go.mod h1:yiEjWVHT4TjkZZ1pa9eS8fIfnnoVuzj1VNTIVEIsSKE=
github.com/lacework/go-sdk v0.2.15 h1:O4hWfVT1b/hBAM4V8UmS8ZbGmsjmiKPyZEoYfkd4Zzg=
github.com/lacework/go-sdk v0.2.15/go.mod h1:yiEjWVHT4TjkZZ1pa9eS8fIfnnoVuzj1VNTIVEIsSKE=
github.com/lacework/go-sdk v0.2.16 h1:oYub4gbIJpxs7GtHPIlk/dSRhivRClvVjfAPFiDnxoo=
github.com/lacework/go-sdk v0.2.16/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 @@ -56,6 +56,7 @@ func Provider() terraform.ResourceProvider {
"lacework_alert_channel_pagerduty": resourceLaceworkAlertChannelPagerDuty(),
"lacework_alert_channel_slack": resourceLaceworkAlertChannelSlack(),
"lacework_alert_channel_splunk": resourceLaceworkAlertChannelSplunk(),
"lacework_alert_channel_service_now": resourceLaceworkAlertChannelServiceNow(),
"lacework_alert_channel_webhook": resourceLaceworkAlertChannelWebhook(),
"lacework_integration_aws_cfg": resourceLaceworkIntegrationAwsCfg(),
"lacework_integration_aws_ct": resourceLaceworkIntegrationAwsCloudTrail(),
Expand Down
242 changes: 242 additions & 0 deletions lacework/resource_lacework_alert_channel_service_now.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,242 @@
package lacework

import (
"fmt"
"log"

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

func resourceLaceworkAlertChannelServiceNow() *schema.Resource {
return &schema.Resource{
Create: resourceLaceworkAlertChannelServiceNowCreate,
Read: resourceLaceworkAlertChannelServiceNowRead,
Update: resourceLaceworkAlertChannelServiceNowUpdate,
Delete: resourceLaceworkAlertChannelServiceNowDelete,

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,
},
"instance_url": {
Type: schema.TypeString,
Required: true,
},
"username": {
Type: schema.TypeString,
Required: true,
},
"password": {
Type: schema.TypeString,
Required: true,
Sensitive: true,
},
"issue_grouping": {
Type: schema.TypeString,
Optional: true,
Default: "Events",
ValidateFunc: func(value interface{}, key string) ([]string, []error) {
switch value.(string) {
case "Events", "Resources":
return nil, nil
default:
return nil, []error{
fmt.Errorf(
"%s: can only be either 'Events' or 'Resources' (default: Events)", key,
),
}
}
},
},
"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 resourceLaceworkAlertChannelServiceNowCreate(d *schema.ResourceData, meta interface{}) error {
var (
lacework = meta.(*api.Client)
serviceNow = api.NewServiceNowAlertChannel(d.Get("name").(string),
api.ServiceNowChannelData{
InstanceURL: d.Get("instanceURL").(string),
Username: d.Get("username").(string),
Password: d.Get("password").(string),
IssueGrouping: d.Get("issue_grouping").(string),
},
)
)
if !d.Get("enabled").(bool) {
serviceNow.Enabled = 0
}

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

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

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

log.Printf("[INFO] Reading %s integration with guid: %v\n", api.ServiceNowChannelIntegration, d.Id())
response, err := lacework.Integrations.GetServiceNowAlertChannel(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("instance_url", integration.Data.InstanceURL)
d.Set("username", integration.Data.Username)
d.Set("issue_grouping", integration.Data.IssueGrouping)

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

d.SetId("")
return nil
}

func resourceLaceworkAlertChannelServiceNowUpdate(d *schema.ResourceData, meta interface{}) error {
var (
lacework = meta.(*api.Client)
serviceNow = api.NewServiceNowAlertChannel(d.Get("name").(string),
api.ServiceNowChannelData{
InstanceURL: d.Get("instanceURL").(string),
Username: d.Get("username").(string),
Password: d.Get("password").(string),
IssueGrouping: d.Get("issue_grouping").(string),
},
)
)

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

serviceNow.IntgGuid = d.Id()

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

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

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

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

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

func validateServiceNowAlertChannelResponse(response *api.ServiceNowAlertChannelResponse) 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
}
Loading