summaryrefslogtreecommitdiff
path: root/monitoring/pagerduty_alert.py
blob: f011b902703f0906d6ed9e1a246892b6ae78774c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
#!/usr/bin/python
# -*- coding: utf-8 -*-
#
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible.  If not, see <http://www.gnu.org/licenses/>.

ANSIBLE_METADATA = {'status': ['preview'],
                    'supported_by': 'community',
                    'version': '1.0'}

DOCUMENTATION = '''

module: pagerduty_alert
short_description: Trigger, acknowledge or resolve PagerDuty incidents
description:
    - This module will let you trigger, acknowledge or resolve a PagerDuty incident by sending events
version_added: "1.9"
author:
    - "Amanpreet Singh (@aps-sids)"
requirements:
    - PagerDuty API access
options:
    name:
        description:
            - PagerDuty unique subdomain.
        required: true
    service_key:
        description:
            - The GUID of one of your "Generic API" services.
            - This is the "service key" listed on a Generic API's service detail page.
        required: true
    state:
        description:
            - Type of event to be sent.
        required: true
        choices:
            - 'triggered'
            - 'acknowledged'
            - 'resolved'
    api_key:
        description:
            - The pagerduty API key (readonly access), generated on the pagerduty site.
        required: true
    desc:
        description:
            - For C(triggered) I(state) - Required. Short description of the problem that led to this trigger. This field (or a truncated version) will be used when generating phone calls, SMS messages and alert emails. It will also appear on the incidents tables in the PagerDuty UI. The maximum length is 1024 characters.
            - For C(acknowledged) or C(resolved) I(state) - Text that will appear in the incident's log associated with this event.
        required: false
        default: Created via Ansible
    incident_key:
        description:
            - Identifies the incident to which this I(state) should be applied.
            - For C(triggered) I(state) - If there's no open (i.e. unresolved) incident with this key, a new one will be created. If there's already an open incident with a matching key, this event will be appended to that incident's log. The event key provides an easy way to "de-dup" problem reports.
            - For C(acknowledged) or C(resolved) I(state) - This should be the incident_key you received back when the incident was first opened by a trigger event. Acknowledge events referencing resolved or nonexistent incidents will be discarded.
        required: false
    client:
        description:
        - The name of the monitoring client that is triggering this event.
        required: false
    client_url:
        description:
        -  The URL of the monitoring client that is triggering this event.
        required: false
'''

EXAMPLES = '''
# Trigger an incident with just the basic options
- pagerduty_alert:
        name: companyabc
        service_key=xxx
        api_key:yourapikey
        state=triggered
        desc="problem that led to this trigger"

# Trigger an incident with more options
- pagerduty_alert:
        service_key=xxx
        api_key=yourapikey
        state=triggered
        desc="problem that led to this trigger"
        incident_key=somekey
        client="Sample Monitoring Service"
        client_url=http://service.example.com

# Acknowledge an incident based on incident_key
- pagerduty_alert:
        service_key=xxx
        api_key=yourapikey
        state=acknowledged
        incident_key=somekey
        desc="some text for incident's log"

# Resolve an incident based on incident_key
- pagerduty_alert:
        service_key=xxx
        api_key=yourapikey
        state=resolved
        incident_key=somekey
        desc="some text for incident's log"
'''


def check(module, name, state, service_key, api_key, incident_key=None):
    url = "https://%s.pagerduty.com/api/v1/incidents" % name
    headers = {
        "Content-type": "application/json",
        "Authorization": "Token token=%s" % api_key
    }

    data = {
        "service_key": service_key,
        "incident_key": incident_key,
        "sort_by": "incident_number:desc"
    }

    response, info = fetch_url(module, url, method='get',
                               headers=headers, data=json.dumps(data))

    if info['status'] != 200:
        module.fail_json(msg="failed to check current incident status."
                             "Reason: %s" % info['msg'])
    json_out = json.loads(response.read())["incidents"][0]

    if state != json_out["status"]:
        return json_out, True
    return json_out, False


def send_event(module, service_key, event_type, desc,
               incident_key=None, client=None, client_url=None):
    url = "https://events.pagerduty.com/generic/2010-04-15/create_event.json"
    headers = {
        "Content-type": "application/json"
    }

    data = {
        "service_key": service_key,
        "event_type": event_type,
        "incident_key": incident_key,
        "description": desc,
        "client": client,
        "client_url": client_url
    }

    response, info = fetch_url(module, url, method='post',
                               headers=headers, data=json.dumps(data))
    if info['status'] != 200:
        module.fail_json(msg="failed to %s. Reason: %s" %
                         (event_type, info['msg']))
    json_out = json.loads(response.read())
    return json_out


def main():
    module = AnsibleModule(
        argument_spec=dict(
            name=dict(required=True),
            service_key=dict(required=True),
            api_key=dict(required=True),
            state=dict(required=True,
                       choices=['triggered', 'acknowledged', 'resolved']),
            client=dict(required=False, default=None),
            client_url=dict(required=False, default=None),
            desc=dict(required=False, default='Created via Ansible'),
            incident_key=dict(required=False, default=None)
        ),
        supports_check_mode=True
    )

    name = module.params['name']
    service_key = module.params['service_key']
    api_key = module.params['api_key']
    state = module.params['state']
    client = module.params['client']
    client_url = module.params['client_url']
    desc = module.params['desc']
    incident_key = module.params['incident_key']

    state_event_dict = {
            'triggered': 'trigger',
            'acknowledged': 'acknowledge',
            'resolved': 'resolve'
        }

    event_type = state_event_dict[state]

    if event_type != 'trigger' and incident_key is None:
        module.fail_json(msg="incident_key is required for "
                             "acknowledge or resolve events")

    out, changed = check(module, name, state,
                         service_key, api_key, incident_key)

    if not module.check_mode and changed is True:
        out = send_event(module, service_key, event_type, desc,
                         incident_key, client, client_url)

    module.exit_json(result=out, changed=changed)

# import module snippets
from ansible.module_utils.basic import *
from ansible.module_utils.urls import *

if __name__ == '__main__':
    main()