-
Notifications
You must be signed in to change notification settings - Fork 51
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #109 from imjaroiswebdev/incidents-support
add support for `/incidents` List/Get/Create/Manage
- Loading branch information
Showing
4 changed files
with
356 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,178 @@ | ||
package pagerduty | ||
|
||
import ( | ||
"fmt" | ||
"log" | ||
) | ||
|
||
// IncidentService handles the communication with incident | ||
// related methods of the PagerDuty API. | ||
type IncidentService service | ||
|
||
// Incident represents a incident. | ||
type Incident struct { | ||
ID string `json:"id,omitempty"` | ||
Type string `json:"type,omitempty"` | ||
Summary string `json:"summary,omitempty"` | ||
Self string `json:"self,omitempty"` | ||
HTMLURL string `json:"html_url,omitempty"` | ||
IncidentNumber int `json:"incident_number,omitempty"` | ||
CreatedAt string `json:"created_at,omitempty"` | ||
Status string `json:"status,omitempty"` | ||
Title string `json:"title,omitempty"` | ||
Resolution string `json:"resolution,omitempty"` | ||
AlertCounts *AlertCounts `json:"alert_counts,omitempty"` | ||
PendingActions []*PendingAction `json:"pending_actions,omitempty"` | ||
IncidentKey string `json:"incident_key,omitempty"` | ||
Service *ServiceReference `json:"service,omitempty"` | ||
AssignedVia string `json:"assigned_via,omitempty"` | ||
Assignments []*IncidentAssignment `json:"assignments,omitempty"` | ||
Acknowledgements []*IncidentAcknowledgement `json:"acknowledgements,omitempty"` | ||
LastStatusChangeAt string `json:"last_status_change_at,omitempty"` | ||
LastStatusChangeBy *IncidentAttributeReference `json:"last_status_change_by,omitempty"` | ||
FirstTriggerLogEntry *IncidentAttributeReference `json:"first_trigger_log_entry,omitempty"` | ||
EscalationPolicy *EscalationPolicyReference `json:"escalation_policy,omitempty"` | ||
Teams []*TeamReference `json:"teams,omitempty"` | ||
Urgency string `json:"urgency,omitempty"` | ||
} | ||
|
||
type AlertCounts struct { | ||
All int `json:"all"` | ||
Resolved int `json:"resolved"` | ||
Triggered int `json:"triggered"` | ||
} | ||
|
||
type PendingAction struct { | ||
At string `json:"at"` | ||
Type string `json:"type"` | ||
} | ||
|
||
type IncidentAssignment struct { | ||
At string `json:"at"` | ||
Assignee UserReference `json:"assignee"` | ||
} | ||
|
||
type IncidentAcknowledgement struct { | ||
At string `json:"at"` | ||
Acknowledger IncidentAttributeReference `json:"acknowledger"` | ||
} | ||
|
||
// IncidentPayload represents an incident. | ||
type IncidentPayload struct { | ||
Incident *Incident `json:"incident,omitempty"` | ||
} | ||
|
||
// ManageIncidentsPayload represents a payload with a list of incidents data. | ||
type ManageIncidentsPayload struct { | ||
Incidents []*Incident `json:"incidents,omitempty"` | ||
} | ||
|
||
// ListIncidentsOptions represents options when listing incidents. | ||
type ListIncidentsOptions struct { | ||
Limit int `url:"limit,omitempty"` | ||
Offset int `url:"offset,omitempty"` | ||
Total int `url:"total,omitempty"` | ||
DateRange string `url:"date_range,omitempty"` | ||
IncidentKey string `url:"incident_key,omitempty"` | ||
Include []string `url:"include,omitempty,brackets"` | ||
ServiceIDs []string `url:"service_ids,omitempty,brackets"` | ||
Since string `url:"since,omitempty"` | ||
SortBy []string `url:"sort_by,omitempty,brackets"` | ||
Statuses []string `url:"statuses,omitempty,brackets"` | ||
TeamIDs []string `url:"team_ids,omitempty,brackets"` | ||
TimeZone string `url:"time_zone,omitempty"` | ||
Until string `url:"until,omitempty"` | ||
Urgencies []string `url:"urgencies,omitempty,brackets"` | ||
UserIDs []string `url:"user_ids,omitempty,brackets"` | ||
} | ||
|
||
// ManageIncidentsOptions represents options when listing incidents. | ||
type ManageIncidentsOptions struct { | ||
Limit int `url:"limit,omitempty"` | ||
Offset int `url:"offset,omitempty"` | ||
Total int `url:"total,omitempty"` | ||
} | ||
|
||
// ListIncidentsResponse represents a list response of incidents. | ||
type ListIncidentsResponse struct { | ||
Limit int `json:"limit,omitempty"` | ||
More bool `json:"more,omitempty"` | ||
Offset int `json:"offset,omitempty"` | ||
Total int `json:"total,omitempty"` | ||
Incidents []*Incident `json:"incidents,omitempty"` | ||
} | ||
|
||
type ManageIncidentsResponse ListIncidentsResponse | ||
|
||
// List lists existing incidents. | ||
func (s *IncidentService) List(o *ListIncidentsOptions) (*ListIncidentsResponse, *Response, error) { | ||
u := "/incidents" | ||
v := new(ListIncidentsResponse) | ||
|
||
resp, err := s.client.newRequestDo("GET", u, o, nil, &v) | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
|
||
return v, resp, nil | ||
} | ||
|
||
// ListAll lists all result pages for incidents list. | ||
func (s *IncidentService) ListAll(o *ListIncidentsOptions) ([]*Incident, error) { | ||
var incidents = make([]*Incident, 0, 25) | ||
more := true | ||
offset := 0 | ||
|
||
for more { | ||
log.Printf("==== Getting incidents at offset %d", offset) | ||
v := new(ListIncidentsResponse) | ||
_, err := s.client.newRequestDo("GET", "/incidents", o, nil, &v) | ||
if err != nil { | ||
return incidents, err | ||
} | ||
incidents = append(incidents, v.Incidents...) | ||
more = v.More | ||
offset += v.Limit | ||
o.Offset = offset | ||
} | ||
return incidents, nil | ||
} | ||
|
||
// ManageIncidents updates existing incidents. | ||
func (s *IncidentService) ManageIncidents(incidents []*Incident, o *ManageIncidentsOptions) (*ManageIncidentsResponse, *Response, error) { | ||
u := "/incidents" | ||
v := new(ManageIncidentsResponse) | ||
|
||
resp, err := s.client.newRequestDo("PUT", u, o, &ManageIncidentsPayload{Incidents: incidents}, &v) | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
|
||
return v, resp, nil | ||
} | ||
|
||
// Create an incident | ||
func (s *IncidentService) Create(incident *Incident) (*Incident, *Response, error) { | ||
u := "/incidents" | ||
v := new(IncidentPayload) | ||
|
||
resp, err := s.client.newRequestDo("POST", u, nil, &IncidentPayload{Incident: incident}, &v) | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
|
||
return v.Incident, resp, nil | ||
} | ||
|
||
// Get retrieves information about an incident. | ||
func (s *IncidentService) Get(id string) (*Incident, *Response, error) { | ||
u := fmt.Sprintf("/incidents/%s", id) | ||
v := new(IncidentPayload) | ||
|
||
resp, err := s.client.newRequestDo("GET", u, nil, nil, &v) | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
|
||
return v.Incident, resp, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,172 @@ | ||
package pagerduty | ||
|
||
import ( | ||
"encoding/json" | ||
"net/http" | ||
"reflect" | ||
"testing" | ||
) | ||
|
||
func TestIncidentsList(t *testing.T) { | ||
setup() | ||
defer teardown() | ||
|
||
mux.HandleFunc("/incidents", func(w http.ResponseWriter, r *http.Request) { | ||
testMethod(t, r, "GET") | ||
w.Write([]byte(`{"incidents": [{"id": "P1D3Z4B"}]}`)) | ||
}) | ||
|
||
resp, _, err := client.Incidents.List(&ListIncidentsOptions{}) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
want := &ListIncidentsResponse{ | ||
Incidents: []*Incident{ | ||
{ | ||
ID: "P1D3Z4B", | ||
}, | ||
}, | ||
} | ||
|
||
if !reflect.DeepEqual(resp, want) { | ||
t.Errorf("returned %#v; want %#v", resp, want) | ||
} | ||
} | ||
|
||
func TestIncidentsListAll(t *testing.T) { | ||
setup() | ||
defer teardown() | ||
var reqCount int | ||
|
||
mux.HandleFunc("/incidents", func(w http.ResponseWriter, r *http.Request) { | ||
testMethod(t, r, "GET") | ||
switch reqCount { | ||
case 0: | ||
w.Write([]byte(`{"incidents":[{"id":"P1D3Z4B"}],"limit":1,"offset":0,"more":true}`)) | ||
reqCount++ | ||
case 1: | ||
w.Write([]byte(`{"incidents":[{"id":"Z1D3K79"}],"limit":1,"offset":1,"more":true}`)) | ||
reqCount++ | ||
default: | ||
w.Write([]byte(`{"incidents":[{"id":"U1D3NS1"}],"limit":1,"offset":2,"more":false}`)) | ||
} | ||
}) | ||
|
||
resp, err := client.Incidents.ListAll(&ListIncidentsOptions{}) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
want := []*Incident{ | ||
{ | ||
ID: "P1D3Z4B", | ||
}, | ||
{ | ||
ID: "Z1D3K79", | ||
}, | ||
{ | ||
ID: "U1D3NS1", | ||
}, | ||
} | ||
|
||
if !reflect.DeepEqual(resp, want) { | ||
t.Errorf("returned %#v; want %#v", resp, want) | ||
} | ||
} | ||
|
||
func TestIncidentsManage(t *testing.T) { | ||
setup() | ||
defer teardown() | ||
|
||
input := []*Incident{{ID: "P1D3Z4B"}} | ||
|
||
mux.HandleFunc("/incidents", func(w http.ResponseWriter, r *http.Request) { | ||
testMethod(t, r, "PUT") | ||
payload := &ManageIncidentsPayload{Incidents: input} | ||
v := new(ManageIncidentsPayload) | ||
json.NewDecoder(r.Body).Decode(v) | ||
if !reflect.DeepEqual(v, payload) { | ||
t.Errorf("Request body = %+v, want %+v", v, payload) | ||
} | ||
w.Write([]byte(`{"incidents": [{"id": "P1D3Z4B"}]}`)) | ||
}) | ||
|
||
resp, _, err := client.Incidents.ManageIncidents(input, &ManageIncidentsOptions{}) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
want := &ManageIncidentsResponse{ | ||
Incidents: []*Incident{ | ||
{ | ||
ID: "P1D3Z4B", | ||
}, | ||
}, | ||
} | ||
|
||
if !reflect.DeepEqual(resp, want) { | ||
t.Errorf("returned %#v; want %#v", resp, want) | ||
} | ||
} | ||
|
||
func TestIncidentsCreate(t *testing.T) { | ||
setup() | ||
defer teardown() | ||
|
||
input := &Incident{ | ||
Type: "incident", | ||
Title: "test incident", | ||
} | ||
|
||
mux.HandleFunc("/incidents", func(w http.ResponseWriter, r *http.Request) { | ||
testMethod(t, r, "POST") | ||
payload := &IncidentPayload{Incident: input} | ||
v := new(IncidentPayload) | ||
json.NewDecoder(r.Body).Decode(v) | ||
if !reflect.DeepEqual(v, payload) { | ||
t.Errorf("Request body = %+v, want %+v", v, payload) | ||
} | ||
w.Write([]byte(`{"incident": {"id": "1", "type": "incident", "title": "test incident"}}`)) | ||
}) | ||
|
||
resp, _, err := client.Incidents.Create(input) | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
want := &Incident{ | ||
ID: "1", | ||
Type: "incident", | ||
Title: "test incident", | ||
} | ||
|
||
if !reflect.DeepEqual(resp, want) { | ||
t.Errorf("returned %#v; want %#v", resp, want) | ||
} | ||
} | ||
|
||
func TestIncidentsGet(t *testing.T) { | ||
setup() | ||
defer teardown() | ||
|
||
mux.HandleFunc("/incidents/1", func(w http.ResponseWriter, r *http.Request) { | ||
testMethod(t, r, "GET") | ||
w.Write([]byte(`{"incident": {"id": "1", "type": "incident", "title": "test incident"}}`)) | ||
}) | ||
|
||
resp, _, err := client.Incidents.Get("1") | ||
if err != nil { | ||
t.Fatal(err) | ||
} | ||
|
||
want := &Incident{ | ||
ID: "1", | ||
Type: "incident", | ||
Title: "test incident", | ||
} | ||
|
||
if !reflect.DeepEqual(resp, want) { | ||
t.Errorf("returned %#v; want %#v", resp, want) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters