pagerduty 2.1.3 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +117 -1
- data/README.md +167 -32
- data/lib/pagerduty.rb +61 -164
- data/lib/pagerduty/events_api_v1.rb +279 -0
- data/lib/pagerduty/events_api_v2.rb +280 -0
- data/lib/pagerduty/http_transport.rb +13 -12
- data/lib/pagerduty/legacy.rb +36 -0
- data/lib/pagerduty/version.rb +2 -2
- metadata +8 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 10e8332a28ba06cbed648d66d0ee4c367e9f179fe30ae4903846ab789070e596
|
4
|
+
data.tar.gz: 56d30e6a7276dceff80df33748def18474204b58c4835d2fd2c59cccace8df2f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4fc9193a4582aae06a8bbd6c886b99086142c7e9a57a4f09230e7152931f227d04c84007190629a9772a4c4e3a1d4a2f8a8f5fcb023f271c287f27c89f15c69d
|
7
|
+
data.tar.gz: a10af69c0ea9fb5b8cb88bcde086e9abbba12fdade60e08255d2192e75450994527256d0bb47947bb05463871affc427874868c689ba9a87ececf671ec25a257
|
data/CHANGELOG.md
CHANGED
@@ -10,7 +10,123 @@ The format is based on [Keep a Changelog], and this project adheres to
|
|
10
10
|
|
11
11
|
## [Unreleased]
|
12
12
|
|
13
|
-
[Unreleased]: https://github.com/envato/pagerduty/compare/
|
13
|
+
[Unreleased]: https://github.com/envato/pagerduty/compare/v3.0.0...HEAD
|
14
|
+
|
15
|
+
## [3.0.0] - 2020-04-20
|
16
|
+
|
17
|
+
### Added
|
18
|
+
|
19
|
+
- A new mechanism for instantiating a Pagerduty instance ([#64]).
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
pagerduty = Pagerduty.build(integration_key: "<my-integration-key>",
|
23
|
+
api_version: 1)
|
24
|
+
```
|
25
|
+
|
26
|
+
This new method will return an instance that implements requested PagerDuty
|
27
|
+
Events API version.
|
28
|
+
|
29
|
+
- Support for the [Pagerduty Events API version 2][events-v2-docs] ([#66]).
|
30
|
+
|
31
|
+
```ruby
|
32
|
+
pagerduty = Pagerduty.build(
|
33
|
+
integration_key: "<my-integration-key>",
|
34
|
+
api_version: 2
|
35
|
+
)
|
36
|
+
incident = pagerduty.trigger(
|
37
|
+
summary: "summary",
|
38
|
+
source: "source",
|
39
|
+
severity: "critical"
|
40
|
+
)
|
41
|
+
incident.acknowledge
|
42
|
+
incident.resolve
|
43
|
+
```
|
44
|
+
|
45
|
+
- Added an `incident` method to the Pagerduty Events API V1 instance ([#67]).
|
46
|
+
This is intended as a drop-in replacement for the now-deprecated
|
47
|
+
`get_incident` method.
|
48
|
+
|
49
|
+
```ruby
|
50
|
+
pagerduty = Pagerduty.build(
|
51
|
+
integration_key: "<integration-key>",
|
52
|
+
api_version: 1
|
53
|
+
)
|
54
|
+
incident = pagerduty.incident("<incident-key>")
|
55
|
+
```
|
56
|
+
|
57
|
+
### Deprecated
|
58
|
+
|
59
|
+
- Using `new` on `Pagerduty` ([#64]). This works, but will be removed in the
|
60
|
+
next major version.
|
61
|
+
|
62
|
+
```diff
|
63
|
+
- pagerduty = Pagerduty.new("<integration-key>")
|
64
|
+
+ pagerduty = Pagerduty.build(integration_key: "<integration-key>", api_version: 1)
|
65
|
+
pagerduty.trigger("<incident description>")
|
66
|
+
incident.acknowledge
|
67
|
+
incident.resolve
|
68
|
+
```
|
69
|
+
|
70
|
+
Instead, use the new `Pagerduty.build` method (see above).
|
71
|
+
|
72
|
+
- The `get_incident` method is now deprecated ([#67]). It still works, but
|
73
|
+
will be removed in the next major release. Please migrate to the new
|
74
|
+
`incident` method, that works in exactly the same way.
|
75
|
+
|
76
|
+
```diff
|
77
|
+
pagerduty = Pagerduty.new("<integration-key>")
|
78
|
+
- incident = pagerduty.get_incident("<incident-key>")
|
79
|
+
+ incident = pagerduty.incident("<incident-key>")
|
80
|
+
incident.trigger("<incident description>")
|
81
|
+
incident.acknowledge
|
82
|
+
incident.resolve
|
83
|
+
```
|
84
|
+
|
85
|
+
### Changed
|
86
|
+
|
87
|
+
- `Pagerduty` is no longer a class. It's now a Ruby module ([#64]). This will
|
88
|
+
break implementations that use `Pagerduty` in their inheritance tree.
|
89
|
+
|
90
|
+
- `PagerdutyIncident` no-longer inherits from `Pagerduty` and its initializer
|
91
|
+
parameters have changed ([#64]). Actually, it's now an alias of the
|
92
|
+
`Pagerduty::EventsApiV1:Incident` class.
|
93
|
+
|
94
|
+
### Removed
|
95
|
+
|
96
|
+
- Can no longer specify a new incident key when triggering from an `Incident`
|
97
|
+
object ([#64]).
|
98
|
+
|
99
|
+
This will now raise an `ArgumentError`. eg.
|
100
|
+
|
101
|
+
```ruby
|
102
|
+
incident1 = pagerduty.trigger('first incident', incident_key: 'one') # this'll work fine
|
103
|
+
incident2 = incident1.trigger('second incident', incident_key: 'two') # this no-longer works.
|
104
|
+
```
|
105
|
+
|
106
|
+
The difference is in the object we're calling the method on.
|
107
|
+
|
108
|
+
Instead always use the pagerduty object when triggering new incidents (with
|
109
|
+
new incident keys).
|
110
|
+
|
111
|
+
This works with the Events API V1:
|
112
|
+
|
113
|
+
```ruby
|
114
|
+
incident1 = pagerduty.trigger('first incident', incident_key: 'one')
|
115
|
+
incident2 = pagerduty.trigger('second incident', incident_key: 'two')
|
116
|
+
```
|
117
|
+
|
118
|
+
And this is even better, as it works with both the Events API V1 and V2:
|
119
|
+
|
120
|
+
```ruby
|
121
|
+
incident1 = pagerduty.incident('one').trigger('first incident')
|
122
|
+
incident2 = pagerduty.incident('two').trigger('second incident')
|
123
|
+
```
|
124
|
+
|
125
|
+
[3.0.0]: https://github.com/envato/pagerduty/compare/v2.1.3...v3.0.0
|
126
|
+
[events-v2-docs]: https://v2.developer.pagerduty.com/docs/send-an-event-events-api-v2
|
127
|
+
[#64]: https://github.com/envato/pagerduty/pull/64
|
128
|
+
[#66]: https://github.com/envato/pagerduty/pull/66
|
129
|
+
[#67]: https://github.com/envato/pagerduty/pull/67
|
14
130
|
|
15
131
|
## [2.1.3] - 2020-02-10
|
16
132
|
|
data/README.md
CHANGED
@@ -1,13 +1,14 @@
|
|
1
1
|
# pagerduty
|
2
2
|
|
3
|
-
|
4
3
|
[![License MIT](https://img.shields.io/badge/license-MIT-brightgreen.svg)](https://github.com/envato/pagerduty/blob/master/LICENSE.txt)
|
5
4
|
[![Gem Version](https://img.shields.io/gem/v/pagerduty.svg?maxAge=2592000)](https://rubygems.org/gems/pagerduty)
|
6
5
|
[![Gem Downloads](https://img.shields.io/gem/dt/pagerduty.svg?maxAge=2592000)](https://rubygems.org/gems/pagerduty)
|
7
6
|
[![Build Status](https://travis-ci.org/envato/pagerduty.svg?branch=master)](https://travis-ci.org/envato/pagerduty)
|
8
7
|
|
9
|
-
Provides a lightweight Ruby interface for calling the [PagerDuty
|
10
|
-
|
8
|
+
Provides a lightweight Ruby interface for calling the [PagerDuty Events
|
9
|
+
API][events-v2-docs].
|
10
|
+
|
11
|
+
[events-v2-docs]: https://v2.developer.pagerduty.com/docs/send-an-event-events-api-v2
|
11
12
|
|
12
13
|
## Installation
|
13
14
|
|
@@ -27,58 +28,171 @@ Or install it yourself as:
|
|
27
28
|
|
28
29
|
## Usage
|
29
30
|
|
31
|
+
### Events API V2
|
32
|
+
|
30
33
|
```ruby
|
31
|
-
#
|
32
|
-
|
34
|
+
# Instantiate a Pagerduty service object providing an integration key and the
|
35
|
+
# desired API version: 2
|
36
|
+
pagerduty = Pagerduty.build(
|
37
|
+
integration_key: "<integration-key>",
|
38
|
+
api_version: 2
|
39
|
+
)
|
33
40
|
|
34
|
-
#
|
35
|
-
|
41
|
+
# Trigger an incident providing minimal details
|
42
|
+
incident = pagerduty.trigger(
|
43
|
+
summary: "summary",
|
44
|
+
source: "source",
|
45
|
+
severity: "critical"
|
46
|
+
)
|
36
47
|
|
37
|
-
# Trigger an incident
|
38
|
-
incident = pagerduty.trigger(
|
48
|
+
# Trigger an incident providing full context
|
49
|
+
incident = pagerduty.trigger(
|
50
|
+
summary: "Example alert on host1.example.com",
|
51
|
+
source: "monitoringtool:cloudvendor:central-region-dc-01:852559987:cluster/api-stats-prod-003",
|
52
|
+
severity: %w[critical error warning info].sample,
|
53
|
+
timestamp: Time.now,
|
54
|
+
component: "postgres",
|
55
|
+
group: "prod-datapipe",
|
56
|
+
class: "deploy",
|
57
|
+
custom_details: {
|
58
|
+
ping_time: "1500ms",
|
59
|
+
load_avg: 0.75
|
60
|
+
},
|
61
|
+
images: [
|
62
|
+
{
|
63
|
+
src: "https://www.pagerduty.com/wp-content/uploads/2016/05/pagerduty-logo-green.png",
|
64
|
+
href: "https://example.com/",
|
65
|
+
alt: "Example text",
|
66
|
+
},
|
67
|
+
],
|
68
|
+
links: [
|
69
|
+
{
|
70
|
+
href: "https://example.com/",
|
71
|
+
text: "Link text",
|
72
|
+
},
|
73
|
+
],
|
74
|
+
client: "Sample Monitoring Service",
|
75
|
+
client_url: "https://monitoring.example.com"
|
76
|
+
)
|
39
77
|
|
40
78
|
# Acknowledge and/or resolve the incident
|
41
79
|
incident.acknowledge
|
42
80
|
incident.resolve
|
43
81
|
|
44
|
-
#
|
45
|
-
|
82
|
+
# Provide a client-defined incident key
|
83
|
+
# (this can be used to update existing incidents)
|
84
|
+
incident = pagerduty.incident("<incident-key>")
|
85
|
+
incident.trigger(
|
86
|
+
summary: "summary",
|
87
|
+
source: "source",
|
88
|
+
severity: "critical"
|
89
|
+
)
|
46
90
|
incident.acknowledge
|
47
91
|
incident.resolve
|
48
92
|
```
|
49
93
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
94
|
+
See the [PagerDuty Events API V2 documentation][events-v2-docs] for a
|
95
|
+
detailed description on the parameters you can send when triggering an
|
96
|
+
incident.
|
97
|
+
|
98
|
+
### Events API V1
|
99
|
+
|
100
|
+
The following code snippet shows how to use the [Pagerduty Events API version
|
101
|
+
1](https://v2.developer.pagerduty.com/docs/events-api).
|
54
102
|
|
55
103
|
```ruby
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
104
|
+
# Instantiate a Pagerduty with a service integration key
|
105
|
+
pagerduty = Pagerduty.build(
|
106
|
+
integration_key: "<integration-key>",
|
107
|
+
api_version: 1,
|
108
|
+
)
|
109
|
+
|
110
|
+
# Trigger an incident
|
111
|
+
incident = pagerduty.trigger(
|
112
|
+
"FAILURE for production/HTTP on machine srv01.acme.com",
|
113
|
+
)
|
114
|
+
|
115
|
+
# Trigger an incident providing context and details
|
116
|
+
incident = pagerduty.trigger(
|
117
|
+
"FAILURE for production/HTTP on machine srv01.acme.com",
|
118
|
+
client: "Sample Monitoring Service",
|
119
|
+
client_url: "https://monitoring.service.com",
|
120
|
+
contexts: [
|
121
|
+
{
|
122
|
+
type: "link",
|
123
|
+
href: "http://acme.pagerduty.com",
|
124
|
+
text: "View the incident on PagerDuty",
|
125
|
+
},
|
126
|
+
{
|
127
|
+
type: "image",
|
128
|
+
src: "https://chart.googleapis.com/chart?chs=600x400&chd=t:6,2,9,5,2,5,7,4,8,2,1&cht=lc&chds=a&chxt=y&chm=D,0033FF,0,0,5,1",
|
129
|
+
}
|
130
|
+
],
|
131
|
+
details: {
|
132
|
+
ping_time: "1500ms",
|
133
|
+
load_avg: 0.75,
|
134
|
+
},
|
62
135
|
)
|
136
|
+
|
137
|
+
# Acknowledge the incident
|
138
|
+
incident.acknowledge
|
139
|
+
|
140
|
+
# Acknowledge, providing a description and extra details
|
141
|
+
incident.acknowledge(
|
142
|
+
"Engineers are investigating the incident",
|
143
|
+
{
|
144
|
+
ping_time: "1700ms",
|
145
|
+
load_avg: 0.71,
|
146
|
+
}
|
147
|
+
)
|
148
|
+
|
149
|
+
# Resolve the incident
|
150
|
+
incident.resolve
|
151
|
+
|
152
|
+
# Resolve, providing a description and extra details
|
153
|
+
incident.acknowledge(
|
154
|
+
"A fix has been deployed and the service has recovered",
|
155
|
+
{
|
156
|
+
ping_time: "120ms",
|
157
|
+
load_avg: 0.23,
|
158
|
+
}
|
159
|
+
)
|
160
|
+
|
161
|
+
# Provide a client defined incident key
|
162
|
+
# (this can be used to update existing incidents)
|
163
|
+
incident = pagerduty.incident("<incident-key>")
|
164
|
+
incident.trigger("Description of the event")
|
165
|
+
incident.acknowledge
|
166
|
+
incident.resolve
|
63
167
|
```
|
64
168
|
|
169
|
+
See the [PagerDuty Events API V1
|
170
|
+
documentation](https://v2.developer.pagerduty.com/docs/trigger-events) for a
|
171
|
+
detailed description of the parameters you can send when triggering an
|
172
|
+
incident.
|
173
|
+
|
65
174
|
### HTTP Proxy Support
|
66
175
|
|
67
176
|
One can explicitly define an HTTP proxy like this:
|
68
177
|
|
69
178
|
```ruby
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
179
|
+
pagerduty = Pagerduty.build(
|
180
|
+
integration_key: "<integration-key>",
|
181
|
+
api_version: 2, # The HTTP proxy settings work with either API version
|
182
|
+
http_proxy: {
|
183
|
+
host: "my.http.proxy.local",
|
184
|
+
port: 3128,
|
185
|
+
username: "<my-proxy-username>",
|
186
|
+
password: "<my-proxy-password>",
|
187
|
+
}
|
77
188
|
)
|
78
189
|
|
79
|
-
#
|
80
|
-
|
81
|
-
|
190
|
+
# Subsequent API calls will then be sent via the HTTP proxy
|
191
|
+
incident = pagerduty.trigger(
|
192
|
+
summary: "summary",
|
193
|
+
source: "source",
|
194
|
+
severity: "critical"
|
195
|
+
)
|
82
196
|
```
|
83
197
|
|
84
198
|
### Debugging Error Responses
|
@@ -88,7 +202,11 @@ go about debugging these unhappy cases:
|
|
88
202
|
|
89
203
|
```ruby
|
90
204
|
begin
|
91
|
-
pagerduty.trigger(
|
205
|
+
pagerduty.trigger(
|
206
|
+
summary: "summary",
|
207
|
+
source: "source",
|
208
|
+
severity: "critical"
|
209
|
+
)
|
92
210
|
rescue Net::HTTPServerException => error
|
93
211
|
error.response.code #=> "400"
|
94
212
|
error.response.message #=> "Bad Request"
|
@@ -96,6 +214,23 @@ rescue Net::HTTPServerException => error
|
|
96
214
|
end
|
97
215
|
```
|
98
216
|
|
217
|
+
### Legacy Interface
|
218
|
+
|
219
|
+
The older Ruby interface from version 2 of the gem is still available.
|
220
|
+
However, this is deprecated and will be removed in the next major release.
|
221
|
+
|
222
|
+
```ruby
|
223
|
+
# Instantiate a Pagerduty with your specific service key
|
224
|
+
pagerduty = Pagerduty.new("<my-integration-key>")
|
225
|
+
|
226
|
+
# Trigger an incident
|
227
|
+
incident = pagerduty.trigger("incident description")
|
228
|
+
|
229
|
+
# Acknowledge and resolve the incident
|
230
|
+
incident.acknowledge
|
231
|
+
incident.resolve
|
232
|
+
```
|
233
|
+
|
99
234
|
## Contributing
|
100
235
|
|
101
236
|
1. Fork it ( https://github.com/envato/pagerduty/fork )
|
data/lib/pagerduty.rb
CHANGED
@@ -2,6 +2,9 @@
|
|
2
2
|
|
3
3
|
require "pagerduty/version"
|
4
4
|
require "pagerduty/http_transport"
|
5
|
+
require "pagerduty/events_api_v1"
|
6
|
+
require "pagerduty/events_api_v2"
|
7
|
+
require "pagerduty/legacy"
|
5
8
|
|
6
9
|
class PagerdutyException < StandardError
|
7
10
|
attr_reader :pagerduty_instance, :api_response
|
@@ -13,179 +16,73 @@ class PagerdutyException < StandardError
|
|
13
16
|
end
|
14
17
|
end
|
15
18
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
22
|
-
#
|
23
|
-
#
|
24
|
-
#
|
25
|
-
#
|
26
|
-
#
|
27
|
-
#
|
19
|
+
module Pagerduty
|
20
|
+
# Build an instance that will send API calls to the specified Pagerduty
|
21
|
+
# Events API version.
|
22
|
+
#
|
23
|
+
# @example Build an instance for the Events API version 1
|
24
|
+
# pagerduty = Pagerduty.build(
|
25
|
+
# integration_key: "<integration-key>",
|
26
|
+
# api_version: 1,
|
27
|
+
# )
|
28
|
+
#
|
29
|
+
# @example Build an instance using an HTTP proxy for API requests
|
30
|
+
# pagerduty = Pagerduty.build(
|
31
|
+
# integration_key: "<integration-key>",
|
32
|
+
# api_version: 1,
|
33
|
+
# http_proxy: {
|
34
|
+
# host: "my.http.proxy.local",
|
35
|
+
# port: 3128,
|
36
|
+
# username: "<my-proxy-username>",
|
37
|
+
# password: "<my-proxy-password>",
|
38
|
+
# }
|
39
|
+
# )
|
40
|
+
#
|
41
|
+
# @option config [String] integration_key Authentication key for connecting
|
42
|
+
# to PagerDuty. A UUID expressed as a 32-digit hexadecimal number.
|
43
|
+
# Integration keys are generated by creating a new service, or creating a
|
44
|
+
# new integration for an existing service in PagerDuty, and can be found on
|
45
|
+
# a service's Integrations tab. This option is required.
|
46
|
+
#
|
47
|
+
# @option config [String] api_version The version of the Pagerduty events API.
|
48
|
+
# The gem currently supports version 1 (`1`). This option is required.
|
49
|
+
#
|
50
|
+
# @option config [String] http_proxy.host The DNS name or IP address of the
|
51
|
+
# proxy host. If nil or unprovided an HTTP proxy will not be used.
|
52
|
+
#
|
53
|
+
# @option config [String] http_proxy.port The TCP port to use to access the
|
54
|
+
# proxy.
|
55
|
+
#
|
56
|
+
# @option config [String] http_proxy.username username if authorization is
|
28
57
|
# required to use the proxy.
|
29
58
|
#
|
30
|
-
# @option
|
59
|
+
# @option config [String] http_proxy.password password if authorization is
|
31
60
|
# required to use the proxy.
|
32
61
|
#
|
33
|
-
|
34
|
-
@service_key = service_key
|
35
|
-
@transport = transport_from_options(options)
|
36
|
-
end
|
37
|
-
|
38
|
-
# Send PagerDuty a trigger event to report a new or ongoing problem. When
|
39
|
-
# PagerDuty receives a trigger event, it will either open a new incident, or
|
40
|
-
# add a new trigger log entry to an existing incident, depending on the
|
41
|
-
# provided incident_key.
|
42
|
-
#
|
43
|
-
# @param [String] description A short description of the problem that led to
|
44
|
-
# this trigger. This field (or a truncated version) will be used when
|
45
|
-
# generating phone calls, SMS messages and alert emails. It will also appear
|
46
|
-
# on the incidents tables in the PagerDuty UI. The maximum length is 1024
|
47
|
-
# characters.
|
62
|
+
# @return [Pagerduty::EventsApiV1] the built instance.
|
48
63
|
#
|
49
|
-
# @
|
50
|
-
#
|
51
|
-
# incident with this key, a new one will be created. If there's already an
|
52
|
-
# open incident with a matching key, this event will be appended to that
|
53
|
-
# incident's log. The event key provides an easy way to "de-dup" problem
|
54
|
-
# reports. If this field isn't provided, PagerDuty will automatically open a
|
55
|
-
# new incident with a unique key.
|
64
|
+
# @raise [ArgumentError] If integration_key or api_version options are not
|
65
|
+
# provided. Or if the provided api_version is unsupported.
|
56
66
|
#
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
# @option options [String] :client_url The URL of the monitoring client that
|
61
|
-
# is triggering this event.
|
62
|
-
#
|
63
|
-
# @option options [Hash] :details An arbitrary hash containing any data you'd
|
64
|
-
# like included in the incident log.
|
65
|
-
#
|
66
|
-
# @return [PagerdutyIncident] The triggered incident.
|
67
|
-
#
|
68
|
-
# @raise [PagerdutyException] If PagerDuty responds with a status that is not
|
69
|
-
# "success"
|
70
|
-
#
|
71
|
-
def trigger(description, options = {})
|
72
|
-
resp = api_call("trigger", options.merge(description: description))
|
73
|
-
ensure_success(resp)
|
74
|
-
PagerdutyIncident.new(
|
75
|
-
service_key,
|
76
|
-
resp["incident_key"],
|
77
|
-
transport: @transport,
|
78
|
-
)
|
79
|
-
end
|
80
|
-
|
81
|
-
# @param [String] incident_key The unique identifier for the incident.
|
82
|
-
#
|
83
|
-
# @return [PagerdutyIncident] The incident referenced by the key.
|
84
|
-
#
|
85
|
-
# @raise [ArgumentError] If incident_key is nil
|
86
|
-
#
|
87
|
-
def get_incident(incident_key)
|
88
|
-
raise ArgumentError, "incident_key is nil" if incident_key.nil?
|
89
|
-
|
90
|
-
PagerdutyIncident.new(
|
91
|
-
service_key,
|
92
|
-
incident_key,
|
93
|
-
transport: @transport,
|
94
|
-
)
|
95
|
-
end
|
96
|
-
|
97
|
-
protected
|
98
|
-
|
99
|
-
def api_call(event_type, args)
|
100
|
-
args = args.merge(
|
101
|
-
service_key: service_key,
|
102
|
-
event_type: event_type,
|
103
|
-
)
|
104
|
-
@transport.send_payload(args)
|
105
|
-
end
|
106
|
-
|
107
|
-
def ensure_success(response)
|
108
|
-
unless response["status"] == "success"
|
109
|
-
raise PagerdutyException.new(self, response, response["message"])
|
67
|
+
def self.build(config)
|
68
|
+
unless config.key?(:integration_key)
|
69
|
+
raise ArgumentError, "integration_key not provided"
|
110
70
|
end
|
111
|
-
|
112
|
-
|
113
|
-
private
|
71
|
+
raise ArgumentError, "incident_key provided" if config.key?(:incident_key)
|
114
72
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
end
|
120
|
-
|
121
|
-
class PagerdutyIncident < Pagerduty
|
122
|
-
attr_reader :incident_key
|
123
|
-
|
124
|
-
# @param [String] service_key The GUID of one of your "Generic API" services.
|
125
|
-
# This is the "service key" listed on a Generic API's service detail page.
|
126
|
-
#
|
127
|
-
# @param [String] incident_key The unique identifier for the incident.
|
128
|
-
#
|
129
|
-
def initialize(service_key, incident_key, options = {})
|
130
|
-
super service_key, options
|
131
|
-
@incident_key = incident_key
|
132
|
-
end
|
133
|
-
|
134
|
-
# @param (see Pagerduty#trigger)
|
135
|
-
# @option (see Pagerduty#trigger)
|
136
|
-
def trigger(description, options = {})
|
137
|
-
super(description, { incident_key: incident_key }.merge(options))
|
138
|
-
end
|
139
|
-
|
140
|
-
# Acknowledge the referenced incident. While an incident is acknowledged, it
|
141
|
-
# won't generate any additional notifications, even if it receives new
|
142
|
-
# trigger events. Send PagerDuty an acknowledge event when you know someone
|
143
|
-
# is presently working on the problem.
|
144
|
-
#
|
145
|
-
# @param [String] description Text that will appear in the incident's log
|
146
|
-
# associated with this event.
|
147
|
-
#
|
148
|
-
# @param [Hash] details An arbitrary hash containing any data you'd like
|
149
|
-
# included in the incident log.
|
150
|
-
#
|
151
|
-
# @return [PagerdutyIncident] self
|
152
|
-
#
|
153
|
-
# @raise [PagerdutyException] If PagerDuty responds with a status that is not
|
154
|
-
# "success"
|
155
|
-
#
|
156
|
-
def acknowledge(description = nil, details = nil)
|
157
|
-
modify_incident("acknowledge", description, details)
|
158
|
-
end
|
159
|
-
|
160
|
-
# Resolve the referenced incident. Once an incident is resolved, it won't
|
161
|
-
# generate any additional notifications. New trigger events with the same
|
162
|
-
# incident_key as a resolved incident won't re-open the incident. Instead, a
|
163
|
-
# new incident will be created. Send PagerDuty a resolve event when the
|
164
|
-
# problem that caused the initial trigger event has been fixed.
|
165
|
-
#
|
166
|
-
# @param [String] description Text that will appear in the incident's log
|
167
|
-
# associated with this event.
|
168
|
-
#
|
169
|
-
# @param [Hash] details An arbitrary hash containing any data you'd like
|
170
|
-
# included in the incident log.
|
171
|
-
#
|
172
|
-
# @return [PagerdutyIncident] self
|
173
|
-
#
|
174
|
-
# @raise [PagerdutyException] If PagerDuty responds with a status that is not
|
175
|
-
# "success"
|
176
|
-
#
|
177
|
-
def resolve(description = nil, details = nil)
|
178
|
-
modify_incident("resolve", description, details)
|
73
|
+
version = config.fetch(:api_version) do
|
74
|
+
raise ArgumentError, "api_version not provided"
|
75
|
+
end
|
76
|
+
events_api_class(version).new(config)
|
179
77
|
end
|
180
78
|
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
ensure_success(resp)
|
189
|
-
self
|
79
|
+
def self.events_api_class(version)
|
80
|
+
class_name = "Pagerduty::EventsApiV#{version}"
|
81
|
+
if const_defined?(class_name)
|
82
|
+
const_get(class_name)
|
83
|
+
else
|
84
|
+
raise ArgumentError, "api_version #{version.inspect} not supported"
|
85
|
+
end
|
190
86
|
end
|
87
|
+
private_class_method :events_api_class
|
191
88
|
end
|
@@ -0,0 +1,279 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Pagerduty
|
4
|
+
# Trigger incidents via the PagerDuty Events API version 1.
|
5
|
+
#
|
6
|
+
# @see https://v2.developer.pagerduty.com/docs/events-api PagerDuty Events
|
7
|
+
# API V1 documentation
|
8
|
+
#
|
9
|
+
# @see Pagerduty.build
|
10
|
+
#
|
11
|
+
# @see Pagerduty::EventsApiV1::Incident
|
12
|
+
#
|
13
|
+
class EventsApiV1
|
14
|
+
# Rather than using this directly, use the {Pagerduty.build} method to
|
15
|
+
# construct an instance.
|
16
|
+
#
|
17
|
+
# @option config [String] integration_key Authentication key for connecting
|
18
|
+
# to PagerDuty. A UUID expressed as a 32-digit hexadecimal number.
|
19
|
+
# Integration keys are generated by creating a new service, or creating a
|
20
|
+
# new integration for an existing service in PagerDuty, and can be found
|
21
|
+
# on a service's Integrations tab. This option is required.
|
22
|
+
#
|
23
|
+
# @option config [String] http_proxy.host The DNS name or IP address of the
|
24
|
+
# proxy host. If nil or unprovided an HTTP proxy will not be used.
|
25
|
+
#
|
26
|
+
# @option config [String] http_proxy.port The TCP port to use to access the
|
27
|
+
# proxy.
|
28
|
+
#
|
29
|
+
# @option config [String] http_proxy.username username if authorization is
|
30
|
+
# required to use the proxy.
|
31
|
+
#
|
32
|
+
# @option config [String] http_proxy.password password if authorization is
|
33
|
+
# required to use the proxy.
|
34
|
+
#
|
35
|
+
# @see Pagerduty.build
|
36
|
+
#
|
37
|
+
def initialize(config)
|
38
|
+
@config = config
|
39
|
+
end
|
40
|
+
|
41
|
+
# Send PagerDuty a trigger event to report a new or ongoing problem.
|
42
|
+
#
|
43
|
+
# @example Trigger an incident
|
44
|
+
# incident = pagerduty.trigger(
|
45
|
+
# "<A description of the event or outage>"
|
46
|
+
# )
|
47
|
+
#
|
48
|
+
# @example Trigger an incident, providing more context and details
|
49
|
+
# incident = pagerduty.trigger(
|
50
|
+
# "FAILURE for production/HTTP on machine srv01.acme.com",
|
51
|
+
# client: "Sample Monitoring Service",
|
52
|
+
# client_url: "https://monitoring.service.com",
|
53
|
+
# contexts: [
|
54
|
+
# {
|
55
|
+
# type: "link",
|
56
|
+
# href: "http://acme.pagerduty.com",
|
57
|
+
# text: "View the incident on PagerDuty",
|
58
|
+
# },
|
59
|
+
# {
|
60
|
+
# type: "image",
|
61
|
+
# src: "https://chart.googleapis.com/chart.png",
|
62
|
+
# }
|
63
|
+
# ],
|
64
|
+
# details: {
|
65
|
+
# ping_time: "1500ms",
|
66
|
+
# load_avg: 0.75,
|
67
|
+
# },
|
68
|
+
# )
|
69
|
+
#
|
70
|
+
# @param [String] description A short description of the problem that led to
|
71
|
+
# this trigger. This field (or a truncated version) will be used when
|
72
|
+
# generating phone calls, SMS messages and alert emails. It will also
|
73
|
+
# appear on the incidents tables in the PagerDuty UI. The maximum length
|
74
|
+
# is 1024 characters.
|
75
|
+
#
|
76
|
+
# @option options [String] client The name of the monitoring client that is
|
77
|
+
# triggering this event.
|
78
|
+
#
|
79
|
+
# @option options [String] client_url The URL of the monitoring client that
|
80
|
+
# is triggering this event.
|
81
|
+
#
|
82
|
+
# @option options [Array] contexts An array of objects. Contexts to be
|
83
|
+
# included with the incident trigger such as links to graphs or images.
|
84
|
+
#
|
85
|
+
# @option options [Hash] details An arbitrary hash containing any data you'd
|
86
|
+
# like included in the incident log.
|
87
|
+
#
|
88
|
+
# @return [Pagerduty::EventsApiV1::Incident] The triggered incident.
|
89
|
+
#
|
90
|
+
# @raise [PagerdutyException] If PagerDuty responds with a status that is
|
91
|
+
# not "success"
|
92
|
+
#
|
93
|
+
def trigger(description, options = {})
|
94
|
+
config = @config.merge(incident_key: options[:incident_key])
|
95
|
+
options = options.reject { |key| key == :incident_key }
|
96
|
+
Incident.new(config).trigger(description, options)
|
97
|
+
end
|
98
|
+
|
99
|
+
# @param [String] incident_key Identifies the incident to which
|
100
|
+
# this trigger event should be applied. If there's no open (i.e.
|
101
|
+
# unresolved) incident with this key, a new one will be created. If
|
102
|
+
# there's already an open incident with a matching key, this event will be
|
103
|
+
# appended to that incident's log. The event key provides an easy way to
|
104
|
+
# "de-dup" problem reports. If this field isn't provided, PagerDuty will
|
105
|
+
# automatically open a new incident with a unique key. The maximum length
|
106
|
+
# is 255 characters.
|
107
|
+
#
|
108
|
+
# @return [Pagerduty::EventsApiV1::Incident] The incident referenced by the
|
109
|
+
# key.
|
110
|
+
#
|
111
|
+
# @raise [ArgumentError] If incident_key is nil
|
112
|
+
#
|
113
|
+
def incident(incident_key)
|
114
|
+
raise ArgumentError, "incident_key is nil" if incident_key.nil?
|
115
|
+
|
116
|
+
Incident.new(@config.merge(incident_key: incident_key))
|
117
|
+
end
|
118
|
+
|
119
|
+
class Incident
|
120
|
+
attr_reader :incident_key
|
121
|
+
|
122
|
+
# @option (see Pagerduty::EventsApiV1#initialize)
|
123
|
+
#
|
124
|
+
# @option config [String] incident_key Identifies the incident to which
|
125
|
+
# this trigger event should be applied. If there's no open
|
126
|
+
# (i.e. unresolved) incident with this key, a new one will be created.
|
127
|
+
# If there's already an open incident with a matching key, this event
|
128
|
+
# will be appended to that incident's log. The event key provides an
|
129
|
+
# easy way to "de-dup" problem reports. If this field isn't provided,
|
130
|
+
# PagerDuty will automatically open a new incident with a unique key.
|
131
|
+
# The maximum length is 255 characters.
|
132
|
+
#
|
133
|
+
def initialize(config)
|
134
|
+
@integration_key = config.fetch(:integration_key) do
|
135
|
+
raise ArgumentError "integration_key not provided"
|
136
|
+
end
|
137
|
+
@incident_key = config[:incident_key]
|
138
|
+
@transport = Pagerduty::HttpTransport.new(
|
139
|
+
path: "/generic/2010-04-15/create_event.json",
|
140
|
+
proxy: config[:http_proxy],
|
141
|
+
)
|
142
|
+
end
|
143
|
+
|
144
|
+
# Send PagerDuty a trigger event to report a new or ongoing problem. When
|
145
|
+
# PagerDuty receives a trigger event, it will either open a new incident,
|
146
|
+
# or add a new trigger log entry to an existing incident, depending on the
|
147
|
+
# provided incident_key.
|
148
|
+
#
|
149
|
+
# @example Trigger or update an incident
|
150
|
+
# incident.trigger(
|
151
|
+
# "<A description of the event or outage>"
|
152
|
+
# )
|
153
|
+
#
|
154
|
+
# @example Trigger or update an incident, providing more context
|
155
|
+
# incident.trigger(
|
156
|
+
# "FAILURE for production/HTTP on machine srv01.acme.com",
|
157
|
+
# client: "Sample Monitoring Service",
|
158
|
+
# client_url: "https://monitoring.service.com",
|
159
|
+
# contexts: [
|
160
|
+
# {
|
161
|
+
# type: "link",
|
162
|
+
# href: "http://acme.pagerduty.com",
|
163
|
+
# text: "View the incident on PagerDuty",
|
164
|
+
# },
|
165
|
+
# {
|
166
|
+
# type: "image",
|
167
|
+
# src: "https://chart.googleapis.com/chart.png",
|
168
|
+
# }
|
169
|
+
# ],
|
170
|
+
# details: {
|
171
|
+
# ping_time: "1500ms",
|
172
|
+
# load_avg: 0.75,
|
173
|
+
# },
|
174
|
+
# )
|
175
|
+
#
|
176
|
+
# @param (see Pagerduty::EventsApiV1#trigger)
|
177
|
+
# @option (see Pagerduty::EventsApiV1#trigger)
|
178
|
+
def trigger(description, options = {})
|
179
|
+
if options.key?(:incident_key)
|
180
|
+
raise ArgumentError, "incident_key provided"
|
181
|
+
end
|
182
|
+
|
183
|
+
options = options.merge(description: description)
|
184
|
+
options[:incident_key] = @incident_key unless @incident_key.nil?
|
185
|
+
response = api_call("trigger", options)
|
186
|
+
@incident_key = response["incident_key"]
|
187
|
+
self
|
188
|
+
end
|
189
|
+
|
190
|
+
# Acknowledge the referenced incident. While an incident is acknowledged,
|
191
|
+
# it won't generate any additional notifications, even if it receives new
|
192
|
+
# trigger events. Send PagerDuty an acknowledge event when you know
|
193
|
+
# someone is presently working on the problem.
|
194
|
+
#
|
195
|
+
# @example Acknowledge the incident
|
196
|
+
# incident.acknowledge
|
197
|
+
#
|
198
|
+
# @example Acknowledge, providing a description and extra details
|
199
|
+
# incident.acknowledge(
|
200
|
+
# "Engineers are investigating the incident",
|
201
|
+
# {
|
202
|
+
# ping_time: "1700ms",
|
203
|
+
# load_avg: 0.71,
|
204
|
+
# }
|
205
|
+
# )
|
206
|
+
#
|
207
|
+
# @param [String] description Text that will appear in the incident's log
|
208
|
+
# associated with this event.
|
209
|
+
#
|
210
|
+
# @param [Hash] details An arbitrary hash containing any data you'd like
|
211
|
+
# included in the incident log.
|
212
|
+
#
|
213
|
+
# @return [Pagerduty::EventsApiV1::Incident] self
|
214
|
+
#
|
215
|
+
# @raise [PagerdutyException] If PagerDuty responds with a status that is
|
216
|
+
# not "success"
|
217
|
+
#
|
218
|
+
def acknowledge(description = nil, details = nil)
|
219
|
+
modify_incident("acknowledge", description, details)
|
220
|
+
end
|
221
|
+
|
222
|
+
# Resolve the referenced incident. Once an incident is resolved, it won't
|
223
|
+
# generate any additional notifications. New trigger events with the same
|
224
|
+
# incident_key as a resolved incident won't re-open the incident. Instead,
|
225
|
+
# a new incident will be created. Send PagerDuty a resolve event when the
|
226
|
+
# problem that caused the initial trigger event has been fixed.
|
227
|
+
#
|
228
|
+
# @example Resolve the incident
|
229
|
+
# incident.resolve
|
230
|
+
#
|
231
|
+
# @example Resolve, providing a description and extra details
|
232
|
+
# incident.resolve(
|
233
|
+
# "A fix has been deployed and the service has recovered",
|
234
|
+
# {
|
235
|
+
# ping_time: "130ms",
|
236
|
+
# load_avg: 0.23,
|
237
|
+
# }
|
238
|
+
# )
|
239
|
+
#
|
240
|
+
# @param [String] description Text that will appear in the incident's log
|
241
|
+
# associated with this event.
|
242
|
+
#
|
243
|
+
# @param [Hash] details An arbitrary hash containing any data you'd like
|
244
|
+
# included in the incident log.
|
245
|
+
#
|
246
|
+
# @return [Pagerduty::EventsApiV1::Incident] self
|
247
|
+
#
|
248
|
+
# @raise [PagerdutyException] If PagerDuty responds with a status that is
|
249
|
+
# not "success"
|
250
|
+
#
|
251
|
+
def resolve(description = nil, details = nil)
|
252
|
+
modify_incident("resolve", description, details)
|
253
|
+
end
|
254
|
+
|
255
|
+
private
|
256
|
+
|
257
|
+
def modify_incident(event_type, description, details)
|
258
|
+
options = { incident_key: incident_key }
|
259
|
+
options[:description] = description if description
|
260
|
+
options[:details] = details if details
|
261
|
+
api_call(event_type, options)
|
262
|
+
self
|
263
|
+
end
|
264
|
+
|
265
|
+
def api_call(event_type, args)
|
266
|
+
args = args.merge(
|
267
|
+
service_key: @integration_key,
|
268
|
+
event_type: event_type,
|
269
|
+
)
|
270
|
+
response = @transport.send_payload(args)
|
271
|
+
unless response["status"] == "success"
|
272
|
+
raise PagerdutyException.new(self, response, response["message"])
|
273
|
+
end
|
274
|
+
|
275
|
+
response
|
276
|
+
end
|
277
|
+
end
|
278
|
+
end
|
279
|
+
end
|
@@ -0,0 +1,280 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "time"
|
4
|
+
|
5
|
+
module Pagerduty
|
6
|
+
# Trigger incidents via the PagerDuty Events API version 2.
|
7
|
+
#
|
8
|
+
# @see https://v2.developer.pagerduty.com/docs/events-api-v2 PagerDuty Events
|
9
|
+
# API V2 documentation
|
10
|
+
#
|
11
|
+
# @see Pagerduty.build
|
12
|
+
#
|
13
|
+
# @see Pagerduty::EventsApiV2::Incident
|
14
|
+
#
|
15
|
+
class EventsApiV2
|
16
|
+
# Rather than using this directly, use the {Pagerduty.build} method to
|
17
|
+
# construct an instance.
|
18
|
+
#
|
19
|
+
# @option config [String] integration_key Authentication key for connecting
|
20
|
+
# to PagerDuty. A UUID expressed as a 32-digit hexadecimal number.
|
21
|
+
# Integration keys are generated by creating a new service, or creating a
|
22
|
+
# new integration for an existing service in PagerDuty, and can be found
|
23
|
+
# on a service's Integrations tab. This option is required.
|
24
|
+
#
|
25
|
+
# @option config [String] http_proxy.host The DNS name or IP address of the
|
26
|
+
# proxy host. If nil or unprovided an HTTP proxy will not be used.
|
27
|
+
#
|
28
|
+
# @option config [String] http_proxy.port The TCP port to use to access the
|
29
|
+
# proxy.
|
30
|
+
#
|
31
|
+
# @option config [String] http_proxy.username username if authorization is
|
32
|
+
# required to use the proxy.
|
33
|
+
#
|
34
|
+
# @option config [String] http_proxy.password password if authorization is
|
35
|
+
# required to use the proxy.
|
36
|
+
#
|
37
|
+
# @see Pagerduty.build
|
38
|
+
#
|
39
|
+
def initialize(config = {})
|
40
|
+
@config = config
|
41
|
+
end
|
42
|
+
|
43
|
+
# Send PagerDuty a trigger event to report a new or ongoing problem. When
|
44
|
+
# PagerDuty receives a trigger event, it will either open a new incident, or
|
45
|
+
# add a new trigger log entry to an existing incident, depending on the
|
46
|
+
# incident key.
|
47
|
+
#
|
48
|
+
# @example Trigger an incident, providing only required details
|
49
|
+
# incident = pagerduty.trigger(
|
50
|
+
# summary: "summary",
|
51
|
+
# source: "source",
|
52
|
+
# severity: "critical"
|
53
|
+
# )
|
54
|
+
#
|
55
|
+
# @example Trigger an incident providing full context
|
56
|
+
# incident = pagerduty.trigger(
|
57
|
+
# summary: "Example alert on host1.example.com",
|
58
|
+
# source: "monitoringtool:host1.example.com/prod-003",
|
59
|
+
# severity: %w[critical error warning info].sample,
|
60
|
+
# timestamp: Time.now,
|
61
|
+
# component: "postgres",
|
62
|
+
# group: "prod-datapipe",
|
63
|
+
# class: "deploy",
|
64
|
+
# custom_details: {
|
65
|
+
# ping_time: "1500ms",
|
66
|
+
# load_avg: 0.75
|
67
|
+
# },
|
68
|
+
# images: [
|
69
|
+
# {
|
70
|
+
# src: "https://chart.googleapis.com/chart.png",
|
71
|
+
# href: "https://example.com/",
|
72
|
+
# alt: "Example text",
|
73
|
+
# },
|
74
|
+
# ],
|
75
|
+
# links: [
|
76
|
+
# {
|
77
|
+
# href: "https://example.com/",
|
78
|
+
# text: "Link text",
|
79
|
+
# },
|
80
|
+
# ],
|
81
|
+
# client: "Sample Monitoring Service",
|
82
|
+
# client_url: "https://monitoring.example.com"
|
83
|
+
# )
|
84
|
+
#
|
85
|
+
# @option details [String] summary A brief text summary of the event,
|
86
|
+
# used to generate the summaries/titles of any associated alerts.
|
87
|
+
# The maximum permitted length of this property is 1024 characters.
|
88
|
+
#
|
89
|
+
# @option details [String] source The unique location of the affected
|
90
|
+
# system, preferably a hostname or FQDN.
|
91
|
+
#
|
92
|
+
# @option details [String] severity The perceived severity of the status
|
93
|
+
# the event is describing with respect to the affected system. This can
|
94
|
+
# be "critical", "error", "warning" or "info".
|
95
|
+
#
|
96
|
+
# @option details [Time] timestamp The time at which the emitting tool
|
97
|
+
# detected or generated the event.
|
98
|
+
#
|
99
|
+
# @option details [String] component Component of the source machine
|
100
|
+
# that is responsible for the event, for example "mysql" or "eth0".
|
101
|
+
#
|
102
|
+
# @option details [String] group Logical grouping of components of a
|
103
|
+
# service, for example "app-stack".
|
104
|
+
#
|
105
|
+
# @option details [String] class The class/type of the event, for
|
106
|
+
# example "ping failure" or "cpu load".
|
107
|
+
#
|
108
|
+
# @option details [Hash] custom_details Additional details about the
|
109
|
+
# event and affected system
|
110
|
+
#
|
111
|
+
# @option details [Array] images List of images to include.
|
112
|
+
#
|
113
|
+
# @option details [Array] links List of links to include.
|
114
|
+
#
|
115
|
+
# @return [Pagerduty::EventsApiV2::Incident] The triggered incident.
|
116
|
+
#
|
117
|
+
# @raise [PagerdutyException] If PagerDuty responds with a status that is
|
118
|
+
# not "success"
|
119
|
+
#
|
120
|
+
# @raise [ArgumentError] If details hash is nil
|
121
|
+
#
|
122
|
+
def trigger(details)
|
123
|
+
Incident.new(@config).trigger(details)
|
124
|
+
end
|
125
|
+
|
126
|
+
# @param [String] incident_key The unique identifier for the incident.
|
127
|
+
#
|
128
|
+
# @return [Pagerduty::EventsApiV2::Incident] The incident referenced by the
|
129
|
+
# provided key.
|
130
|
+
#
|
131
|
+
# @raise [ArgumentError] If incident_key is nil
|
132
|
+
#
|
133
|
+
def incident(incident_key)
|
134
|
+
raise ArgumentError, "incident_key is nil" if incident_key.nil?
|
135
|
+
|
136
|
+
Incident.new(@config.merge(incident_key: incident_key))
|
137
|
+
end
|
138
|
+
|
139
|
+
class Incident
|
140
|
+
attr_reader :incident_key
|
141
|
+
|
142
|
+
# @option (see Pagerduty::EventsApiV1#initialize)
|
143
|
+
#
|
144
|
+
# @option config [String] incident_key Identifies the incident to which
|
145
|
+
# this trigger event should be applied. If there's no open
|
146
|
+
# (i.e. unresolved) incident with this key, a new one will be created.
|
147
|
+
# If there's already an open incident with a matching key, this event
|
148
|
+
# will be appended to that incident's log. The event key provides an
|
149
|
+
# easy way to "de-dup" problem reports. If this field isn't provided,
|
150
|
+
# PagerDuty will automatically open a new incident with a unique key.
|
151
|
+
# The maximum length is 255 characters.
|
152
|
+
#
|
153
|
+
def initialize(config = {})
|
154
|
+
@integration_key = config.fetch(:integration_key) do
|
155
|
+
raise ArgumentError "integration_key not provided"
|
156
|
+
end
|
157
|
+
@incident_key = config[:incident_key]
|
158
|
+
@transport = Pagerduty::HttpTransport.new(
|
159
|
+
path: "/v2/enqueue",
|
160
|
+
proxy: config[:http_proxy],
|
161
|
+
)
|
162
|
+
end
|
163
|
+
|
164
|
+
# Send PagerDuty a trigger event to report a new or ongoing problem. When
|
165
|
+
# PagerDuty receives a trigger event, it will either open a new incident,
|
166
|
+
# or add a new trigger log entry to an existing incident, depending on
|
167
|
+
# the incident key.
|
168
|
+
#
|
169
|
+
# @example Trigger an incident, providing only required details
|
170
|
+
# incident = pagerduty.trigger(
|
171
|
+
# summary: "summary",
|
172
|
+
# source: "source",
|
173
|
+
# severity: "critical"
|
174
|
+
# )
|
175
|
+
#
|
176
|
+
# @example Trigger an incident providing full context
|
177
|
+
# incident = pagerduty.trigger(
|
178
|
+
# summary: "Example alert on host1.example.com",
|
179
|
+
# source: "monitoringtool:host1.example.com/prod-003",
|
180
|
+
# severity: %w[critical error warning info].sample,
|
181
|
+
# timestamp: Time.now,
|
182
|
+
# component: "postgres",
|
183
|
+
# group: "prod-datapipe",
|
184
|
+
# class: "deploy",
|
185
|
+
# custom_details: {
|
186
|
+
# ping_time: "1500ms",
|
187
|
+
# load_avg: 0.75
|
188
|
+
# },
|
189
|
+
# images: [
|
190
|
+
# {
|
191
|
+
# src: "https://chart.googleapis.com/chart.png",
|
192
|
+
# href: "https://example.com/",
|
193
|
+
# alt: "Example text",
|
194
|
+
# },
|
195
|
+
# ],
|
196
|
+
# links: [
|
197
|
+
# {
|
198
|
+
# href: "https://example.com/",
|
199
|
+
# text: "Link text",
|
200
|
+
# },
|
201
|
+
# ],
|
202
|
+
# client: "Sample Monitoring Service",
|
203
|
+
# client_url: "https://monitoring.example.com"
|
204
|
+
# )
|
205
|
+
#
|
206
|
+
# @param (see Pagerduty::EventsApiV2#trigger)
|
207
|
+
# @option (see Pagerduty::EventsApiV2#trigger)
|
208
|
+
def trigger(details)
|
209
|
+
if details.key?(:dedup_key) || details.key?(:incident_key)
|
210
|
+
raise ArgumentError, "incident_key or dedup_key provided, "\
|
211
|
+
"please use the EventsApiv2::incident method "\
|
212
|
+
"to specify an incident key"
|
213
|
+
end
|
214
|
+
|
215
|
+
response = api_call("trigger", trigger_request(details))
|
216
|
+
@incident_key = response["dedup_key"]
|
217
|
+
self
|
218
|
+
end
|
219
|
+
|
220
|
+
# Acknowledge the referenced incident. While an incident is acknowledged,
|
221
|
+
# it won't generate any additional notifications, even if it receives new
|
222
|
+
# trigger events. Send PagerDuty an acknowledge event when you know
|
223
|
+
# someone is presently working on the problem.
|
224
|
+
#
|
225
|
+
# @return [Pagerduty::EventsApiV2::Incident] self
|
226
|
+
#
|
227
|
+
# @raise [PagerdutyException] If PagerDuty responds with a status that is
|
228
|
+
# not "success"
|
229
|
+
#
|
230
|
+
def acknowledge
|
231
|
+
api_call("acknowledge")
|
232
|
+
self
|
233
|
+
end
|
234
|
+
|
235
|
+
# Resolve the referenced incident. Once an incident is resolved, it won't
|
236
|
+
# generate any additional notifications. New trigger events with the same
|
237
|
+
# incident_key as a resolved incident won't re-open the incident. Instead,
|
238
|
+
# a new incident will be created. Send PagerDuty a resolve event when the
|
239
|
+
# problem that caused the initial trigger event has been fixed.
|
240
|
+
#
|
241
|
+
# @return [Pagerduty::EventsApiV2::Incident] self
|
242
|
+
#
|
243
|
+
# @raise [PagerdutyException] If PagerDuty responds with a status that is
|
244
|
+
# not "success"
|
245
|
+
#
|
246
|
+
def resolve
|
247
|
+
api_call("resolve")
|
248
|
+
self
|
249
|
+
end
|
250
|
+
|
251
|
+
private
|
252
|
+
|
253
|
+
PAYLOAD_ATTR = %i[summary timestamp source severity
|
254
|
+
component group class custom_details].freeze
|
255
|
+
private_constant :PAYLOAD_ATTR
|
256
|
+
|
257
|
+
def trigger_request(details)
|
258
|
+
payload = details.select { |key| PAYLOAD_ATTR.include?(key) }
|
259
|
+
payload[:timestamp] &&= payload[:timestamp].iso8601
|
260
|
+
request = details.merge(payload: payload)
|
261
|
+
request.reject! { |key| PAYLOAD_ATTR.include?(key) }
|
262
|
+
request
|
263
|
+
end
|
264
|
+
|
265
|
+
def api_call(event_action, payload = {})
|
266
|
+
payload = payload.merge(
|
267
|
+
dedup_key: incident_key,
|
268
|
+
routing_key: @integration_key,
|
269
|
+
event_action: event_action,
|
270
|
+
)
|
271
|
+
response = @transport.send_payload(payload)
|
272
|
+
unless response["status"] == "success"
|
273
|
+
raise PagerdutyException.new(self, response, response["message"])
|
274
|
+
end
|
275
|
+
|
276
|
+
response
|
277
|
+
end
|
278
|
+
end
|
279
|
+
end
|
280
|
+
end
|
@@ -3,19 +3,20 @@
|
|
3
3
|
require "json"
|
4
4
|
require "net/https"
|
5
5
|
|
6
|
-
|
7
|
-
# @
|
6
|
+
module Pagerduty
|
7
|
+
# @private
|
8
8
|
class HttpTransport
|
9
9
|
HOST = "events.pagerduty.com"
|
10
10
|
PORT = 443
|
11
|
-
|
11
|
+
private_constant :HOST, :PORT
|
12
12
|
|
13
|
-
def initialize(
|
14
|
-
@
|
13
|
+
def initialize(config)
|
14
|
+
@path = config.fetch(:path)
|
15
|
+
@proxy = config[:proxy] || {}
|
15
16
|
end
|
16
17
|
|
17
|
-
def send_payload(payload
|
18
|
-
response = post
|
18
|
+
def send_payload(payload)
|
19
|
+
response = post(payload.to_json)
|
19
20
|
response.error! unless transported?(response)
|
20
21
|
JSON.parse(response.body)
|
21
22
|
end
|
@@ -23,7 +24,7 @@ class Pagerduty
|
|
23
24
|
private
|
24
25
|
|
25
26
|
def post(payload)
|
26
|
-
post = Net::HTTP::Post.new(
|
27
|
+
post = Net::HTTP::Post.new(@path)
|
27
28
|
post.body = payload
|
28
29
|
http.request(post)
|
29
30
|
end
|
@@ -39,10 +40,10 @@ class Pagerduty
|
|
39
40
|
|
40
41
|
def http_proxy
|
41
42
|
Net::HTTP.Proxy(
|
42
|
-
@
|
43
|
-
@
|
44
|
-
@
|
45
|
-
@
|
43
|
+
@proxy[:host],
|
44
|
+
@proxy[:port],
|
45
|
+
@proxy[:username],
|
46
|
+
@proxy[:password],
|
46
47
|
)
|
47
48
|
end
|
48
49
|
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# This file contains patches to provide backwards compatibility with version 2
|
4
|
+
# of the pagerduty gem. On the release of the next major version (4.0) it will
|
5
|
+
# be deleted, thus breaking backwards compatibility.
|
6
|
+
|
7
|
+
PagerdutyIncident = Pagerduty::EventsApiV1::Incident
|
8
|
+
|
9
|
+
Pagerduty::EventsApiV1::Incident.class_eval do
|
10
|
+
def service_key
|
11
|
+
@integration_key
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
Pagerduty::EventsApiV1.class_eval do
|
16
|
+
alias_method :get_incident, :incident
|
17
|
+
|
18
|
+
def service_key
|
19
|
+
@config[:integration_key]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
Pagerduty.class_eval do
|
24
|
+
def self.new(service_key, options = {})
|
25
|
+
build(
|
26
|
+
integration_key: service_key,
|
27
|
+
api_version: 1,
|
28
|
+
http_proxy: {
|
29
|
+
host: options[:proxy_host],
|
30
|
+
port: options[:proxy_port],
|
31
|
+
username: options[:proxy_username],
|
32
|
+
password: options[:proxy_password],
|
33
|
+
},
|
34
|
+
)
|
35
|
+
end
|
36
|
+
end
|
data/lib/pagerduty/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pagerduty
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Charlie Somerville
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2020-
|
12
|
+
date: 2020-04-20 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: json
|
@@ -94,16 +94,19 @@ files:
|
|
94
94
|
- LICENSE.txt
|
95
95
|
- README.md
|
96
96
|
- lib/pagerduty.rb
|
97
|
+
- lib/pagerduty/events_api_v1.rb
|
98
|
+
- lib/pagerduty/events_api_v2.rb
|
97
99
|
- lib/pagerduty/http_transport.rb
|
100
|
+
- lib/pagerduty/legacy.rb
|
98
101
|
- lib/pagerduty/version.rb
|
99
102
|
homepage: http://github.com/envato/pagerduty
|
100
103
|
licenses:
|
101
104
|
- MIT
|
102
105
|
metadata:
|
103
106
|
bug_tracker_uri: https://github.com/envato/pagerduty/issues
|
104
|
-
changelog_uri: https://github.com/envato/pagerduty/blob/
|
105
|
-
documentation_uri: https://www.rubydoc.info/gems/pagerduty/
|
106
|
-
source_code_uri: https://github.com/envato/pagerduty/tree/
|
107
|
+
changelog_uri: https://github.com/envato/pagerduty/blob/v3.0.0/CHANGELOG.md
|
108
|
+
documentation_uri: https://www.rubydoc.info/gems/pagerduty/3.0.0
|
109
|
+
source_code_uri: https://github.com/envato/pagerduty/tree/v3.0.0
|
107
110
|
post_install_message:
|
108
111
|
rdoc_options: []
|
109
112
|
require_paths:
|