Skip to content

Commit

Permalink
feat(cli): Migrate Pager Duty alert channel to API v2 (#585)
Browse files Browse the repository at this point in the history
  • Loading branch information
dmurray-lacework authored Oct 18, 2021
1 parent 7847d3b commit 68be1ec
Show file tree
Hide file tree
Showing 6 changed files with 216 additions and 8 deletions.
15 changes: 10 additions & 5 deletions api/_examples/pagerduty-alert-channel/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,32 @@ package main
import (
"fmt"
"log"
"os"

"github.com/lacework/go-sdk/api"
)

func main() {
lacework, err := api.NewClient("account", api.WithApiKeys("KEY", "SECRET"))
lacework, err := api.NewClient(os.Getenv("LW_ACCOUNT"),
api.WithSubaccount(os.Getenv("LW_SUBACCOUNT")),
api.WithApiKeys(os.Getenv("LW_API_KEY"), os.Getenv("LW_API_SECRET")),
api.WithApiV2())
if err != nil {
log.Fatal(err)
}

alert := api.NewPagerDutyAlertChannel("pagerduty-alert-from-golang",
api.PagerDutyData{
alert := api.NewAlertChannel("pagerduty-alert-from-golang",
api.PagerDutyApiAlertChannelType,
api.PagerDutyApiDataV2{
IntegrationKey: "1234abc8901abc567abc123abc78e012",
},
)

response, err := lacework.Integrations.CreatePagerDutyAlertChannel(alert)
response, err := lacework.V2.AlertChannels.Create(alert)
if err != nil {
log.Fatal(err)
}

// Output: PagerDuty alert channel created: THE-INTEGRATION-GUID
fmt.Printf("PagerDuty alert channel created: %s", response.Data[0].IntgGuid)
fmt.Printf("PagerDuty alert channel created: %s", response.Data.IntgGuid)
}
2 changes: 2 additions & 0 deletions api/alert_channels.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ const (
GcpPubSubAlertChannelType
SplunkHecAlertChannelType
ServiceNowRestAlertChannelType
PagerDutyApiAlertChannelType
IbmQRadarAlertChannelType
)

Expand All @@ -110,6 +111,7 @@ var AlertChannelTypes = map[alertChannelType]string{
GcpPubSubAlertChannelType: "GcpPubsub",
SplunkHecAlertChannelType: "SplunkHec",
ServiceNowRestAlertChannelType: "ServiceNowRest",
PagerDutyApiAlertChannelType: "PagerDutyApi",
IbmQRadarAlertChannelType: "IbmQradar",
}

Expand Down
51 changes: 51 additions & 0 deletions api/alert_channels_pager_duty.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
//
// Author:: Darren Murray (<[email protected]>)
// Copyright:: Copyright 2021, Lacework Inc.
// License:: Apache License, Version 2.0
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

package api

// GetPagerDutyApi gets a single PagerDuty alert channel matching the
// provided integration guid
func (svc *AlertChannelsService) GetPagerDutyApi(guid string) (
response PagerDutyApiAlertChannelResponseV2,
err error,
) {
err = svc.get(guid, &response)
return
}

// UpdatePagerDutyApi updates a single PagerDuty integration on the Lacework Server
func (svc *AlertChannelsService) UpdatePagerDutyApi(data AlertChannel) (
response PagerDutyApiAlertChannelResponseV2,
err error,
) {
err = svc.update(data.ID(), data, &response)
return
}

type PagerDutyApiAlertChannelResponseV2 struct {
Data PagerDutyApiAlertChannelV2 `json:"data"`
}

type PagerDutyApiAlertChannelV2 struct {
v2CommonIntegrationData
Data PagerDutyApiDataV2 `json:"data"`
}

type PagerDutyApiDataV2 struct {
IntegrationKey string `json:"apiIntgKey"`
}
137 changes: 137 additions & 0 deletions api/alert_channels_pager_duty_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
//
// Author:: Darren Murray (<[email protected]>)
// Copyright:: Copyright 2021, Lacework Inc.
// License:: Apache License, Version 2.0
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

package api_test

import (
"fmt"
"net/http"
"testing"

"github.com/stretchr/testify/assert"

"github.com/lacework/go-sdk/api"
"github.com/lacework/go-sdk/internal/intgguid"
"github.com/lacework/go-sdk/internal/lacework"
)

func TestAlertChannelsGetPagerDuty(t *testing.T) {
var (
intgGUID = intgguid.New()
apiPath = fmt.Sprintf("AlertChannels/%s", intgGUID)
fakeServer = lacework.MockServer()
)
fakeServer.UseApiV2()
fakeServer.MockToken("TOKEN")
defer fakeServer.Close()

fakeServer.MockAPI(apiPath, func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, "GET", r.Method, "GetPagerDutyApi() should be a GET method")
fmt.Fprintf(w, generateAlertChannelResponse(singlePagerDutyAlertChannel(intgGUID)))
})

c, err := api.NewClient("test",
api.WithApiV2(),
api.WithToken("TOKEN"),
api.WithURL(fakeServer.URL()),
)
assert.Nil(t, err)

response, err := c.V2.AlertChannels.GetPagerDutyApi(intgGUID)
if assert.NoError(t, err) {
assert.NotNil(t, response)
assert.Equal(t, intgGUID, response.Data.IntgGuid)
assert.Equal(t, "integration_name", response.Data.Name)
assert.True(t, response.Data.State.Ok)
assert.Equal(t, response.Data.Data.IntegrationKey, "1234abc8901abc567abc123abc78e012")
}
}

func TestAlertChannelPagerDutyUpdate(t *testing.T) {
var (
intgGUID = intgguid.New()
apiPath = fmt.Sprintf("AlertChannels/%s", intgGUID)
fakeServer = lacework.MockServer()
)
fakeServer.UseApiV2()
fakeServer.MockToken("TOKEN")
defer fakeServer.Close()

fakeServer.MockAPI(apiPath, func(w http.ResponseWriter, r *http.Request) {
assert.Equal(t, "PATCH", r.Method, "UpdatePagerDutyApi() should be a PATCH method")

if assert.NotNil(t, r.Body) {
body := httpBodySniffer(r)
assert.Contains(t, body, intgGUID, "INTG_GUID missing")
assert.Contains(t, body, "integration_name", "alert channel name is missing")
assert.Contains(t, body, "PagerDutyApi", "wrong alert channel type")
assert.Contains(t, body, "apiIntgKey\":\"1234abc8901abc567abc123abc78e012", "missing host url")
}

fmt.Fprintf(w, generateAlertChannelResponse(singlePagerDutyAlertChannel(intgGUID)))
})

c, err := api.NewClient("test",
api.WithApiV2(),
api.WithToken("TOKEN"),
api.WithURL(fakeServer.URL()),
)
assert.Nil(t, err)

pagerDutyAlertChan := api.NewAlertChannel("integration_name",
api.PagerDutyApiAlertChannelType,
api.PagerDutyApiDataV2{
IntegrationKey: "1234abc8901abc567abc123abc78e012",
},
)
assert.Equal(t, "integration_name", pagerDutyAlertChan.Name, "PagerDuty alert channel name mismatch")
assert.Equal(t, "PagerDutyApi", pagerDutyAlertChan.Type, "a new PagerDuty alert channel should match its type")
assert.Equal(t, 1, pagerDutyAlertChan.Enabled, "a new PagerDuty alert channel should be enabled")
pagerDutyAlertChan.IntgGuid = intgGUID

response, err := c.V2.AlertChannels.UpdatePagerDutyApi(pagerDutyAlertChan)
if assert.NoError(t, err) {
assert.NotNil(t, response)
assert.Equal(t, intgGUID, response.Data.IntgGuid)
assert.True(t, response.Data.State.Ok)
assert.Equal(t, response.Data.Data.IntegrationKey, "1234abc8901abc567abc123abc78e012")
}
}

func singlePagerDutyAlertChannel(id string) string {
return fmt.Sprintf(`
{
"createdOrUpdatedBy": "[email protected]",
"createdOrUpdatedTime": "2021-06-01T18:10:40.745Z",
"data": {
"apiIntgKey": "1234abc8901abc567abc123abc78e012"
},
"enabled": 1,
"intgGuid": %q,
"isOrg": 0,
"name": "integration_name",
"state": {
"details": {},
"lastSuccessfulTime": 1627895573122,
"lastUpdatedTime": 1627895573122,
"ok": true
},
"type": "PagerDutyApi"
}
`, id)
}
12 changes: 12 additions & 0 deletions api/alert_channels_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ func TestAlertChannelTypes(t *testing.T) {
"ServiceNowRest", api.ServiceNowRestAlertChannelType.String(),
"wrong alert channel type",
)
assert.Equal(t,
"PagerDutyApi", api.PagerDutyApiAlertChannelType.String(),
"wrong alert channel type",
)
assert.Equal(t,
"IbmQradar", api.IbmQRadarAlertChannelType.String(),
"wrong alert channel type",
Expand Down Expand Up @@ -136,6 +140,10 @@ func TestFindAlertChannelType(t *testing.T) {
assert.True(t, found, "alert channel type should exist")
assert.Equal(t, "ServiceNowRest", alertFound.String(), "wrong alert channel type")

alertFound, found = api.FindAlertChannelType("PagerDutyApi")
assert.True(t, found, "alert channel type should exist")
assert.Equal(t, "PagerDutyApi", alertFound.String(), "wrong alert channel type")

alertFound, found = api.FindAlertChannelType("IbmQradar")
assert.True(t, found, "alert channel type should exist")
assert.Equal(t, "IbmQradar", alertFound.String(), "wrong alert channel type")
Expand Down Expand Up @@ -283,6 +291,7 @@ func TestAlertChannelsList(t *testing.T) {
gcpPubSubAlertChan = generateGuids(&allGUIDs, 2)
splunkHecAlertChan = generateGuids(&allGUIDs, 2)
serviceNowRestAlertChan = generateGuids(&allGUIDs, 2)
pagerDutyApiAlertChan = generateGuids(&allGUIDs, 2)
ibmQradarAlertChan = generateGuids(&allGUIDs, 2)
expectedLen = len(allGUIDs)
fakeServer = lacework.MockServer()
Expand All @@ -306,6 +315,7 @@ func TestAlertChannelsList(t *testing.T) {
generateAlertChannels(gcpPubSubAlertChan, "GcpPubsub"),
generateAlertChannels(splunkHecAlertChan, "SplunkHec"),
generateAlertChannels(serviceNowRestAlertChan, "ServiceNowRest"),
generateAlertChannels(pagerDutyApiAlertChan, "PagerDutyApi"),
generateAlertChannels(ibmQradarAlertChan, "IbmQradar"),
}
fmt.Fprintf(w,
Expand Down Expand Up @@ -372,6 +382,8 @@ func generateAlertChannels(guids []string, iType string) string {
alertChannels[i] = singleSplunkAlertChannel(guid)
case api.ServiceNowRestAlertChannelType.String():
alertChannels[i] = singleServiceNowRestAlertChannel(guid)
case api.PagerDutyApiAlertChannelType.String():
alertChannels[i] = singlePagerDutyAlertChannel(guid)
case api.IbmQRadarAlertChannelType.String():
alertChannels[i] = singleIbmQRadarAlertChannel(guid)
}
Expand Down
7 changes: 4 additions & 3 deletions cli/cmd/integration_pagerduty.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,15 @@ func createPagerDutyAlertChannelIntegration() error {
return err
}

alert := api.NewPagerDutyAlertChannel(answers.Name,
api.PagerDutyData{
alert := api.NewAlertChannel(answers.Name,
api.PagerDutyApiAlertChannelType,
api.PagerDutyApiDataV2{
IntegrationKey: answers.Key,
},
)

cli.StartProgress(" Creating integration...")
_, err = cli.LwApi.Integrations.CreatePagerDutyAlertChannel(alert)
_, err = cli.LwApi.V2.AlertChannels.Create(alert)
cli.StopProgress()
return err
}

0 comments on commit 68be1ec

Please sign in to comment.