@@ -0,0 +1,650 @@
1+{-# LANGUAGE DataKinds #-}
2+{-# LANGUAGE ExtendedDefaultRules #-}
3+{-# LANGUAGE FlexibleInstances #-}
4+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
5+{-# LANGUAGE LambdaCase #-}
6+{-# LANGUAGE OverloadedStrings #-}
7+{-# LANGUAGE TemplateHaskell #-}
8+{-# LANGUAGE TypeFamilies #-}
9+
10+{-# OPTIONS_GHC -fno-warn-type-defaults #-}
11+
12+-- Module : Network.PagerDuty.REST.Incidents
13+-- Copyright : (c) 2013-2014 Brendan Hay <brendan.g.hay@gmail.com>
14+-- License : This Source Code Form is subject to the terms of
15+-- the Mozilla Public License, v. 2.0.
16+-- A copy of the MPL can be found in the LICENSE file or
17+-- you can obtain it at http://mozilla.org/MPL/2.0/.
18+-- Maintainer : Brendan Hay <brendan.g.hay@gmail.com>
19+-- Stability : experimental
20+-- Portability : non-portable (GHC extensions)
21+
22+-- | PagerDuty receives updates (called events) from monitoring systems through
23+-- services (like Nagios, email or generic API calls). Upon receiving an event,
24+-- active services will create a new incident and begin escalating it as
25+-- defined by the service's escalation policy. Events can be de-duplicated into
26+-- existing incidents based on service de-duplication rules to prevent you from
27+-- being overwhelmed by event storms.
28+--
29+-- An incident can be open, acknowledged or resolved. Whenever an incident is
30+-- created, it is assigned to a user (according to the escalation process, as
31+-- described by escalation rules and schedules). The assigned user has a chance
32+-- to either acknowledge that he is working on it, or to resolve it.
33+--
34+-- Resolving an incident closes it, whereas acknowledging it halts the
35+-- escalation process. If the incident is not resolved by the service's
36+-- incident ack timeout it continues up the escalation chain.
37+--
38+-- When an incident is triggered or when it is escalated it creates alerts
39+-- (also known as notifications). Alerts are messages containing the details of
40+-- the incident, and can be sent through SMS, email and phone calls.
41+--
42+-- Incidents and Incident Counts from the last 30 days are returned by
43+-- default. To change this default date range, see the documentation for the
44+-- since, until or dateRange parameters.
45+--
46+-- Note: that to create an incident you need to trigger it through the
47+-- "Network.PagerDuty.Integration" API.
48+--
49+-- /See:/ <http://developer.pagerduty.com/documentation/rest/incidents>
50+module Network.PagerDuty.REST.Incidents
51+ (
52+ -- * List Incidents
53+ ListIncidents
54+ , listIncidents
55+ , lsSince
56+ , lsUntil
57+ , lsDateRange
58+ , lsStatus
59+ , lsIncidentKey
60+ , lsService
61+ , lsAssignedToUser
62+ , lsTimeZone
63+ , lsSortBy
64+
65+ -- * Count Incidents
66+ , CountIncidents
67+ , countIncidents
68+ , cSince
69+ , cUntil
70+ , cDateRange
71+ , cStatus
72+ , cIncidentKey
73+ , cService
74+ , cAssignedToUser
75+
76+ -- * Get Incident
77+ , getIncident
78+
79+ -- * Update Incidents
80+ , UpdateIncidents
81+ , updateIncidents
82+ , updateIncidentsBasic
83+ , uiIncidents
84+
85+ -- * Resolve Incident
86+ , resolveIncident
87+ , resolveIncidentBasic
88+
89+ -- * Acknowledge Incident
90+ , acknowledgeIncident
91+ , acknowledgeIncidentBasic
92+
93+ -- * Reassign Incident
94+ , ReassignIncident
95+ , reassignIncident
96+ , riEscalationPolicy
97+ , riEscalationLevel
98+ , riAssignedToUser
99+
100+ -- * Types
101+ , Sort (..)
102+ , _Desc
103+ , _Asc
104+
105+ , Field (..)
106+
107+ , IncidentStatus (..)
108+ , UpdateStatus (..)
109+
110+ , UpdateIncident
111+ , iiId
112+ , iiStatus
113+ , iiEscalationLevel
114+ , iiEscalationPolicy
115+ , iiAssignedToUser
116+
117+ , UpdatedIncidents
118+ , uiId
119+ , uiStatus
120+ , uiIncidentNumber
121+ , uiUrl
122+ , uiError
123+
124+ , Assignee
125+ , aAt
126+ , aObject
127+
128+ , HasIncident (..)
129+ , Incident
130+ ) where
131+
132+import Control.Applicative hiding (empty)
133+import Control.Lens
134+import Data.Aeson
135+import Data.ByteString.Conversion (ToByteString(..), toByteString')
136+import Data.Default.Class
137+import Data.Maybe
138+import Data.Monoid hiding (All)
139+import Data.Text (Text)
140+import qualified Data.Text.Encoding as Text
141+import Data.Time
142+import Network.HTTP.Types
143+import Network.PagerDuty.Internal.Query
144+import Network.PagerDuty.Internal.TH
145+import Network.PagerDuty.Internal.Types
146+
147+default (Path)
148+
149+incidents :: Path
150+incidents = "incidents"
151+
152+data Sort a
153+ = Desc a
154+ | Asc a
155+ deriving (Eq, Show)
156+
157+makePrisms ''Sort
158+
159+data Field
160+ = IncidentNumber
161+ -- ^ The number of your incident.
162+ | CreatedOn
163+ -- ^ The date/time the incident was triggered.
164+ | ResolvedOn
165+ -- ^ The date/time the incident was resolved.
166+ deriving (Eq, Show)
167+
168+instance QueryValues (Sort Field) where
169+ queryValues s = case s of
170+ Desc f -> ["desc:" <> field f]
171+ Asc f -> ["asc:" <> field f]
172+ where
173+ field IncidentNumber = "incidentNumber"
174+ field CreatedOn = "createdOn"
175+ field ResolvedOn = "resolvedOn"
176+
177+data Range = All
178+ deriving (Eq, Show)
179+
180+instance QueryValues Range where
181+ queryValues All = ["all"]
182+
183+data IncidentStatus
184+ = ITriggered
185+ | IAcknowledged
186+ | IResolved
187+ | IOther Text
188+ deriving (Eq, Show)
189+
190+instance ToByteString IncidentStatus where
191+ builder = \case
192+ ITriggered -> "triggered"
193+ IAcknowledged -> "acknowledged"
194+ IResolved -> "resolved"
195+ IOther t -> builder t
196+
197+instance FromJSON IncidentStatus where
198+ parseJSON = withText "status" $ pure . \case
199+ "triggered" -> ITriggered
200+ "acknowledged" -> IAcknowledged
201+ "resolved" -> IResolved
202+ t -> IOther t
203+
204+instance ToJSON IncidentStatus where
205+ toJSON = String . Text.decodeUtf8 . toByteString'
206+
207+data Assignee = Assignee
208+ { _aAt :: Date
209+ , _aObject :: Object
210+ } deriving (Eq, Show)
211+
212+deriveRecord ''Assignee
213+
214+data Incident = Incident
215+ { _iIncidentNumber' :: !Int
216+ , _iStatus' :: !IncidentStatus
217+ , _iCreatedOn' :: Date
218+ , _iHtmlUrl' :: Text
219+ , _iIncidentKey' :: Maybe IncidentKey
220+ , _iService' :: Object
221+ , _iEscalationPolicy' :: Maybe Object
222+ , _iAssignedTo' :: [Assignee]
223+ , _iAcknowledgers' :: [Assignee]
224+ , _iLastStatusChangeBy' :: Maybe Assignee
225+ , _iLastStatusChangeOn' :: Maybe Date
226+ , _iTriggerSummaryData' :: Object
227+ , _iTriggerDetailsHtmlUrl' :: Text
228+ } deriving (Eq, Show)
229+
230+deriveRecord ''Incident
231+
232+class HasIncident a where
233+ incident :: Lens' a Incident
234+
235+ -- | The number of the incident. This is unique across your account.
236+ iIncidentNumber :: Lens' a Int
237+
238+ -- | The current status of the incident. Valid statuses are:
239+ iStatus :: Lens' a IncidentStatus
240+
241+ -- | The date/time the incident was triggered.
242+ iCreatedOn :: Lens' a UTCTime
243+
244+ -- | The PagerDuty website URL where the incident can be viewed and further
245+ -- actions taken. This is not the resource URL.
246+ iHtmlUrl :: Lens' a Text
247+
248+ -- | The incident's de-duplication key. See the PagerDuty Integration API
249+ -- docs for further details.
250+ iIncidentKey :: Lens' a (Maybe IncidentKey)
251+
252+ -- | The PagerDuty service that the incident belongs to. The service will
253+ -- contain fields of its own.
254+ iService :: Lens' a Object
255+
256+ -- | The escalation policy that the incident belongs to. The policy will
257+ -- contain fields of its own.
258+ iEscalationPolicy :: Lens' a (Maybe Object)
259+
260+ -- | The list of assignments of the incident. An assignment is an object
261+ -- containing the assigned user as well as the date/time the incident was
262+ -- assigned to that user. The user will contain fields of its own.
263+ -- This list is empty if the status of the incident is resolved.
264+ iAssignedTo :: Lens' a [Assignee]
265+
266+ -- | The list of acknowledgements of the incident. An acknowledgement is an
267+ -- object containing the acknowleding object (either a user or the
268+ -- integration API) as well as the date/time the incident was acknowledged.
269+ -- This field is only present if the status of the incident is acknowledged.
270+ -- This field is sorted in ascending order by acknowledgement time.
271+ iAcknowledgers :: Lens' a [Assignee]
272+
273+ -- | The user who is responsible for the incident's last status change. If
274+ -- the incident is in the acknowledged or resolved status, this will be the user
275+ -- that took the first acknowledged or resolved action. If the incident was
276+ -- automatically resolved (say through the Event Integration API), or if the
277+ -- incident is in the triggered state, this will be null. User fields are the
278+ -- same as in the assignedToUser field above.
279+ iLastStatusChangeBy :: Lens' a (Maybe Assignee)
280+
281+ -- | The date/time the incident's status last changed.
282+ iLastStatusChangeOn :: Lens' a (Maybe UTCTime)
283+
284+ -- | Some condensed information regarding the initial event that triggered
285+ -- this incident. This data will be a set of key/value pairs that vary depending
286+ -- on what sort of event triggered the incident (email, Event API request,
287+ -- etc). For instance, if an email triggered the incident, then the
288+ -- triggerSummaryData will likely contain a subject. There are no guarantees
289+ -- o nthe full presence of this data for every incident.
290+ iTriggerSummaryData :: Lens' a Object
291+
292+ -- | The PagerDuty website URL where the full details regarding the initial
293+ -- event that triggered this incident can be found. (This is not the resource
294+ -- URL.)
295+ iTriggerDetailsHtmlUrl :: Lens' a Text
296+
297+ iIncidentNumber = incident.iIncidentNumber'
298+ iStatus = incident.iStatus'
299+ iCreatedOn = incident.iCreatedOn'._D
300+ iHtmlUrl = incident.iHtmlUrl'
301+ iIncidentKey = incident.iIncidentKey'
302+ iService = incident.iService'
303+ iEscalationPolicy = incident.iEscalationPolicy'
304+ iAssignedTo = incident.iAssignedTo'
305+ iAcknowledgers = incident.iAcknowledgers'
306+ iLastStatusChangeBy = incident.iLastStatusChangeBy'
307+ iLastStatusChangeOn = incident.iLastStatusChangeOn'.mapping _D
308+ iTriggerSummaryData = incident.iTriggerSummaryData'
309+ iTriggerDetailsHtmlUrl = incident.iTriggerDetailsHtmlUrl'
310+
311+instance HasIncident Incident where
312+ incident = id
313+
314+data ListIncidents = ListIncidents
315+ { _lsSince' :: Maybe Date
316+ , _lsUntil' :: Maybe Date
317+ , _lsDateRange' :: Maybe Range
318+ , _lsStatus' :: Maybe (CSV IncidentStatus)
319+ , _lsIncidentKey' :: Maybe IncidentKey
320+ , _lsService' :: Maybe (CSV ServiceId)
321+ , _lsAssignedToUser' :: Maybe (CSV UserId)
322+ , _lsTimeZone' :: !TZ
323+ , _lsSortBy' :: Maybe (Sort Field)
324+ } deriving (Eq, Show)
325+
326+queryRequest ''ListIncidents
327+
328+instance Paginate ListIncidents
329+
330+-- | The start of the date range over which you want to search.
331+lsSince :: Lens' (Request ListIncidents s b) (Maybe UTCTime)
332+lsSince = upd.lsSince'.mapping _D
333+
334+-- | The end of the date range over which you want to search.
335+--
336+-- /Note: If you leave off either since or until, a 30 day default range is
337+-- applied to your open ended range. Not including the since parameter will set
338+-- the date range to until - 30 days. Likewise, if you leave off until,
339+-- it is set to since + 30 days.
340+--
341+-- Defaults to the last 30 days if you leave off both. The size of the date
342+-- range must be less than 180 days.
343+lsUntil :: Lens' (Request ListIncidents s b) (Maybe UTCTime)
344+lsUntil = upd.lsUntil'.mapping _D
345+
346+-- | When set, the since and until parameters and defaults are
347+-- ignored. Use this to get all incidents since the account was created.
348+lsDateRange :: Lens' (Request ListIncidents s b) Bool
349+lsDateRange = upd.lens get_ (flip set_)
350+ where
351+ get_ = (Just All ==) . view lsDateRange'
352+ set_ x = lsDateRange' .~ listToMaybe [All | x]
353+
354+-- | Returns only the incidents currently in the passed status(es).
355+lsStatus :: Lens' (Request ListIncidents s b) (Maybe [IncidentStatus])
356+lsStatus = upd.lsStatus'.mapping _CSV
357+
358+-- | Returns only the incidents with the passed de-duplication key.
359+--
360+-- /See:/ "Network.PagerDuty.Integration"
361+lsIncidentKey :: Lens' (Request ListIncidents s b) (Maybe IncidentKey)
362+lsIncidentKey = upd.lsIncidentKey'
363+
364+-- | Returns only the incidents associated with the passed service(s). This
365+-- expects one or more service IDs.
366+lsService :: Lens' (Request ListIncidents s b) (Maybe [ServiceId])
367+lsService = upd.lsService'.mapping _CSV
368+
369+-- | Returns only the incidents currently assigned to the passed user(s). This
370+-- expects one or more user IDs.
371+--
372+-- /Note:/ When using the assignedToUser filter, you will only receive
373+-- incidents with statuses of triggered or acknowledged. This is because resolved
374+-- incidents are not assigned to any user.
375+lsAssignedToUser :: Lens' (Request ListIncidents s b) (Maybe [UserId])
376+lsAssignedToUser = upd.lsAssignedToUser'.mapping _CSV
377+
378+-- | Time zone in which dates in the result will be rendered.
379+--
380+-- /Default:/ 'UTC'.
381+lsTimeZone :: Lens' (Request ListIncidents s b) TimeZone
382+lsTimeZone = upd.lsTimeZone'._TZ
383+
384+-- | Used to specify both the field you wish to sort the results on, as well as
385+-- the direction (ascending/descending) of the results.
386+lsSortBy :: Lens' (Request ListIncidents s b) (Maybe (Sort Field))
387+lsSortBy = upd.lsSortBy'
388+
389+-- | The PagerDuty incidents query API can be used to query current and
390+-- historical PagerDuty incidents over a date range, letting you build custom
391+-- dashboards or incident reports. The API allows for searching for incidents
392+-- with multiple filters or query parameters, various sorts, and also supports
393+-- the pagination of results.
394+--
395+-- @GET \/incidents@
396+--
397+-- /See:/ <http://developer.pagerduty.com/documentation/rest/incidents/list>
398+listIncidents :: Request ListIncidents s [Incident]
399+listIncidents =
400+ mk ListIncidents
401+ { _lsSince' = Nothing
402+ , _lsUntil' = Nothing
403+ , _lsDateRange' = Nothing
404+ , _lsStatus' = Nothing
405+ , _lsIncidentKey' = Nothing
406+ , _lsService' = Nothing
407+ , _lsAssignedToUser' = Nothing
408+ , _lsTimeZone' = def
409+ , _lsSortBy' = Nothing
410+ } & path .~ incidents
411+
412+-- | Get detailed information about an incident. Accepts either an incident id,
413+-- or an incident number.
414+--
415+-- @GET \/incidents\/\:id@
416+--
417+-- /See:/ <http://developer.pagerduty.com/documentation/rest/incidents/show>
418+getIncident :: IncidentId -> Request Empty s Incident
419+getIncident i = empty & path .~ incidents % i
420+
421+data CountIncidents = CountIncidents
422+ { _cSince' :: Maybe Date
423+ , _cUntil' :: Maybe Date
424+ , _cDateRange' :: Maybe Range
425+ , _cStatus' :: Maybe (CSV IncidentStatus)
426+ , _cIncidentKey' :: Maybe IncidentKey
427+ , _cService' :: Maybe (CSV ServiceId)
428+ , _cAssignedToUser' :: Maybe (CSV UserId)
429+ } deriving (Eq, Show)
430+
431+queryRequest ''CountIncidents
432+
433+-- | The start of the date range over which you want to search.
434+cSince :: Lens' (Request CountIncidents s b) (Maybe UTCTime)
435+cSince = upd.cSince'.mapping _D
436+
437+-- | The end of the date range over which you want to search.
438+--
439+-- /Note: If you leave off either since or until, a 30 day default range is
440+-- applied to your open ended range. Not including the since parameter will set
441+-- the date range to until - 30 days. Likewise, if you leave off until,
442+-- it is set to since + 30 days.
443+--
444+-- Defaults to the last 30 days if you leave off both. The size of the date
445+-- range must be less than 180 days.
446+cUntil :: Lens' (Request CountIncidents s b) (Maybe UTCTime)
447+cUntil = upd.cUntil'.mapping _D
448+
449+-- | When set, the since and until parameters and defaults are
450+-- ignored. Use this to get all counts since the account was created.
451+cDateRange :: Lens' (Request CountIncidents s b) Bool
452+cDateRange = upd.lens get_ (flip set_)
453+ where
454+ get_ = (Just All ==) . view cDateRange'
455+ set_ x = cDateRange' .~ listToMaybe [All | x]
456+
457+-- | Only counts the incidents currently in the passed status(es).
458+cStatus :: Lens' (Request CountIncidents s b) (Maybe [IncidentStatus])
459+cStatus = upd.cStatus'.mapping _CSV
460+
461+-- | Returns only the incidents with the passed de-duplication key.
462+--
463+-- /See:/ "Network.PagerDuty.Integration"
464+cIncidentKey :: Lens' (Request CountIncidents s b) (Maybe IncidentKey)
465+cIncidentKey = upd.cIncidentKey'
466+
467+-- | Only counts the incidents associated with the passed service(s).
468+-- This is expecting one or more service IDs.
469+cService :: Lens' (Request CountIncidents s b) (Maybe [ServiceId]) -- list1
470+cService = upd.cService'.mapping _CSV
471+
472+-- | Only counts the incidents currently assigned to the passed user(s).
473+-- This is expecting one or more user IDs.
474+--
475+-- /Note:/ When using the assigned_to_user filter, you will only count
476+-- incidents with statuses of triggered or acknowledged. This is because resolved
477+-- incidents are not assigned to any user.
478+cAssignedToUser :: Lens' (Request CountIncidents s b) (Maybe [UserId]) -- list1
479+cAssignedToUser = upd.cAssignedToUser'.mapping _CSV
480+
481+newtype Count = Count Int
482+ deriving (Eq, Ord, Show, Bounded, Enum, Num, Integral, Real)
483+
484+instance FromJSON Count where
485+ parseJSON = withObject "count" $ \o -> Count <$> o .: "total"
486+
487+-- | Use this query if you are simply looking for the count of incidents that
488+-- match a given query. This should be used if you don't need access to the
489+-- actual incident details.
490+--
491+-- @GET \/incidents\/count@
492+--
493+-- /See:/ <http://developer.pagerduty.com/documentation/rest/incidents/count>
494+countIncidents :: Request CountIncidents s Count
495+countIncidents =
496+ mk CountIncidents
497+ { _cSince' = Nothing
498+ , _cUntil' = Nothing
499+ , _cDateRange' = Nothing
500+ , _cStatus' = Nothing
501+ , _cIncidentKey' = Nothing
502+ , _cService' = Nothing
503+ , _cAssignedToUser' = Nothing
504+ } & path .~ incidents % "count"
505+
506+
507+data UpdateStatus
508+ = UAcknowledged
509+ | UResolved
510+ deriving (Eq, Show)
511+
512+deriveNullary ''UpdateStatus
513+
514+data UpdateIncident = UpdateIncident
515+ { _iiId :: IncidentId
516+ , _iiStatus :: Maybe UpdateStatus
517+ , _iiEscalationLevel :: Maybe Int
518+ , _iiEscalationPolicy :: Maybe EscalationPolicyId
519+ , _iiAssignedToUser :: Maybe (CSV UserId)
520+ } deriving (Eq, Show)
521+
522+deriveJSON ''UpdateIncident
523+
524+-- | The id of the incident to update.
525+makeLens "_iiId" ''UpdateIncident
526+
527+-- | The new status of the incident.
528+makeLens "_iiStatus" ''UpdateIncident
529+
530+-- | Escalate incident to this level in the escalation policy.
531+makeLens "_iiEscalationLevel" ''UpdateIncident
532+
533+-- | Delegate this incident to the specified escalation policy id.
534+-- This restarts the incident's escalation following the new policy.
535+makeLens "_iiEscalationPolicy" ''UpdateIncident
536+
537+-- | List of user IDs to assign this incident to.
538+makeLens "_iiAssignedToUser" ''UpdateIncident
539+
540+data UpdatedIncidents = UpdatedIncidents
541+ { _uiId :: IncidentId
542+ , _uiStatus :: IncidentStatus
543+ , _uiIncidentNumber :: !Int
544+ , _uiUrl :: Text
545+ , _uiError :: Maybe Object
546+ } deriving (Eq, Show)
547+
548+deriveRecord ''UpdatedIncidents
549+
550+data UpdateIncidents = UpdateIncidents
551+ { _uiIncidents' :: [UpdateIncident]
552+ } deriving (Eq, Show)
553+
554+jsonRequest ''UpdateIncidents
555+
556+uiIncidents :: Lens' (Request UpdateIncidents s b) [UpdateIncident]
557+uiIncidents = upd.uiIncidents'
558+
559+-- | Acknowledge, resolve, escalate or reassign one or more incidents.
560+--
561+-- @PUT \/incidents@
562+--
563+-- /See:/ <http://developer.pagerduty.com/documentation/rest/incidents/update>
564+updateIncidents :: RequesterId -> Request UpdateIncidents s [UpdatedIncidents]
565+updateIncidents r = auth updateIncidentsBasic & query .~ [("requester_id", r)]
566+
567+-- | A version of 'updateIncidents' which uses HTTP Basic authentication and
568+-- doesn't require a 'RequesterId'.
569+updateIncidentsBasic :: Request UpdateIncidents Basic [UpdatedIncidents]
570+updateIncidentsBasic =
571+ mk UpdateIncidents
572+ { _uiIncidents' = []
573+ } & meth .~ PUT
574+ & path .~ incidents
575+
576+-- | Resolve an incident.
577+--
578+-- @PUT \/incidents\/\:id\/resolve@
579+--
580+-- /See:/ <http://developer.pagerduty.com/documentation/rest/incidents/resolve>
581+resolveIncident :: IncidentId
582+ -> RequesterId
583+ -> Request Empty s Empty
584+resolveIncident i r =
585+ auth (resolveIncidentBasic i) & query .~ [("requester_id", r)]
586+
587+-- | A version of 'resolveIncident' which uses HTTP Basic authentication and
588+-- doesn't require a 'RequesterId'.
589+resolveIncidentBasic :: IncidentId -> Request Empty s Empty
590+resolveIncidentBasic i = empty & meth .~ PUT & path .~ incidents % i % "resolve"
591+
592+-- | Acknowledge an incident.
593+--
594+-- @PUT \/incidents\/\:id\/acknowledge@
595+--
596+-- /See:/ <http://developer.pagerduty.com/documentation/rest/incidents/acknowledge>
597+acknowledgeIncident :: IncidentId
598+ -> RequesterId
599+ -> Request Empty s Empty
600+acknowledgeIncident i r =
601+ auth (acknowledgeIncidentBasic i) & query .~ [("requester_id", r)]
602+
603+-- | A version of 'acknowledgeIncident' which uses HTTP Basic authentication and
604+-- doesn't require a 'RequesterId'.
605+acknowledgeIncidentBasic :: IncidentId -> Request Empty s Empty
606+acknowledgeIncidentBasic i =
607+ empty & meth .~ PUT & path .~ incidents % i % "acknowledge"
608+
609+data ReassignIncident = ReassignIncident
610+ { _riEscalationPolicy' :: Maybe EscalationPolicyId
611+ , _riEscalationLevel' :: Maybe Int
612+ , _riAssignedToUser' :: Maybe (CSV UserId)
613+ } deriving (Eq, Show)
614+
615+jsonRequest ''ReassignIncident
616+
617+-- | The ID of an escalation policy. Delegate the incident to this escalation
618+-- policy.
619+riEscalationPolicy :: Lens' (Request ReassignIncident s b) (Maybe EscalationPolicyId)
620+riEscalationPolicy = upd.riEscalationPolicy'
621+
622+-- | Escalate incident to this level in the escalation policy.
623+riEscalationLevel :: Lens' (Request ReassignIncident s b) (Maybe Int)
624+riEscalationLevel = upd.riEscalationLevel'
625+
626+-- | Comma separated list of user IDs to assign this incident to.
627+riAssignedToUser :: Lens' (Request ReassignIncident s b) (Maybe [UserId])
628+riAssignedToUser = upd.riAssignedToUser'.mapping _CSV
629+
630+-- | Reassign an incident.
631+--
632+-- @PUT \/incidents\/\:id\/reassign@
633+--
634+-- /See:/ <http://developer.pagerduty.com/documentation/rest/incidents/reassign>
635+reassignIncident :: IncidentId
636+ -> RequesterId
637+ -> Request ReassignIncident s Empty
638+reassignIncident i r =
639+ auth (reassignIncidentBasic i) & query .~ [("requester_id", r)]
640+
641+-- | A version of 'reassignIncident' which uses HTTP Basic authentication and
642+-- doesn't require a 'RequesterId'.
643+reassignIncidentBasic :: IncidentId -> Request ReassignIncident s Empty
644+reassignIncidentBasic i =
645+ mk ReassignIncident
646+ { _riEscalationPolicy' = Nothing
647+ , _riEscalationLevel' = Nothing
648+ , _riAssignedToUser' = Nothing
649+ } & meth .~ PUT
650+ & path .~ incidents % i % "reassign"