mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
Update pagerduty modules to rest v2 (#42618)
* refactored from procedural to OOP * updated ongoing maintenance windows to PagerDuty REST API v2 * update create maintenance windows to PagerDuty REST API v2 * update absent maintenance windows to PagerDuty REST API v2 * update pager alert module to PagerDuty REST API v2 * removed basic HTTP authorization updated parameter description and examples * fix failed sanity checks * revised documentation according to review * make obsolete service key parameter an alias to a new integration key parameter
This commit is contained in:
parent
122780abce
commit
dd28be3aab
4 changed files with 298 additions and 117 deletions
|
@ -35,31 +35,27 @@ options:
|
||||||
choices: [ "running", "started", "ongoing", "absent" ]
|
choices: [ "running", "started", "ongoing", "absent" ]
|
||||||
name:
|
name:
|
||||||
description:
|
description:
|
||||||
- PagerDuty unique subdomain.
|
- PagerDuty unique subdomain. Obsolete. It is not used with PagerDuty REST v2 API.
|
||||||
required: true
|
|
||||||
user:
|
user:
|
||||||
description:
|
description:
|
||||||
- PagerDuty user ID.
|
- PagerDuty user ID. Obsolete. Please, use I(token) for authorization.
|
||||||
required: true
|
|
||||||
passwd:
|
|
||||||
description:
|
|
||||||
- PagerDuty user password.
|
|
||||||
required: true
|
|
||||||
token:
|
token:
|
||||||
description:
|
description:
|
||||||
- A pagerduty token, generated on the pagerduty site. Can be used instead of
|
- A pagerduty token, generated on the pagerduty site. It is used for authorization.
|
||||||
user/passwd combination.
|
|
||||||
required: true
|
required: true
|
||||||
version_added: '1.8'
|
version_added: '1.8'
|
||||||
requester_id:
|
requester_id:
|
||||||
description:
|
description:
|
||||||
- ID of user making the request. Only needed when using a token and creating a maintenance_window.
|
- ID of user making the request. Only needed when creating a maintenance_window.
|
||||||
required: true
|
|
||||||
version_added: '1.8'
|
version_added: '1.8'
|
||||||
service:
|
service:
|
||||||
description:
|
description:
|
||||||
- A comma separated list of PagerDuty service IDs.
|
- A comma separated list of PagerDuty service IDs.
|
||||||
aliases: [ services ]
|
aliases: [ services ]
|
||||||
|
window_id:
|
||||||
|
description:
|
||||||
|
- ID of maintenance window. Only needed when absent a maintenance_window.
|
||||||
|
version_added: "2.7"
|
||||||
hours:
|
hours:
|
||||||
description:
|
description:
|
||||||
- Length of maintenance window in hours.
|
- Length of maintenance window in hours.
|
||||||
|
@ -83,28 +79,21 @@ options:
|
||||||
'''
|
'''
|
||||||
|
|
||||||
EXAMPLES = '''
|
EXAMPLES = '''
|
||||||
# List ongoing maintenance windows using a user/passwd
|
|
||||||
- pagerduty:
|
|
||||||
name: companyabc
|
|
||||||
user: example@example.com
|
|
||||||
passwd: password123
|
|
||||||
state: ongoing
|
|
||||||
|
|
||||||
# List ongoing maintenance windows using a token
|
# List ongoing maintenance windows using a token
|
||||||
- pagerduty:
|
- pagerduty:
|
||||||
name: companyabc
|
name: companyabc
|
||||||
token: xxxxxxxxxxxxxx
|
token: xxxxxxxxxxxxxx
|
||||||
state: ongoing
|
state: ongoing
|
||||||
|
|
||||||
# Create a 1 hour maintenance window for service FOO123, using a user/passwd
|
# Create a 1 hour maintenance window for service FOO123
|
||||||
- pagerduty:
|
- pagerduty:
|
||||||
name: companyabc
|
name: companyabc
|
||||||
user: example@example.com
|
user: example@example.com
|
||||||
passwd: password123
|
token: yourtoken
|
||||||
state: running
|
state: running
|
||||||
service: FOO123
|
service: FOO123
|
||||||
|
|
||||||
# Create a 5 minute maintenance window for service FOO123, using a token
|
# Create a 5 minute maintenance window for service FOO123
|
||||||
- pagerduty:
|
- pagerduty:
|
||||||
name: companyabc
|
name: companyabc
|
||||||
token: xxxxxxxxxxxxxx
|
token: xxxxxxxxxxxxxx
|
||||||
|
@ -118,7 +107,6 @@ EXAMPLES = '''
|
||||||
- pagerduty:
|
- pagerduty:
|
||||||
name: companyabc
|
name: companyabc
|
||||||
user: example@example.com
|
user: example@example.com
|
||||||
passwd: password123
|
|
||||||
state: running
|
state: running
|
||||||
service: FOO123
|
service: FOO123
|
||||||
hours: 4
|
hours: 4
|
||||||
|
@ -129,9 +117,8 @@ EXAMPLES = '''
|
||||||
- pagerduty:
|
- pagerduty:
|
||||||
name: companyabc
|
name: companyabc
|
||||||
user: example@example.com
|
user: example@example.com
|
||||||
passwd: password123
|
|
||||||
state: absent
|
state: absent
|
||||||
service: '{{ pd_window.result.maintenance_window.id }}'
|
window_id: '{{ pd_window.result.maintenance_window.id }}'
|
||||||
'''
|
'''
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
|
@ -143,87 +130,86 @@ from ansible.module_utils.urls import fetch_url
|
||||||
from ansible.module_utils._text import to_bytes
|
from ansible.module_utils._text import to_bytes
|
||||||
|
|
||||||
|
|
||||||
def auth_header(user, passwd, token):
|
class PagerDutyRequest(object):
|
||||||
if token:
|
def __init__(self, module, name, user, token):
|
||||||
return "Token token=%s" % token
|
self.module = module
|
||||||
|
self.name = name
|
||||||
|
self.user = user
|
||||||
|
self.token = token
|
||||||
|
self.headers = {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
"Authorization": self._auth_header(),
|
||||||
|
'Accept': 'application/vnd.pagerduty+json;version=2'
|
||||||
|
}
|
||||||
|
|
||||||
auth = base64.b64encode(to_bytes('%s:%s' % (user, passwd)).replace('\n', ''))
|
def ongoing(self, http_call=fetch_url):
|
||||||
return "Basic %s" % auth
|
url = "https://api.pagerduty.com/maintenance_windows?filter=ongoing"
|
||||||
|
headers = dict(self.headers)
|
||||||
|
|
||||||
|
response, info = http_call(self.module, url, headers=headers)
|
||||||
|
if info['status'] != 200:
|
||||||
|
self.module.fail_json(msg="failed to lookup the ongoing window: %s" % info['msg'])
|
||||||
|
|
||||||
def ongoing(module, name, user, passwd, token):
|
json_out = self._read_response(response)
|
||||||
url = "https://" + name + ".pagerduty.com/api/v1/maintenance_windows/ongoing"
|
|
||||||
headers = {"Authorization": auth_header(user, passwd, token)}
|
|
||||||
|
|
||||||
response, info = fetch_url(module, url, headers=headers)
|
return False, json_out, False
|
||||||
if info['status'] != 200:
|
|
||||||
module.fail_json(msg="failed to lookup the ongoing window: %s" % info['msg'])
|
|
||||||
|
|
||||||
try:
|
def create(self, requester_id, service, hours, minutes, desc, http_call=fetch_url):
|
||||||
json_out = json.loads(response.read())
|
if not requester_id:
|
||||||
except:
|
self.module.fail_json(msg="requester_id is required when maintenance window should be created")
|
||||||
json_out = ""
|
|
||||||
|
|
||||||
return False, json_out, False
|
url = 'https://api.pagerduty.com/maintenance_windows'
|
||||||
|
|
||||||
|
headers = dict(self.headers)
|
||||||
|
headers.update({'From': requester_id})
|
||||||
|
|
||||||
def create(module, name, user, passwd, token, requester_id, service, hours, minutes, desc):
|
start, end = self._compute_start_end_time(hours, minutes)
|
||||||
now = datetime.datetime.utcnow()
|
services = self._create_services_payload(service)
|
||||||
later = now + datetime.timedelta(hours=int(hours), minutes=int(minutes))
|
|
||||||
start = now.strftime("%Y-%m-%dT%H:%M:%SZ")
|
|
||||||
end = later.strftime("%Y-%m-%dT%H:%M:%SZ")
|
|
||||||
|
|
||||||
url = "https://" + name + ".pagerduty.com/api/v1/maintenance_windows"
|
request_data = {'maintenance_window': {'start_time': start, 'end_time': end, 'description': desc, 'services': services}}
|
||||||
headers = {
|
|
||||||
'Authorization': auth_header(user, passwd, token),
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
}
|
|
||||||
request_data = {'maintenance_window': {'start_time': start, 'end_time': end, 'description': desc, 'service_ids': service}}
|
|
||||||
|
|
||||||
if requester_id:
|
data = json.dumps(request_data)
|
||||||
request_data['requester_id'] = requester_id
|
response, info = http_call(self.module, url, data=data, headers=headers, method='POST')
|
||||||
else:
|
if info['status'] != 201:
|
||||||
if token:
|
self.module.fail_json(msg="failed to create the window: %s" % info['msg'])
|
||||||
module.fail_json(msg="requester_id is required when using a token")
|
|
||||||
|
|
||||||
data = json.dumps(request_data)
|
json_out = self._read_response(response)
|
||||||
response, info = fetch_url(module, url, data=data, headers=headers, method='POST')
|
|
||||||
if info['status'] != 201:
|
|
||||||
module.fail_json(msg="failed to create the window: %s" % info['msg'])
|
|
||||||
|
|
||||||
try:
|
return False, json_out, True
|
||||||
json_out = json.loads(response.read())
|
|
||||||
except:
|
|
||||||
json_out = ""
|
|
||||||
|
|
||||||
return False, json_out, True
|
def _create_services_payload(self, service):
|
||||||
|
if (isinstance(service, list)):
|
||||||
|
return [{'id': s, 'type': 'service_reference'} for s in service]
|
||||||
|
else:
|
||||||
|
return [{'id': service, 'type': 'service_reference'}]
|
||||||
|
|
||||||
|
def _compute_start_end_time(self, hours, minutes):
|
||||||
|
now = datetime.datetime.utcnow()
|
||||||
|
later = now + datetime.timedelta(hours=int(hours), minutes=int(minutes))
|
||||||
|
start = now.strftime("%Y-%m-%dT%H:%M:%SZ")
|
||||||
|
end = later.strftime("%Y-%m-%dT%H:%M:%SZ")
|
||||||
|
return start, end
|
||||||
|
|
||||||
def absent(module, name, user, passwd, token, requester_id, service):
|
def absent(self, window_id, http_call=fetch_url):
|
||||||
url = "https://" + name + ".pagerduty.com/api/v1/maintenance_windows/" + service[0]
|
url = "https://api.pagerduty.com/maintenance_windows/" + window_id
|
||||||
headers = {
|
headers = dict(self.headers)
|
||||||
'Authorization': auth_header(user, passwd, token),
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
}
|
|
||||||
request_data = {}
|
|
||||||
|
|
||||||
if requester_id:
|
response, info = http_call(self.module, url, headers=headers, method='DELETE')
|
||||||
request_data['requester_id'] = requester_id
|
if info['status'] != 204:
|
||||||
else:
|
self.module.fail_json(msg="failed to delete the window: %s" % info['msg'])
|
||||||
if token:
|
|
||||||
module.fail_json(msg="requester_id is required when using a token")
|
|
||||||
|
|
||||||
data = json.dumps(request_data)
|
json_out = self._read_response(response)
|
||||||
response, info = fetch_url(module, url, data=data, headers=headers, method='DELETE')
|
|
||||||
if info['status'] != 204:
|
|
||||||
module.fail_json(msg="failed to delete the window: %s" % info['msg'])
|
|
||||||
|
|
||||||
try:
|
return False, json_out, True
|
||||||
json_out = json.loads(response.read())
|
|
||||||
except:
|
|
||||||
json_out = ""
|
|
||||||
|
|
||||||
return False, json_out, True
|
def _auth_header(self):
|
||||||
|
return "Token token=%s" % self.token
|
||||||
|
|
||||||
|
def _read_response(self, response):
|
||||||
|
try:
|
||||||
|
return json.loads(response.read())
|
||||||
|
except:
|
||||||
|
return ""
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
@ -231,11 +217,11 @@ def main():
|
||||||
module = AnsibleModule(
|
module = AnsibleModule(
|
||||||
argument_spec=dict(
|
argument_spec=dict(
|
||||||
state=dict(required=True, choices=['running', 'started', 'ongoing', 'absent']),
|
state=dict(required=True, choices=['running', 'started', 'ongoing', 'absent']),
|
||||||
name=dict(required=True),
|
name=dict(required=False),
|
||||||
user=dict(required=False),
|
user=dict(required=False),
|
||||||
passwd=dict(required=False, no_log=True),
|
token=dict(required=True, no_log=True),
|
||||||
token=dict(required=False, no_log=True),
|
|
||||||
service=dict(required=False, type='list', aliases=["services"]),
|
service=dict(required=False, type='list', aliases=["services"]),
|
||||||
|
window_id=dict(required=False),
|
||||||
requester_id=dict(required=False),
|
requester_id=dict(required=False),
|
||||||
hours=dict(default='1', required=False),
|
hours=dict(default='1', required=False),
|
||||||
minutes=dict(default='0', required=False),
|
minutes=dict(default='0', required=False),
|
||||||
|
@ -247,30 +233,28 @@ def main():
|
||||||
state = module.params['state']
|
state = module.params['state']
|
||||||
name = module.params['name']
|
name = module.params['name']
|
||||||
user = module.params['user']
|
user = module.params['user']
|
||||||
passwd = module.params['passwd']
|
|
||||||
token = module.params['token']
|
|
||||||
service = module.params['service']
|
service = module.params['service']
|
||||||
|
window_id = module.params['window_id']
|
||||||
hours = module.params['hours']
|
hours = module.params['hours']
|
||||||
minutes = module.params['minutes']
|
minutes = module.params['minutes']
|
||||||
token = module.params['token']
|
token = module.params['token']
|
||||||
desc = module.params['desc']
|
desc = module.params['desc']
|
||||||
requester_id = module.params['requester_id']
|
requester_id = module.params['requester_id']
|
||||||
|
|
||||||
if not token and not (user or passwd):
|
pd = PagerDutyRequest(module, name, user, token)
|
||||||
module.fail_json(msg="neither user and passwd nor token specified")
|
|
||||||
|
|
||||||
if state == "running" or state == "started":
|
if state == "running" or state == "started":
|
||||||
if not service:
|
if not service:
|
||||||
module.fail_json(msg="service not specified")
|
module.fail_json(msg="service not specified")
|
||||||
(rc, out, changed) = create(module, name, user, passwd, token, requester_id, service, hours, minutes, desc)
|
(rc, out, changed) = pd.create(requester_id, service, hours, minutes, desc)
|
||||||
if rc == 0:
|
if rc == 0:
|
||||||
changed = True
|
changed = True
|
||||||
|
|
||||||
if state == "ongoing":
|
if state == "ongoing":
|
||||||
(rc, out, changed) = ongoing(module, name, user, passwd, token)
|
(rc, out, changed) = pd.ongoing()
|
||||||
|
|
||||||
if state == "absent":
|
if state == "absent":
|
||||||
(rc, out, changed) = absent(module, name, user, passwd, token, requester_id, service)
|
(rc, out, changed) = pd.absent(window_id)
|
||||||
|
|
||||||
if rc != 0:
|
if rc != 0:
|
||||||
module.fail_json(msg="failed", result=out)
|
module.fail_json(msg="failed", result=out)
|
||||||
|
|
|
@ -26,13 +26,21 @@ requirements:
|
||||||
options:
|
options:
|
||||||
name:
|
name:
|
||||||
description:
|
description:
|
||||||
- PagerDuty unique subdomain.
|
- PagerDuty unique subdomain. Obsolete. It is not used with PagerDuty REST v2 API.
|
||||||
|
service_id:
|
||||||
|
description:
|
||||||
|
- ID of PagerDuty service when incidents will be triggered, acknowledged or resolved.
|
||||||
required: true
|
required: true
|
||||||
|
version_added: "2.7"
|
||||||
service_key:
|
service_key:
|
||||||
|
description:
|
||||||
|
- The GUID of one of your "Generic API" services. Obsolete. Please use I(integration_key).
|
||||||
|
integration_key:
|
||||||
description:
|
description:
|
||||||
- The GUID of one of your "Generic API" services.
|
- The GUID of one of your "Generic API" services.
|
||||||
- This is the "service key" listed on a Generic API's service detail page.
|
- This is the "integration key" listed on a "Integrations" tab of PagerDuty service.
|
||||||
required: true
|
required: true
|
||||||
|
version_added: "2.7"
|
||||||
state:
|
state:
|
||||||
description:
|
description:
|
||||||
- Type of event to be sent.
|
- Type of event to be sent.
|
||||||
|
@ -62,6 +70,7 @@ options:
|
||||||
- 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
|
- 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.
|
trigger event. Acknowledge events referencing resolved or nonexistent incidents will be discarded.
|
||||||
required: false
|
required: false
|
||||||
|
version_added: "2.7"
|
||||||
client:
|
client:
|
||||||
description:
|
description:
|
||||||
- The name of the monitoring client that is triggering this event.
|
- The name of the monitoring client that is triggering this event.
|
||||||
|
@ -76,15 +85,17 @@ EXAMPLES = '''
|
||||||
# Trigger an incident with just the basic options
|
# Trigger an incident with just the basic options
|
||||||
- pagerduty_alert:
|
- pagerduty_alert:
|
||||||
name: companyabc
|
name: companyabc
|
||||||
service_key: xxx
|
integration_key: xxx
|
||||||
api_key: yourapikey
|
api_key: yourapikey
|
||||||
|
service_id: PDservice
|
||||||
state: triggered
|
state: triggered
|
||||||
desc: problem that led to this trigger
|
desc: problem that led to this trigger
|
||||||
|
|
||||||
# Trigger an incident with more options
|
# Trigger an incident with more options
|
||||||
- pagerduty_alert:
|
- pagerduty_alert:
|
||||||
service_key: xxx
|
integration_key: xxx
|
||||||
api_key: yourapikey
|
api_key: yourapikey
|
||||||
|
service_id: PDservice
|
||||||
state: triggered
|
state: triggered
|
||||||
desc: problem that led to this trigger
|
desc: problem that led to this trigger
|
||||||
incident_key: somekey
|
incident_key: somekey
|
||||||
|
@ -93,16 +104,18 @@ EXAMPLES = '''
|
||||||
|
|
||||||
# Acknowledge an incident based on incident_key
|
# Acknowledge an incident based on incident_key
|
||||||
- pagerduty_alert:
|
- pagerduty_alert:
|
||||||
service_key: xxx
|
integration_key: xxx
|
||||||
api_key: yourapikey
|
api_key: yourapikey
|
||||||
|
service_id: PDservice
|
||||||
state: acknowledged
|
state: acknowledged
|
||||||
incident_key: somekey
|
incident_key: somekey
|
||||||
desc: "some text for incident's log"
|
desc: "some text for incident's log"
|
||||||
|
|
||||||
# Resolve an incident based on incident_key
|
# Resolve an incident based on incident_key
|
||||||
- pagerduty_alert:
|
- pagerduty_alert:
|
||||||
service_key: xxx
|
integration_key: xxx
|
||||||
api_key: yourapikey
|
api_key: yourapikey
|
||||||
|
service_id: PDservice
|
||||||
state: resolved
|
state: resolved
|
||||||
incident_key: somekey
|
incident_key: somekey
|
||||||
desc: "some text for incident's log"
|
desc: "some text for incident's log"
|
||||||
|
@ -111,23 +124,31 @@ import json
|
||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible.module_utils.urls import fetch_url
|
from ansible.module_utils.urls import fetch_url
|
||||||
|
from ansible.module_utils.six.moves.urllib.parse import urlparse, urlencode, urlunparse
|
||||||
|
|
||||||
|
|
||||||
def check(module, name, state, service_key, api_key, incident_key=None):
|
def check(module, name, state, service_id, integration_key, api_key, incident_key=None, http_call=fetch_url):
|
||||||
url = "https://%s.pagerduty.com/api/v1/incidents" % name
|
url = 'https://api.pagerduty.com/incidents'
|
||||||
headers = {
|
headers = {
|
||||||
"Content-type": "application/json",
|
"Content-type": "application/json",
|
||||||
"Authorization": "Token token=%s" % api_key
|
"Authorization": "Token token=%s" % api_key,
|
||||||
|
'Accept': 'application/vnd.pagerduty+json;version=2'
|
||||||
}
|
}
|
||||||
|
|
||||||
data = {
|
params = {
|
||||||
"service_key": service_key,
|
'service_ids[]': service_id,
|
||||||
"incident_key": incident_key,
|
'sort_by': 'incident_number:desc',
|
||||||
"sort_by": "incident_number:desc"
|
'time_zone': 'UTC'
|
||||||
}
|
}
|
||||||
|
if incident_key:
|
||||||
|
params['incident_key'] = incident_key
|
||||||
|
|
||||||
response, info = fetch_url(module, url, method='get',
|
url_parts = list(urlparse(url))
|
||||||
headers=headers, data=json.dumps(data))
|
url_parts[4] = urlencode(params, True)
|
||||||
|
|
||||||
|
url = urlunparse(url_parts)
|
||||||
|
|
||||||
|
response, info = http_call(module, url, method='get', headers=headers)
|
||||||
|
|
||||||
if info['status'] != 200:
|
if info['status'] != 200:
|
||||||
module.fail_json(msg="failed to check current incident status."
|
module.fail_json(msg="failed to check current incident status."
|
||||||
|
@ -167,8 +188,10 @@ def send_event(module, service_key, event_type, desc,
|
||||||
def main():
|
def main():
|
||||||
module = AnsibleModule(
|
module = AnsibleModule(
|
||||||
argument_spec=dict(
|
argument_spec=dict(
|
||||||
name=dict(required=True),
|
name=dict(required=False),
|
||||||
service_key=dict(required=True),
|
service_id=dict(required=True),
|
||||||
|
service_key=dict(require=False),
|
||||||
|
integration_key=dict(require=False),
|
||||||
api_key=dict(required=True),
|
api_key=dict(required=True),
|
||||||
state=dict(required=True,
|
state=dict(required=True,
|
||||||
choices=['triggered', 'acknowledged', 'resolved']),
|
choices=['triggered', 'acknowledged', 'resolved']),
|
||||||
|
@ -181,6 +204,8 @@ def main():
|
||||||
)
|
)
|
||||||
|
|
||||||
name = module.params['name']
|
name = module.params['name']
|
||||||
|
service_id = module.params['service_id']
|
||||||
|
integration_key = module.params['integration_key']
|
||||||
service_key = module.params['service_key']
|
service_key = module.params['service_key']
|
||||||
api_key = module.params['api_key']
|
api_key = module.params['api_key']
|
||||||
state = module.params['state']
|
state = module.params['state']
|
||||||
|
@ -189,6 +214,14 @@ def main():
|
||||||
desc = module.params['desc']
|
desc = module.params['desc']
|
||||||
incident_key = module.params['incident_key']
|
incident_key = module.params['incident_key']
|
||||||
|
|
||||||
|
if integration_key is None:
|
||||||
|
if service_key is not None:
|
||||||
|
integration_key = service_key
|
||||||
|
module.warn('"service_key" is obsolete parameter and will be removed.'
|
||||||
|
' Please, use "integration_key" instead')
|
||||||
|
else:
|
||||||
|
module.fail_json(msg="'integration_key' is required parameter")
|
||||||
|
|
||||||
state_event_dict = {
|
state_event_dict = {
|
||||||
'triggered': 'trigger',
|
'triggered': 'trigger',
|
||||||
'acknowledged': 'acknowledge',
|
'acknowledged': 'acknowledge',
|
||||||
|
@ -201,11 +234,11 @@ def main():
|
||||||
module.fail_json(msg="incident_key is required for "
|
module.fail_json(msg="incident_key is required for "
|
||||||
"acknowledge or resolve events")
|
"acknowledge or resolve events")
|
||||||
|
|
||||||
out, changed = check(module, name, state,
|
out, changed = check(module, name, state, service_id,
|
||||||
service_key, api_key, incident_key)
|
integration_key, api_key, incident_key)
|
||||||
|
|
||||||
if not module.check_mode and changed is True:
|
if not module.check_mode and changed is True:
|
||||||
out = send_event(module, service_key, event_type, desc,
|
out = send_event(module, integration_key, event_type, desc,
|
||||||
incident_key, client, client_url)
|
incident_key, client, client_url)
|
||||||
|
|
||||||
module.exit_json(result=out, changed=changed)
|
module.exit_json(result=out, changed=changed)
|
||||||
|
|
123
test/units/modules/monitoring/test_pagerduty.py
Normal file
123
test/units/modules/monitoring/test_pagerduty.py
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
from ansible.compat.tests import unittest
|
||||||
|
from ansible.modules.monitoring import pagerduty
|
||||||
|
|
||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
|
class PagerDutyTest(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.pd = pagerduty.PagerDutyRequest(module=pagerduty, name='name', user='user', token='token')
|
||||||
|
|
||||||
|
def _assert_ongoing_maintenance_windows(self, module, url, headers):
|
||||||
|
self.assertEquals('https://api.pagerduty.com/maintenance_windows?filter=ongoing', url)
|
||||||
|
return object(), {'status': 200}
|
||||||
|
|
||||||
|
def _assert_ongoing_window_with_v1_compatible_header(self, module, url, headers, data=None, method=None):
|
||||||
|
self.assertDictContainsSubset(
|
||||||
|
{'Accept': 'application/vnd.pagerduty+json;version=2'},
|
||||||
|
headers,
|
||||||
|
'Accept:application/vnd.pagerduty+json;version=2 HTTP header not found'
|
||||||
|
)
|
||||||
|
return object(), {'status': 200}
|
||||||
|
|
||||||
|
def _assert_create_a_maintenance_window_url(self, module, url, headers, data=None, method=None):
|
||||||
|
self.assertEquals('https://api.pagerduty.com/maintenance_windows', url)
|
||||||
|
return object(), {'status': 201}
|
||||||
|
|
||||||
|
def _assert_create_a_maintenance_window_http_method(self, module, url, headers, data=None, method=None):
|
||||||
|
self.assertEquals('POST', method)
|
||||||
|
return object(), {'status': 201}
|
||||||
|
|
||||||
|
def _assert_create_a_maintenance_window_from_header(self, module, url, headers, data=None, method=None):
|
||||||
|
self.assertDictContainsSubset(
|
||||||
|
{'From': 'requester_id'},
|
||||||
|
headers,
|
||||||
|
'From:requester_id HTTP header not found'
|
||||||
|
)
|
||||||
|
return object(), {'status': 201}
|
||||||
|
|
||||||
|
def _assert_create_window_with_v1_compatible_header(self, module, url, headers, data=None, method=None):
|
||||||
|
self.assertDictContainsSubset(
|
||||||
|
{'Accept': 'application/vnd.pagerduty+json;version=2'},
|
||||||
|
headers,
|
||||||
|
'Accept:application/vnd.pagerduty+json;version=2 HTTP header not found'
|
||||||
|
)
|
||||||
|
return object(), {'status': 201}
|
||||||
|
|
||||||
|
def _assert_create_window_payload(self, module, url, headers, data=None, method=None):
|
||||||
|
payload = json.loads(data)
|
||||||
|
window_data = payload['maintenance_window']
|
||||||
|
self.assertTrue('start_time' in window_data, '"start_time" is requiered attribute')
|
||||||
|
self.assertTrue('end_time' in window_data, '"end_time" is requiered attribute')
|
||||||
|
self.assertTrue('services' in window_data, '"services" is requiered attribute')
|
||||||
|
return object(), {'status': 201}
|
||||||
|
|
||||||
|
def _assert_create_window_single_service(self, module, url, headers, data=None, method=None):
|
||||||
|
payload = json.loads(data)
|
||||||
|
window_data = payload['maintenance_window']
|
||||||
|
services = window_data['services']
|
||||||
|
self.assertEquals(
|
||||||
|
[{'id': 'service_id', 'type': 'service_reference'}],
|
||||||
|
services
|
||||||
|
)
|
||||||
|
return object(), {'status': 201}
|
||||||
|
|
||||||
|
def _assert_create_window_multiple_service(self, module, url, headers, data=None, method=None):
|
||||||
|
payload = json.loads(data)
|
||||||
|
window_data = payload['maintenance_window']
|
||||||
|
services = window_data['services']
|
||||||
|
print(services)
|
||||||
|
self.assertEquals(
|
||||||
|
[
|
||||||
|
{'id': 'service_id_1', 'type': 'service_reference'},
|
||||||
|
{'id': 'service_id_2', 'type': 'service_reference'},
|
||||||
|
{'id': 'service_id_3', 'type': 'service_reference'},
|
||||||
|
],
|
||||||
|
services
|
||||||
|
)
|
||||||
|
return object(), {'status': 201}
|
||||||
|
|
||||||
|
def _assert_absent_maintenance_window_url(self, module, url, headers, method=None):
|
||||||
|
self.assertEquals('https://api.pagerduty.com/maintenance_windows/window_id', url)
|
||||||
|
return object(), {'status': 204}
|
||||||
|
|
||||||
|
def _assert_absent_window_with_v1_compatible_header(self, module, url, headers, method=None):
|
||||||
|
self.assertDictContainsSubset(
|
||||||
|
{'Accept': 'application/vnd.pagerduty+json;version=2'},
|
||||||
|
headers,
|
||||||
|
'Accept:application/vnd.pagerduty+json;version=2 HTTP header not found'
|
||||||
|
)
|
||||||
|
return object(), {'status': 204}
|
||||||
|
|
||||||
|
def test_ongoing_maintenance_windos_url(self):
|
||||||
|
self.pd.ongoing(http_call=self._assert_ongoing_maintenance_windows)
|
||||||
|
|
||||||
|
def test_ongoing_maintenance_windos_compatibility_header(self):
|
||||||
|
self.pd.ongoing(http_call=self._assert_ongoing_window_with_v1_compatible_header)
|
||||||
|
|
||||||
|
def test_create_maintenance_window_url(self):
|
||||||
|
self.pd.create('requester_id', 'service', 1, 0, 'desc', http_call=self._assert_create_a_maintenance_window_url)
|
||||||
|
|
||||||
|
def test_create_maintenance_window_http_method(self):
|
||||||
|
self.pd.create('requester_id', 'service', 1, 0, 'desc', http_call=self._assert_create_a_maintenance_window_http_method)
|
||||||
|
|
||||||
|
def test_create_maintenance_from_header(self):
|
||||||
|
self.pd.create('requester_id', 'service', 1, 0, 'desc', http_call=self._assert_create_a_maintenance_window_from_header)
|
||||||
|
|
||||||
|
def test_create_maintenance_compatibility_header(self):
|
||||||
|
self.pd.create('requester_id', 'service', 1, 0, 'desc', http_call=self._assert_create_window_with_v1_compatible_header)
|
||||||
|
|
||||||
|
def test_create_maintenance_request_payload(self):
|
||||||
|
self.pd.create('requester_id', 'service', 1, 0, 'desc', http_call=self._assert_create_window_payload)
|
||||||
|
|
||||||
|
def test_create_maintenance_for_single_service(self):
|
||||||
|
self.pd.create('requester_id', 'service_id', 1, 0, 'desc', http_call=self._assert_create_window_single_service)
|
||||||
|
|
||||||
|
def test_create_maintenance_for_multiple_services(self):
|
||||||
|
self.pd.create('requester_id', ['service_id_1', 'service_id_2', 'service_id_3'], 1, 0, 'desc', http_call=self._assert_create_window_multiple_service)
|
||||||
|
|
||||||
|
def test_absent_maintenance_window_url(self):
|
||||||
|
self.pd.absent('window_id', http_call=self._assert_absent_maintenance_window_url)
|
||||||
|
|
||||||
|
def test_absent_maintenance_compatibility_header(self):
|
||||||
|
self.pd.absent('window_id', http_call=self._assert_absent_window_with_v1_compatible_header)
|
41
test/units/modules/monitoring/test_pagerduty_alert.py
Normal file
41
test/units/modules/monitoring/test_pagerduty_alert.py
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
from ansible.compat.tests import unittest
|
||||||
|
from ansible.modules.monitoring import pagerduty_alert
|
||||||
|
|
||||||
|
from ansible.module_utils.six.moves.urllib.parse import urlparse, urlencode, urlunparse
|
||||||
|
|
||||||
|
|
||||||
|
class PagerDutyAlertsTest(unittest.TestCase):
|
||||||
|
def _assert_incident_api(self, module, url, method, headers):
|
||||||
|
self.assertTrue('https://api.pagerduty.com/incidents' in url, 'url must contain REST API v2 network path')
|
||||||
|
self.assertTrue('service_ids%5B%5D=service_id' in url, 'url must contain service id to filter incidents')
|
||||||
|
self.assertTrue('sort_by=incident_number%3Adesc' in url, 'url should contain sorting parameter')
|
||||||
|
self.assertTrue('time_zone=UTC' in url, 'url should contain time zone parameter')
|
||||||
|
return Response(), {'status': 200}
|
||||||
|
|
||||||
|
def _assert_compatibility_header(self, module, url, method, headers):
|
||||||
|
self.assertDictContainsSubset(
|
||||||
|
{'Accept': 'application/vnd.pagerduty+json;version=2'},
|
||||||
|
headers,
|
||||||
|
'Accept:application/vnd.pagerduty+json;version=2 HTTP header not found'
|
||||||
|
)
|
||||||
|
return Response(), {'status': 200}
|
||||||
|
|
||||||
|
def _assert_incident_key(self, module, url, method, headers):
|
||||||
|
self.assertTrue('incident_key=incident_key_value' in url, 'url must contain incident key')
|
||||||
|
return Response(), {'status': 200}
|
||||||
|
|
||||||
|
def test_incident_url(self):
|
||||||
|
pagerduty_alert.check(None, 'name', 'state', 'service_id', 'integration_key', 'api_key', http_call=self._assert_incident_api)
|
||||||
|
|
||||||
|
def test_compatibility_header(self):
|
||||||
|
pagerduty_alert.check(None, 'name', 'state', 'service_id', 'integration_key', 'api_key', http_call=self._assert_compatibility_header)
|
||||||
|
|
||||||
|
def test_incident_key_in_url_when_it_is_given(self):
|
||||||
|
pagerduty_alert.check(
|
||||||
|
None, 'name', 'state', 'service_id', 'integration_key', 'api_key', incident_key='incident_key_value', http_call=self._assert_incident_key
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class Response(object):
|
||||||
|
def read(self):
|
||||||
|
return '{"incidents":[{"id": "incident_id", "status": "triggered"}]}'
|
Loading…
Reference in a new issue