Skip to content

Commit

Permalink
Merge pull request #241 from goatherder/event_v2_client
Browse files Browse the repository at this point in the history
Event v2 client
  • Loading branch information
Scott McAllister authored Oct 16, 2020
2 parents e6408ba + e053a10 commit 32373a5
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 20 deletions.
51 changes: 34 additions & 17 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ import (
)

const (
apiEndpoint = "https://api.pagerduty.com"
apiEndpoint = "https://api.pagerduty.com"
v2EventsAPIEndpoint = "https://events.pagerduty.com"
)

// The type of authentication to use with the API client
Expand Down Expand Up @@ -96,8 +97,9 @@ var defaultHTTPClient HTTPClient = newDefaultHTTPClient()

// Client wraps http client
type Client struct {
authToken string
apiEndpoint string
authToken string
apiEndpoint string
v2EventsAPIEndpoint string

// Authentication type to use for API
authType authType
Expand All @@ -111,10 +113,11 @@ type Client struct {
// NewClient creates an API client using an account/user API token
func NewClient(authToken string, options ...ClientOptions) *Client {
client := Client{
authToken: authToken,
apiEndpoint: apiEndpoint,
authType: apiToken,
HTTPClient: defaultHTTPClient,
authToken: authToken,
apiEndpoint: apiEndpoint,
v2EventsAPIEndpoint: v2EventsAPIEndpoint,
authType: apiToken,
HTTPClient: defaultHTTPClient,
}

for _, opt := range options {
Expand All @@ -139,6 +142,13 @@ func WithAPIEndpoint(endpoint string) ClientOptions {
}
}

// WithV2EventsAPIEndpoint allows for a custom V2 Events API endpoint to be passed into the client
func WithV2EventsAPIEndpoint(endpoint string) ClientOptions {
return func(c *Client) {
c.v2EventsAPIEndpoint = endpoint
}
}

// WithOAuth allows for an OAuth token to be passed into the the client
func WithOAuth() ClientOptions {
return func(c *Client) {
Expand Down Expand Up @@ -174,29 +184,36 @@ func (c *Client) get(path string) (*http.Response, error) {
return c.do("GET", path, nil, nil)
}

func (c *Client) do(method, path string, body io.Reader, headers *map[string]string) (*http.Response, error) {
endpoint := c.apiEndpoint + path
req, _ := http.NewRequest(method, endpoint, body)
// needed where pagerduty use a different endpoint for certain actions (eg: v2 events)
func (c *Client) doWithEndpoint(endpoint, method, path string, authRequired bool, body io.Reader, headers *map[string]string) (*http.Response, error) {
req, _ := http.NewRequest(method, endpoint+path, body)
req.Header.Set("Accept", "application/vnd.pagerduty+json;version=2")
if headers != nil {
for k, v := range *headers {
req.Header.Set(k, v)
}
}
req.Header.Set("User-Agent", "go-pagerduty/"+Version)
req.Header.Set("Content-Type", "application/json")

switch c.authType {
case oauthToken:
req.Header.Set("Authorization", "Bearer "+c.authToken)
default:
req.Header.Set("Authorization", "Token token="+c.authToken)
if authRequired {
switch c.authType {
case oauthToken:
req.Header.Set("Authorization", "Bearer "+c.authToken)
default:
req.Header.Set("Authorization", "Token token="+c.authToken)
}
}

req.Header.Set("User-Agent", "go-pagerduty/"+Version)
req.Header.Set("Content-Type", "application/json")

resp, err := c.HTTPClient.Do(req)
return c.checkResponse(resp, err)
}

func (c *Client) do(method, path string, body io.Reader, headers *map[string]string) (*http.Response, error) {
return c.doWithEndpoint(c.apiEndpoint, method, path, true, body, headers)
}

func (c *Client) decodeJSON(resp *http.Response, payload interface{}) error {
defer resp.Body.Close()
decoder := json.NewDecoder(resp.Body)
Expand Down
23 changes: 20 additions & 3 deletions event_v2.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"net/http"
)

// Event includes the incident/alert details
// V2Event includes the incident/alert details
type V2Event struct {
RoutingKey string `json:"routing_key"`
Action string `json:"event_action"`
Expand All @@ -20,7 +20,7 @@ type V2Event struct {
Payload *V2Payload `json:"payload,omitempty"`
}

// Payload represents the individual event details for an event
// V2Payload represents the individual event details for an event
type V2Payload struct {
Summary string `json:"summary"`
Source string `json:"source"`
Expand All @@ -32,7 +32,7 @@ type V2Payload struct {
Details interface{} `json:"custom_details,omitempty"`
}

// Response is the json response body for an event
// V2EventResponse is the json response body for an event
type V2EventResponse struct {
Status string `json:"status,omitempty"`
DedupKey string `json:"dedup_key,omitempty"`
Expand Down Expand Up @@ -69,3 +69,20 @@ func ManageEvent(e V2Event) (*V2EventResponse, error) {
}
return &eventResponse, nil
}

// ManageEvent handles the trigger, acknowledge, and resolve methods for an event
func (c *Client) ManageEvent(e *V2Event) (*V2EventResponse, error) {
headers := make(map[string]string)

data, err := json.Marshal(e)
if err != nil {
return nil, err
}
resp, err := c.doWithEndpoint(c.v2EventsAPIEndpoint, "POST", "/v2/enqueue", false, bytes.NewBuffer(data), &headers)
if err != nil {
return nil, err
}
result := &V2EventResponse{}
err = json.NewDecoder(resp.Body).Decode(result)
return result, err
}
30 changes: 30 additions & 0 deletions event_v2_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package pagerduty

import (
"net/http"
"testing"
)

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

mux.HandleFunc("/v2/enqueue", func(w http.ResponseWriter, r *http.Request) {
testMethod(t, r, "POST")
w.Write([]byte(`{"status": "ok", "dedup_key": "yes", "message": "ok"}`))
})
var client = &Client{v2EventsAPIEndpoint: server.URL, apiEndpoint: server.URL, authToken: "foo", HTTPClient: defaultHTTPClient}
evt := &V2Event{
RoutingKey: "abc123",
}
res, err := client.ManageEvent(evt)
if err != nil {
t.Fatal(err)
}
want := &V2EventResponse{
Status: "ok",
DedupKey: "yes",
Message: "ok",
}
testEqual(t, want, res)
}

0 comments on commit 32373a5

Please sign in to comment.