alert.go raw
1 package rest
2
3 import (
4 "errors"
5 "fmt"
6 "net/http"
7
8 "gopkg.in/ns1/ns1-go.v2/rest/model/alerting"
9 )
10
11 // AlertsService handles 'alerting/v1/alerts' endpoint.
12 type AlertsService service
13
14 // The base for the alerting api relative to /v1
15 // client.NewRequest will call ResolveReference and remove /v1/../
16 const alertingRelativeBase = "../alerting/v1"
17
18 type alertListResponse struct {
19 Limit *int64 `json:"limit,omitempty"`
20 Next *string `json:"next,omitempty"`
21 Results []*alerting.Alert `json:"results"`
22 TotalResults *int64 `json:"total_results,omitempty"`
23 }
24
25 // List returns all configured alerts.
26 //
27 // NS1 API docs: https://ns1.com/api/#alerts-get
28 func (s *AlertsService) List() ([]*alerting.Alert, *http.Response, error) {
29 path := fmt.Sprintf("%s/%s", alertingRelativeBase, "alerts")
30 req, err := s.client.NewRequest("GET", path, nil)
31 if err != nil {
32 return nil, nil, err
33 }
34
35 alertListResp := alertListResponse{}
36 var resp *http.Response
37 if s.client.FollowPagination {
38 resp, err = s.client.DoWithPagination(req, &alertListResp, s.nextAlerts)
39 } else {
40 resp, err = s.client.Do(req, &alertListResp)
41 }
42 if err != nil {
43 return nil, resp, err
44 }
45 alerts := alertListResp.Results
46 return alerts, resp, nil
47 }
48
49 // nextAlerts is a pagination helper than gets and appends another list of alerts
50 // to the passed alerts.
51 func (s *AlertsService) nextAlerts(v *interface{}, uri string) (*http.Response, error) {
52 nextAlerts := &alertListResponse{}
53 resp, err := s.client.getURI(&nextAlerts, uri)
54 if err != nil {
55 return resp, err
56 }
57 alertListResp, ok := (*v).(*alertListResponse)
58 if !ok {
59 return nil, fmt.Errorf(
60 "incorrect value for v, expected value of type *[]*alerting.Alert, got: %T", v,
61 )
62 }
63 alertListResp.Results = append(alertListResp.Results, nextAlerts.Results...)
64 return resp, nil
65 }
66
67 // Get returns the details of a specific alert.
68 //
69 // NS1 API docs: https://ns1.com/api/#alert-alertid-get
70 func (s *AlertsService) Get(alertID string) (*alerting.Alert, *http.Response, error) {
71 path := fmt.Sprintf("%s/%s/%s", alertingRelativeBase, "alerts", alertID)
72 req, err := s.client.NewRequest("GET", path, nil)
73 if err != nil {
74 return nil, nil, err
75 }
76
77 var alert alerting.Alert
78 resp, err := s.client.Do(req, &alert)
79 if err != nil {
80 switch err.(type) {
81 case *Error:
82 if resourceMissingMatch(err.(*Error).Message) {
83 return nil, resp, ErrAlertMissing
84 }
85 }
86 return nil, resp, err
87 }
88
89 return &alert, resp, nil
90 }
91
92 // Create takes a *alerting.Alert and creates a new alert.
93 //
94 // NS1 API docs: https://ns1.com/api/#alert-post
95 func (s *AlertsService) Create(alert *alerting.Alert) (*http.Response, error) {
96 path := fmt.Sprintf("%s/%s", alertingRelativeBase, "alerts")
97 req, err := s.client.NewRequest("POST", path, &alert)
98 if err != nil {
99 return nil, err
100 }
101
102 // Update the alerts fields with data from api(ensure consistent)
103 resp, err := s.client.Do(req, &alert)
104 if err != nil {
105 switch err.(type) {
106 case *Error:
107 if err.(*Error).Resp.StatusCode == http.StatusConflict {
108 return resp, ErrAlertExists
109 }
110 }
111 return resp, err
112 }
113
114 return resp, nil
115 }
116
117 // Update updates the fields specified in the passed alert object.
118 //
119 // NS1 API docs: https://ns1.com/api/#alert-alertid-patch
120 func (s *AlertsService) Update(alert *alerting.Alert) (*http.Response, error) {
121 alertID := ""
122 if alert != nil && alert.ID != nil {
123 alertID = *alert.ID
124 }
125 path := fmt.Sprintf("%s/%s/%s", alertingRelativeBase, "alerts", alertID)
126
127 req, err := s.client.NewRequest("PATCH", path, &alert)
128 if err != nil {
129 return nil, err
130 }
131
132 // Update the alerts fields with data from api(ensure consistent)
133 resp, err := s.client.Do(req, &alert)
134 if err != nil {
135 return resp, err
136 }
137
138 return resp, nil
139 }
140
141 // Replace replaces the values in an alert with the values in the passed object.
142 //
143 // NS1 API docs: https://ns1.com/api/#alert-alertid-put
144 func (s *AlertsService) Replace(alert *alerting.Alert) (*http.Response, error) {
145 alertID := ""
146 if alert != nil && alert.ID != nil {
147 alertID = *alert.ID
148 }
149 path := fmt.Sprintf("%s/%s/%s", alertingRelativeBase, "alerts", alertID)
150
151 req, err := s.client.NewRequest("PUT", path, &alert)
152 if err != nil {
153 return nil, err
154 }
155
156 // Update the alerts fields with data from api (ensure consistent)
157 resp, err := s.client.Do(req, &alert)
158 if err != nil {
159 return resp, err
160 }
161
162 return resp, nil
163 }
164
165 // Delete deletes an existing alert.
166 //
167 // NS1 API docs: https://ns1.com/api/#alert-alertid-delete
168 func (s *AlertsService) Delete(alertID string) (*http.Response, error) {
169 path := fmt.Sprintf("%s/%s/%s", alertingRelativeBase, "alerts", alertID)
170 req, err := s.client.NewRequest("DELETE", path, nil)
171 if err != nil {
172 return nil, err
173 }
174
175 resp, err := s.client.Do(req, nil)
176 if err != nil {
177 return resp, err
178 }
179
180 return resp, nil
181 }
182
183 // Test an existing alert, triggers notifications for the given alert id.
184 //
185 // NS1 API docs: https://ns1.com/api/#alert-alertid-test
186 func (s *AlertsService) Test(alertID string) (*http.Response, error) {
187 path := fmt.Sprintf("%s/%s/%s/test", alertingRelativeBase, "alerts", alertID)
188 req, err := s.client.NewRequest("POST", path, nil)
189 if err != nil {
190 return nil, err
191 }
192
193 resp, err := s.client.Do(req, nil)
194 if err != nil {
195 return resp, err
196 }
197
198 return resp, nil
199 }
200
201 var (
202 // ErrAlertExists bundles POST create error.
203 ErrAlertExists = errors.New("alert already exists")
204
205 // ErrAlertMissing bundles GET/PUT/PATCH/DELETE error.
206 ErrAlertMissing = errors.New("alert does not exist")
207 )
208