Skip to content

Commit

Permalink
Merge pull request #246 from PagerDuty/Add_Change_events
Browse files Browse the repository at this point in the history
Add Support For Change Events
  • Loading branch information
Scott McAllister authored Oct 21, 2020
2 parents 32373a5 + 43b8770 commit 4cd79a4
Show file tree
Hide file tree
Showing 2 changed files with 190 additions and 0 deletions.
75 changes: 75 additions & 0 deletions change_events.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package pagerduty

import (
"bytes"
"encoding/json"
"errors"
)

const ChangeEventPath = "/v2/change/enqueue"

// ChangeEvent represents a ChangeEvent's request parameters
// https://developer.pagerduty.com/docs/events-api-v2/send-change-events/#parameters
type ChangeEvent struct {
RoutingKey string `json:"routing_key"`
Payload Payload `json:"payload"`
Links []Link `json:"links"`
}

// Payload ChangeEvent Payload
// https://developer.pagerduty.com/docs/events-api-v2/send-change-events/#example-request-payload
type Payload struct {
Source string `json:"source"`
Summary string `json:"summary"`
Timestamp string `json:"timestamp"`
CustomDetails map[string]interface{} `json:"custom_details"`
}

// Link represents a single link in a ChangeEvent
// https://developer.pagerduty.com/docs/events-api-v2/send-change-events/#the-links-property
type Link struct {
Href string `json:"href"`
Text string `json:"text"`
}

// ChangeEventResponse is the json response body for an event
type ChangeEventResponse struct {
Status string `json:"status,omitempty"`
Message string `json:"message,omitempty"`
Errors []string `json:"errors,omitempty"`
}

// CreateChangeEvent Sends PagerDuty a single ChangeEvent to record
// The v2EventsAPIEndpoint parameter must be set on the client
// Documentation can be found at https://developer.pagerduty.com/docs/events-api-v2/send-change-events
func (c *Client) CreateChangeEvent(e ChangeEvent) (*ChangeEventResponse, error) {
if c.v2EventsAPIEndpoint == "" {
return nil, errors.New("v2EventsAPIEndpoint field must be set on Client")
}

headers := make(map[string]string)

data, err := json.Marshal(e)
if err != nil {
return nil, err
}

resp, err := c.doWithEndpoint(
c.v2EventsAPIEndpoint,
"POST",
ChangeEventPath,
false,
bytes.NewBuffer(data),
&headers,
)
if err != nil {
return nil, err
}

var eventResponse ChangeEventResponse
if err := json.NewDecoder(resp.Body).Decode(&eventResponse); err != nil {
return nil, err
}

return &eventResponse, nil
}
115 changes: 115 additions & 0 deletions change_events_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package pagerduty

import (
"io/ioutil"
"net/http"
"testing"
)

const (
expectedChangeCreatePayload = `{"routing_key":"a0000000aa0000a0a000aa0a0a0aa000","payload":{"source":"Test runner",` +
`"summary":"Summary can't be blank","timestamp":"2020-10-19T03:06:16.318Z",` +
`"custom_details":{"DetailKey1":"DetailValue1","DetailKey2":"DetailValue2"}},` +
`"links":[{"href":"https://acme.pagerduty.dev/build/2","text":"View more details in Acme!"},` +
`{"href":"https://acme2.pagerduty.dev/build/2","text":"View more details in Acme2!"}]}`
)

func TestChangeEvent_Create(t *testing.T) {
setup()
defer teardown()

mux.HandleFunc(
"/v2/change/enqueue", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "POST")
w.WriteHeader(http.StatusAccepted)
w.Write([]byte(`{"message": "Change event processed", "status": "success"}`))
},
)

var client = &Client{
v2EventsAPIEndpoint: server.URL,
apiEndpoint: server.URL,
authToken: "foo",
HTTPClient: defaultHTTPClient,
}

want := ChangeEventResponse{
Status: "success",
Message: "Change event processed",
}

eventDetails := map[string]interface{}{"DetailKey1": "DetailValue1", "DetailKey2": "DetailValue2"}
ce := ChangeEvent{
RoutingKey: "a0000000aa0000a0a000aa0a0a0aa000",
Payload: Payload{
Source: "Test runner",
Summary: "Summary can't be blank",
Timestamp: "2020-10-19T03:06:16.318Z",
CustomDetails: eventDetails,
},
Links: []Link{
{
Href: "https://acme.pagerduty.dev/build/2",
Text: "View more details in Acme!",
},
{
Href: "https://acme2.pagerduty.dev/build/2",
Text: "View more details in Acme2!",
},
},
}

res, err := client.CreateChangeEvent(ce)

if err != nil {
t.Fatal(err)
}
testEqual(t, want, *res)
}

func TestChangeEvent_CreateWithPayloadVerification(t *testing.T) {
setup()
defer teardown()

mux.HandleFunc(
"/v2/change/enqueue", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "POST")
body, err := ioutil.ReadAll(r.Body)
if err != nil {
t.Fatal(err)
}
testEqual(t, expectedChangeCreatePayload, string(body))
},
)

var client = &Client{
v2EventsAPIEndpoint: server.URL,
apiEndpoint: server.URL,
authToken: "foo",
HTTPClient: defaultHTTPClient,
}

eventDetails := map[string]interface{}{"DetailKey1": "DetailValue1", "DetailKey2": "DetailValue2"}
ce := ChangeEvent{
RoutingKey: "a0000000aa0000a0a000aa0a0a0aa000",
Payload: Payload{
Source: "Test runner",
Summary: "Summary can't be blank",
Timestamp: "2020-10-19T03:06:16.318Z",
CustomDetails: eventDetails,
},
Links: []Link{
{
Href: "https://acme.pagerduty.dev/build/2",
Text: "View more details in Acme!",
},
{
Href: "https://acme2.pagerduty.dev/build/2",
Text: "View more details in Acme2!",
},
},
}

_, _ = client.CreateChangeEvent(ce)

}

0 comments on commit 4cd79a4

Please sign in to comment.