git.iko.soy/typeable/pagerduty
on develop help sign in
Adding
commita666fb4600f79ba4b114604456976fc787061781 authorBrendan Hay <brendan.g.hay@gmail.com> dateTue 7 Oct 2014, 12:00 (12 years ago) parentc346e35
9 files changed+338−17
pagerduty.cabal+1−1 src/Network/PagerDuty/REST.hs+3−1 src/Network/PagerDuty/REST/EscalationPolicies/EscalationRules.hs+1−1 src/Network/PagerDuty/REST/Incidents.hs+317−8 src/Network/PagerDuty/REST/Reports.hs+1−1 src/Network/PagerDuty/REST/Schedules.hs+1−1 src/Network/PagerDuty/REST/Services.hs+1−1 src/Network/PagerDuty/REST/Services/EmailFilters.hs+1−2 src/Network/PagerDuty/Types.hs+12−1
pagerduty.cabal+1−1
@@ -46,7 +46,7 @@ library
4646 -- , Network.PagerDuty.REST.Schedules
4747-- , Network.PagerDuty.REST.Schedules.Overrides
4848 -- , Network.PagerDuty.REST.Services
49− , Network.PagerDuty.REST.Services.EmailFilters
49+-- , Network.PagerDuty.REST.Services.EmailFilters
5050 , Network.PagerDuty.REST.Users
5151 , Network.PagerDuty.REST.Users.ContactMethods
5252 , Network.PagerDuty.REST.Users.NotificationRules
src/Network/PagerDuty/REST.hs+3−1
@@ -33,10 +33,12 @@ import Network.HTTP.Types
3333import Network.PagerDuty.IO
3434import Network.PagerDuty.Types
3535
36−-- | Make the type names consistent, for example:
36+-- Make the type names consistent, for example:
3737-- Suffix with *Details or *Info for results
3838-- No suffix for requests if necessary
3939
40+-- FIXME: verify correct actions are all paginated
41+
4042send :: (MonadIO m, FromJSON b)
4143 => Auth s
4244 -> SubDomain
src/Network/PagerDuty/REST/EscalationPolicies/EscalationRules.hs+1−1
@@ -75,7 +75,7 @@ import Network.PagerDuty.REST.Users
7575import Network.PagerDuty.TH
7676import Network.PagerDuty.Types
7777
78−default (Builder)
78+default (Path)
7979
8080rules :: PolicyId -> Path
8181rules p = "escalation_policies" % p % "escalation_rules"
src/Network/PagerDuty/REST/Incidents.hs+317−8
@@ -1,5 +1,12 @@
1−{-# LANGUAGE OverloadedStrings #-}
2−{-# LANGUAGE TemplateHaskell #-}
1+{-# LANGUAGE DataKinds #-}
2+{-# LANGUAGE ExtendedDefaultRules #-}
3+{-# LANGUAGE FlexibleInstances #-}
4+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
5+{-# LANGUAGE OverloadedStrings #-}
6+{-# LANGUAGE TemplateHaskell #-}
7+{-# LANGUAGE TypeFamilies #-}
8+
9+{-# OPTIONS_GHC -fno-warn-type-defaults #-}
310
411-- Module : Network.PagerDuty.REST.Incidents
512-- Copyright : (c) 2013-2014 Brendan Hay <brendan.g.hay@gmail.com>
@@ -33,7 +40,7 @@
3340--
3441-- Incidents and Incident Counts from the last 30 days are returned by
3542-- default. To change this default date range, see the documentation for the
36−-- since, until or date_range parameters.
43+-- since, until or dateRange parameters.
3744--
3845-- Note: that to create an incident you need to trigger it through the
3946-- "Network.PagerDuty.Integration" API.
@@ -44,17 +51,227 @@ module Network.PagerDuty.REST.Incidents
4451
4552 ) where
4653
54+import Control.Applicative hiding (empty)
4755import Control.Lens
48−import Data.Monoid
49−import Data.Text (Text)
56+import Data.Aeson
57+import Data.ByteString.Conversion (ToByteString(..))
58+import Data.Default
59+import Data.Monoid hiding (All)
60+import Data.Text (Text)
5061import Data.Time
5162import Network.HTTP.Types
63+import Network.PagerDuty.Query
5264import Network.PagerDuty.TH
5365import Network.PagerDuty.Types
5466
67+default (Path)
68+
5569incidents :: Path
5670incidents = "incidents"
5771
72+data Sort a
73+ = Desc a
74+ | Asc a
75+ deriving (Eq, Show)
76+
77+makePrisms ''Sort
78+
79+data Field
80+ = IncidentNumber
81+ -- ^ The number of your incident.
82+ | CreatedOn
83+ -- ^ The date/time the incident was triggered.
84+ | ResolvedOn
85+ -- ^ The date/time the incident was resolved.
86+ deriving (Eq, Show)
87+
88+instance QueryValues (Sort Field) where
89+ queryValues s = case s of
90+ Desc f -> ["desc:" <> field f]
91+ Asc f -> ["asc:" <> field f]
92+ where
93+ field IncidentNumber = "incidentNumber"
94+ field CreatedOn = "createdOn"
95+ field ResolvedOn = "resolvedOn"
96+
97+data Range = All
98+ deriving (Eq, Show)
99+
100+instance QueryValues Range where
101+ queryValues All = ["all"]
102+
103+data IncidentStatus
104+ = Triggered
105+ | Acknowledged
106+ | Resolved
107+ | Other Text
108+ deriving (Eq, Show)
109+
110+deriveNullary ''IncidentStatus
111+
112+instance ToByteString IncidentStatus where
113+ builder Triggered = "triggered"
114+ builder Acknowledged = "acknowledged"
115+ builder Resolved = "resolved"
116+ builder (Other t) = builder t
117+
118+data Assignee = Assignee
119+ { _aAt :: Date
120+ , _aObject :: Object
121+ } deriving (Eq, Show)
122+
123+deriveRecord ''Assignee
124+
125+data Incident = Incident
126+ { _iIncidentNumber :: !Int
127+ , _iStatus :: !IncidentStatus
128+ , _iCreatedOn :: Date
129+ , _iHtmlUrl :: Text
130+ , _iIncidentKey :: Maybe IncidentKey
131+ , _iService :: Object
132+ , _iEscalationPolicy :: Maybe Object
133+ , _iAssignedTo :: [Assignee]
134+ , _iAcknowledgers :: [Assignee]
135+ , _iLastStatusChangeBy :: Maybe Assignee
136+ , _iLastStatusChangeOn :: Maybe Date
137+ , _iTriggerSummaryData :: Object
138+ , _iTriggerDetailsHtmlUrl :: Text
139+ } deriving (Eq, Show)
140+
141+deriveJSON ''Incident
142+
143+-- | The number of the incident. This is unique across your account.
144+makeLens "_iIncidentNumber" ''Incident
145+
146+-- | The current status of the incident. Valid statuses are:
147+makeLens "_iStatus" ''Incident
148+
149+-- | The date/time the incident was triggered.
150+iCreatedOn :: Lens' Incident UTCTime
151+iCreatedOn = lens _iCreatedOn (\i x -> i { _iCreatedOn = x }) . _D
152+
153+-- | The PagerDuty website URL where the incident can be viewed and further
154+-- actions taken. This is not the resource URL.
155+makeLens "_iHtmlUrl" ''Incident
156+
157+-- | The incident's de-duplication key. See the PagerDuty Integration API docs
158+-- for further details.
159+makeLens "_iIncidentKey" ''Incident
160+
161+-- | The PagerDuty service that the incident belongs to. The service will
162+-- contain fields of its own.
163+makeLens "_iService" ''Incident
164+
165+-- | The escalation policy that the incident belongs to. The policy will
166+-- contain fields of its own.
167+makeLens "_iEscalationPolicy" ''Incident
168+
169+-- | The list of assignments of the incident. An assignment is an object
170+-- containing the assigned user as well as the date/time the incident was assigned
171+-- to that user. The user will contain fields of its own. This list is empty if
172+-- the status of the incident is resolved.
173+makeLens "_iAssignedTo" ''Incident
174+
175+-- | The list of acknowledgements of the incident. An acknowledgement is an
176+-- object containing the acknowleding object (either a user or the integration
177+-- API) as well as the date/time the incident was acknowledged. This field is only
178+-- present if the status of the incident is acknowledged. This field is sorted in
179+-- ascending order by acknowledgement time.
180+makeLens "_iAcknowledgers" ''Incident
181+
182+-- | The user who is responsible for the incident's last status change. If the incident is in the acknowledged or resolved status, this will be the user that took the first acknowledged or resolved action. If the incident was automatically resolved (say through the Event Integration API), or if the incident is in the triggered state, this will be null. User fields are the same as in the assignedToUser field above.
183+makeLens "_iLastStatusChangeBy" ''Incident
184+
185+-- | The date/time the incident's status last changed.
186+iLastStatusChangeOn :: Lens' Incident (Maybe UTCTime)
187+iLastStatusChangeOn =
188+ lens _iLastStatusChangeOn (\i x -> i { _iLastStatusChangeOn = x })
189+ . mapping _D
190+
191+-- | Some condensed information regarding the initial event that triggered this incident. This data will be a set of key/value pairs that vary depending on what sort of event triggered the incident (email, Event API request, etc). For instance, if an email triggered the incident, then the triggerSummaryData will likely contain a subject. There are no guarantees on the full presence of this data for every incident.
192+makeLens "_iTriggerSummaryData" ''Incident
193+
194+-- | The PagerDuty website URL where the full details regarding the initial event that triggered this incident can be found. (This is not the resource URL.)
195+makeLens "_iTriggerDetailsHtmlUrl" ''Incident
196+
197+data ListIncidents = ListIncidents
198+ { _lsSince' :: Maybe Date
199+ , _lsUntil' :: Maybe Date
200+ , _lsDateRange' :: Maybe Range
201+ , _lsStatus' :: Maybe (CSV IncidentStatus)
202+ , _lsIncidentKey' :: Maybe IncidentKey
203+ , _lsService' :: Maybe (CSV ServiceId)
204+ , _lsAssignedToUser' :: Maybe (CSV UserId)
205+ , _lsTimeZone' :: !TZ
206+ , _lsSortBy' :: Maybe (Sort Field)
207+ } deriving (Eq, Show)
208+
209+queryRequest ''ListIncidents
210+
211+instance Paginate ListIncidents
212+
213+-- | The start of the date range over which you want to search.
214+lsSince :: Lens' (Request ListIncidents s b) (Maybe UTCTime)
215+lsSince = upd.lsSince'.mapping _D
216+
217+-- | The end of the date range over which you want to search.
218+--
219+-- /Note: If you leave off either since or until, a 30 day default range is
220+-- applied to your open ended range. Not including the since parameter will set
221+-- the date range to until - 30 days. Likewise, if you leave off until,
222+-- it is set to since + 30 days.
223+--
224+-- Defaults to the last 30 days if you leave off both. The size of the date
225+-- range must be less than 180 days.
226+lsUntil :: Lens' (Request ListIncidents s b) (Maybe UTCTime)
227+lsUntil = upd.lsUntil'.mapping _D
228+
229+-- | When set, the since and until parameters and defaults are
230+-- ignored. Use this to get all incidents since the account was created.
231+lsDateRange :: Lens' (Request ListIncidents s b) Bool
232+lsDateRange = upd . lens get' set'
233+ where
234+ get' x
235+ | Just All <- _lsDateRange' x = True
236+ | otherwise = False
237+
238+ set' l x = l { _lsDateRange' = if x then Just All else Nothing }
239+
240+-- | Returns only the incidents currently in the passed status(es).
241+lsStatus :: Lens' (Request ListIncidents s b) (Maybe [IncidentStatus])
242+lsStatus = upd.lsStatus'.mapping _CSV
243+
244+-- | Returns only the incidents with the passed de-duplication key.
245+--
246+-- /See:/ "Network.PagerDuty.Integration"
247+lsIncidentKey :: Lens' (Request ListIncidents s b) (Maybe IncidentKey)
248+lsIncidentKey = upd.lsIncidentKey'
249+
250+-- | Returns only the incidents associated with the passed service(s). This
251+-- expects one or more service IDs.
252+lsService :: Lens' (Request ListIncidents s b) (Maybe [ServiceId])
253+lsService = upd.lsService'.mapping _CSV
254+
255+-- | Returns only the incidents currently assigned to the passed user(s). This
256+-- expects one or more user IDs.
257+--
258+-- /Note:/ When using the assignedToUser filter, you will only receive
259+-- incidents with statuses of triggered or acknowledged. This is because resolved
260+-- incidents are not assigned to any user.
261+lsAssignedToUser :: Lens' (Request ListIncidents s b) (Maybe [UserId])
262+lsAssignedToUser = upd.lsAssignedToUser'.mapping _CSV
263+
264+-- | Time zone in which dates in the result will be rendered.
265+--
266+-- /Default:/ 'UTC'.
267+lsTimeZone :: Lens' (Request ListIncidents s b) TimeZone
268+lsTimeZone = upd.lsTimeZone'._TZ
269+
270+-- | Used to specify both the field you wish to sort the results on, as well as
271+-- the direction (ascending/descending) of the results.
272+lsSortBy :: Lens' (Request ListIncidents s b) (Maybe (Sort Field))
273+lsSortBy = upd.lsSortBy'
274+
58275-- | The PagerDuty incidents query API can be used to query current and
59276-- historical PagerDuty incidents over a date range, letting you build custom
60277-- dashboards or incident reports. The API allows for searching for incidents
@@ -64,7 +281,19 @@ incidents = "incidents"
64281-- @GET \/incidents@
65282--
66283-- /See:/ <http://developer.pagerduty.com/documentation/rest/incidents/list>
67−listIncidents = undefined
284+listIncidents :: Request ListIncidents s [Incident]
285+listIncidents =
286+ mk ListIncidents
287+ { _lsSince' = Nothing
288+ , _lsUntil' = Nothing
289+ , _lsDateRange' = Nothing
290+ , _lsStatus' = Nothing
291+ , _lsIncidentKey' = Nothing
292+ , _lsService' = Nothing
293+ , _lsAssignedToUser' = Nothing
294+ , _lsTimeZone' = def
295+ , _lsSortBy' = Nothing
296+ } & path .~ incidents
68297
69298-- | Get detailed information about an incident. Accepts either an incident id,
70299-- or an incident number.
@@ -72,7 +301,77 @@ listIncidents = undefined
72301-- @GET \/incidents\/\:id@
73302--
74303-- /See:/ <http://developer.pagerduty.com/documentation/rest/incidents/show>
75−getIncident = undefined
304+getIncident :: IncidentId -> Request Empty s Incident
305+getIncident i = empty & path .~ incidents % i
306+
307+data CountIncidents = CountIncidents
308+ { _cSince' :: Maybe Date
309+ , _cUntil' :: Maybe Date
310+ , _cDateRange' :: Maybe Range
311+ , _cStatus' :: Maybe (CSV IncidentStatus)
312+ , _cIncidentKey' :: Maybe IncidentKey
313+ , _cService' :: Maybe (CSV ServiceId)
314+ , _cAssignedToUser' :: Maybe (CSV UserId)
315+ } deriving (Eq, Show)
316+
317+queryRequest ''CountIncidents
318+
319+-- | The start of the date range over which you want to search.
320+cSince :: Lens' (Request CountIncidents s b) (Maybe UTCTime)
321+cSince = upd.cSince'.mapping _D
322+
323+-- | The end of the date range over which you want to search.
324+--
325+-- /Note: If you leave off either since or until, a 30 day default range is
326+-- applied to your open ended range. Not including the since parameter will set
327+-- the date range to until - 30 days. Likewise, if you leave off until,
328+-- it is set to since + 30 days.
329+--
330+-- Defaults to the last 30 days if you leave off both. The size of the date
331+-- range must be less than 180 days.
332+cUntil :: Lens' (Request CountIncidents s b) (Maybe UTCTime)
333+cUntil = upd.cUntil'.mapping _D
334+
335+-- | When set, the since and until parameters and defaults are
336+-- ignored. Use this to get all counts since the account was created.
337+cDateRange :: Lens' (Request CountIncidents s b) Bool
338+cDateRange = upd . lens get' set'
339+ where
340+ get' x
341+ | Just All <- _cDateRange' x = True
342+ | otherwise = False
343+
344+ set' l x = l { _cDateRange' = if x then Just All else Nothing }
345+
346+-- | Only counts the incidents currently in the passed status(es).
347+cStatus :: Lens' (Request CountIncidents s b) (Maybe [IncidentStatus])
348+cStatus = upd.cStatus'.mapping _CSV
349+
350+-- | Returns only the incidents with the passed de-duplication key.
351+--
352+-- /See:/ "Network.PagerDuty.Integration"
353+cIncidentKey :: Lens' (Request CountIncidents s b) (Maybe IncidentKey)
354+cIncidentKey = upd.cIncidentKey'
355+
356+-- | Only counts the incidents associated with the passed service(s).
357+-- This is expecting one or more service IDs.
358+cService :: Lens' (Request CountIncidents s b) (Maybe [ServiceId]) -- list1
359+cService = upd.cService'.mapping _CSV
360+
361+-- | Only counts the incidents currently assigned to the passed user(s).
362+-- This is expecting one or more user IDs.
363+--
364+-- /Note:/ When using the assigned_to_user filter, you will only count
365+-- incidents with statuses of triggered or acknowledged. This is because resolved
366+-- incidents are not assigned to any user.
367+cAssignedToUser :: Lens' (Request CountIncidents s b) (Maybe [UserId]) -- list1
368+cAssignedToUser = upd.cAssignedToUser'.mapping _CSV
369+
370+newtype Count = Count Int
371+ deriving (Eq, Ord, Show, Bounded, Enum, Num, Integral, Real)
372+
373+instance FromJSON Count where
374+ parseJSON = withObject "count" $ \o -> Count <$> o .: "total"
76375
77376-- | Use this query if you are simply looking for the count of incidents that
78377-- match a given query. This should be used if you don't need access to the
@@ -81,7 +380,17 @@ getIncident = undefined
81380-- @GET \/incidents\/count@
82381--
83382-- /See:/ <http://developer.pagerduty.com/documentation/rest/incidents/count>
84−countIncidents = undefined
383+countIncidents :: Request CountIncidents s Count
384+countIncidents =
385+ mk CountIncidents
386+ { _cSince' = Nothing
387+ , _cUntil' = Nothing
388+ , _cDateRange' = Nothing
389+ , _cStatus' = Nothing
390+ , _cIncidentKey' = Nothing
391+ , _cService' = Nothing
392+ , _cAssignedToUser' = Nothing
393+ } & path .~ incidents % "count"
85394
86395-- | Acknowledge, resolve, escalate or reassign one or more incidents.
87396--
src/Network/PagerDuty/REST/Reports.hs+1−1
@@ -65,7 +65,7 @@ import Data.Time
6565import Network.PagerDuty.TH
6666import Network.PagerDuty.Types
6767
68−default (Builder)
68+default (Path)
6969
7070reports :: Path
7171reports = "reports"
src/Network/PagerDuty/REST/Schedules.hs+1−1
@@ -120,7 +120,7 @@ import Network.PagerDuty.REST.Users (User)
120120import Network.PagerDuty.TH
121121import Network.PagerDuty.Types
122122
123−default (Builder)
123+default (Path)
124124
125125schedules :: Path
126126schedules = "schedules"
src/Network/PagerDuty/REST/Services.hs+1−1
@@ -115,7 +115,7 @@ import Network.HTTP.Types
115115import Network.PagerDuty.TH
116116import Network.PagerDuty.Types
117117
118−default (Builder)
118+default (Path)
119119
120120services :: Path
121121services = "services"
src/Network/PagerDuty/REST/Services/EmailFilters.hs+1−2
@@ -42,7 +42,6 @@ module Network.PagerDuty.REST.Services.EmailFilters
4242import Control.Applicative hiding (empty)
4343import Control.Lens hiding ((.=))
4444import Data.Aeson
45−import Data.ByteString.Builder (Builder)
4645import Data.Default
4746import Data.Monoid
4847import Data.Text (Text)
@@ -50,7 +49,7 @@ import Network.HTTP.Types
5049import Network.PagerDuty.TH
5150import Network.PagerDuty.Types
5251
53−default (Builder)
52+default (Path)
5453
5554filters :: ServiceId -> Path
5655filters s = "services" % s % "email_filters"
src/Network/PagerDuty/Types.hs+12−1
@@ -62,7 +62,7 @@ import Data.ByteString.Conversion hiding (List)
6262import Data.Default
6363import Data.Function (on)
6464import qualified Data.HashMap.Strict as Map
65−import Data.List (deleteBy)
65+import Data.List (deleteBy, intersperse)
6666import Data.Monoid
6767import Data.String
6868import Data.Text (Text)
@@ -77,6 +77,16 @@ import System.Locale
7777
7878-- FIXME: Verify IncidentId/IncidentKey .. *Id/*Key are actually different or needed
7979
80+newtype CSV a = CSV [a]
81+ deriving (Eq, Show, Monoid)
82+
83+makePrisms ''CSV
84+
85+instance ToByteString a => ToByteString (CSV a) where
86+ builder (CSV xs) = mconcat . intersperse "," $ map builder xs
87+
88+instance ToByteString a => QueryValues (CSV a)
89+
8090newtype List a = L [a]
8191 deriving (Eq, Show, Monoid)
8292
@@ -391,6 +401,7 @@ type ServiceId = Id "service"
391401type UserId = Id "user"
392402type VendorId = Id "vendor"
393403type WindowId = Id "maintenance-window"
404+type IncidentId = Id "incident"
394405
395406data Empty = Empty
396407