pagerduty 2.1.3 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
[](https://github.com/envato/pagerduty/blob/master/LICENSE.txt)
|
5
4
|
[](https://rubygems.org/gems/pagerduty)
|
6
5
|
[](https://rubygems.org/gems/pagerduty)
|
7
6
|
[](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:
|