From 7c3439963067b71d4fe31061f08e3186e9c83281 Mon Sep 17 00:00:00 2001
From: Andrew Newdigate <andrew@troupe.co>
Date: Wed, 5 Mar 2014 22:22:56 +0000
Subject: [PATCH 1/4] Added support for setting up maintenance windows of under
 an hour. Added support for using tokens instead of usernames and passwords.

---
 monitoring/pagerduty | 62 +++++++++++++++++++++++++++++++++-----------
 1 file changed, 47 insertions(+), 15 deletions(-)

diff --git a/monitoring/pagerduty b/monitoring/pagerduty
index bfd0573f4de..13e1597c986 100644
--- a/monitoring/pagerduty
+++ b/monitoring/pagerduty
@@ -39,6 +39,13 @@ options:
         default: null
         choices: []
         aliases: []
+    requester_id:
+        description:
+            - ID of user making the request. Only needed when using a token and creating a maintenance_window.
+        required: true
+        default: null
+        choices: []
+        aliases: []
     service:
         description:
             - PagerDuty service ID.
@@ -53,6 +60,13 @@ options:
         default: 1
         choices: []
         aliases: []
+    minutes:
+        description:
+            - Maintenance window in minutes (this is added to the hours).
+        required: false
+        default: 0
+        choices: []
+        aliases: []
     desc:
         description:
             - Short description of maintenance window.
@@ -90,34 +104,42 @@ import datetime
 import urllib2
 import base64
 
+def create_req(url, data, name, user, passwd, token):
+    req = urllib2.Request(url, data)
+    if token:
+        req.add_header("Authorization", "Token token=%s" % token)
+    else:
+        auth = base64.encodestring('%s:%s' % (user, passwd)).replace('\n', '')
+        req.add_header("Authorization", "Basic %s" % auth)
 
-def ongoing(name, user, passwd):
+    return req
 
+def ongoing(name, user, passwd, token):
     url = "https://" + name + ".pagerduty.com/api/v1/maintenance_windows/ongoing"
-    auth = base64.encodestring('%s:%s' % (user, passwd)).replace('\n', '')
-
-    req = urllib2.Request(url)
-    req.add_header("Authorization", "Basic %s" % auth)
+    req = create_req(url, None, name, user, passwd, token)
     res = urllib2.urlopen(req)
     out = res.read()
 
     return False, out
 
 
-def create(name, user, passwd, service, hours, desc):
+def create(name, user, passwd, token, requester_id, service, hours, minutes, desc):
 
     now = datetime.datetime.utcnow()
-    later = now + datetime.timedelta(hours=int(hours))
+    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"
-    auth = base64.encodestring('%s:%s' % (user, passwd)).replace('\n', '')
-    data = json.dumps({'maintenance_window': {'start_time': start, 'end_time': end, 'description': desc, 'service_ids': [service]}})
+    request_data = {'maintenance_window': {'start_time': start, 'end_time': end, 'description': desc, 'service_ids': [service]}}
+    if requester_id:
+        request_data['requester_id'] = requester_id
 
-    req = urllib2.Request(url, data)
-    req.add_header("Authorization", "Basic %s" % auth)
+    data = json.dumps(request_data)
+
+    req = create_req(url, data, name, user, passwd, token)
     req.add_header('Content-Type', 'application/json')
+
     res = urllib2.urlopen(req)
     out = res.read()
 
@@ -130,10 +152,13 @@ def main():
         argument_spec=dict(
         state=dict(required=True, choices=['running', 'started', 'ongoing']),
         name=dict(required=True),
-        user=dict(required=True),
-        passwd=dict(required=True),
+        user=dict(required=False),
+        passwd=dict(required=False),
+        token=dict(required=False),
         service=dict(required=False),
+        requester_id=dict(required=False),
         hours=dict(default='1', required=False),
+        minutes=dict(default='0', required=False),
         desc=dict(default='Created by Ansible', required=False)
         )
     )
@@ -142,17 +167,24 @@ def main():
     name = module.params['name']
     user = module.params['user']
     passwd = module.params['passwd']
+    token = module.params['token']
     service = module.params['service']
     hours = module.params['hours']
+    minutes = module.params['minutes']
+    token = module.params['token']
     desc = module.params['desc']
+    requester_id =  module.params['requester_id']
+
+    if not token and not (user or passwd):
+        module.fail_json(msg="neither user and passwd nor token specified")
 
     if state == "running" or state == "started":
         if not service:
             module.fail_json(msg="service not specified")
-        (rc, out) = create(name, user, passwd, service, hours, desc)
+        (rc, out) = create(name, user, passwd, token, requester_id, service, hours, minutes, desc)
 
     if state == "ongoing":
-        (rc, out) = ongoing(name, user, passwd)
+        (rc, out) = ongoing(name, user, passwd, token)
 
     if rc != 0:
         module.fail_json(msg="failed", result=out)

From cd1722b7436a1623cd2f48efc9205d22e9dd2ff0 Mon Sep 17 00:00:00 2001
From: Andrew Newdigate <andrew@troupe.co>
Date: Thu, 6 Mar 2014 09:18:38 +0000
Subject: [PATCH 2/4] Added 'version_added' attributes for new fields. Also
 added missing fields to documentation and added some more examples.

---
 monitoring/pagerduty | 27 +++++++++++++++++++++++++--
 1 file changed, 25 insertions(+), 2 deletions(-)

diff --git a/monitoring/pagerduty b/monitoring/pagerduty
index 13e1597c986..d2f630ae82a 100644
--- a/monitoring/pagerduty
+++ b/monitoring/pagerduty
@@ -39,6 +39,15 @@ options:
         default: null
         choices: []
         aliases: []
+    token:
+        description:
+            - A pagerduty token, generated on the pagerduty site. Can be used instead of
+              user/passwd combination.
+        required: true
+        default: null
+        choices: []
+        aliases: []
+        version_added: '1.6'
     requester_id:
         description:
             - ID of user making the request. Only needed when using a token and creating a maintenance_window.
@@ -46,6 +55,7 @@ options:
         default: null
         choices: []
         aliases: []
+        version_added: '1.6'
     service:
         description:
             - PagerDuty service ID.
@@ -67,6 +77,7 @@ options:
         default: 0
         choices: []
         aliases: []
+        version_added: '1.6'
     desc:
         description:
             - Short description of maintenance window.
@@ -79,16 +90,28 @@ notes:
 '''
 
 EXAMPLES='''
-# List ongoing maintenance windows.
+# List ongoing maintenance windows using a user/passwd
 - pagerduty: name=companyabc user=example@example.com passwd=password123 state=ongoing
 
-# Create a 1 hour maintenance window for service FOO123.
+# List ongoing maintenance windows using a token
+- pagerduty: name=companyabc token=xxxxxxxxxxxxxx state=ongoing
+
+# Create a 1 hour maintenance window for service FOO123, using a user/passwd
 - pagerduty: name=companyabc
              user=example@example.com
              passwd=password123
              state=running
              service=FOO123
 
+# Create a 5 minute maintenance window for service FOO123, using a token
+- pagerduty: name=companyabc
+             token=xxxxxxxxxxxxxx
+             hours=0
+             minutes=5
+             state=running
+             service=FOO123
+
+
 # Create a 4 hour maintenance window for service FOO123 with the description "deployment".
 - pagerduty: name=companyabc
              user=example@example.com

From 34ec5076c34caf8b3fe9888d2e6bc851ad54d653 Mon Sep 17 00:00:00 2001
From: Andrew Newdigate <andrew@troupe.co>
Date: Wed, 16 Apr 2014 22:44:34 +0100
Subject: [PATCH 3/4] Removing unused code

---
 monitoring/pagerduty | 10 ----------
 1 file changed, 10 deletions(-)

diff --git a/monitoring/pagerduty b/monitoring/pagerduty
index 90771a818bd..af0af88c77b 100644
--- a/monitoring/pagerduty
+++ b/monitoring/pagerduty
@@ -142,15 +142,6 @@ def auth_header(user, passwd, token):
     auth = base64.encodestring('%s:%s' % (user, passwd)).replace('\n', '')
     return "Basic %s" % auth
 
-def create_req(url, data, name, user, passwd, token):
-    req = urllib2.Request(url, data)
-    if token:
-        req.add_header("Authorization", "Token token=%s" % token)
-    else:
-        auth = base64.encodestring('%s:%s' % (user, passwd)).replace('\n', '')
-        req.add_header("Authorization", "Basic %s" % auth)
-    return req
-
 def ongoing(module, name, user, passwd, token):
     url = "https://" + name + ".pagerduty.com/api/v1/maintenance_windows/ongoing"
     headers = {"Authorization": auth_header(user, passwd, token)}
@@ -169,7 +160,6 @@ def create(module, name, user, passwd, token, requester_id, service, hours, minu
     end = later.strftime("%Y-%m-%dT%H:%M:%SZ")
 
     url = "https://" + name + ".pagerduty.com/api/v1/maintenance_windows"
-    auth = base64.encodestring('%s:%s' % (user, passwd)).replace('\n', '')
     headers = {
         'Authorization': auth_header(user, passwd, token),
         'Content-Type' : 'application/json',

From 5a07456558b1e85748dc0c1404e2d056a015000d Mon Sep 17 00:00:00 2001
From: Andrew Newdigate <andrew@troupe.co>
Date: Wed, 16 Apr 2014 23:00:01 +0100
Subject: [PATCH 4/4] Added additional error checking to avoid HTTP400
 responses from ansible.

---
 monitoring/pagerduty | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/monitoring/pagerduty b/monitoring/pagerduty
index af0af88c77b..70b310c1a2f 100644
--- a/monitoring/pagerduty
+++ b/monitoring/pagerduty
@@ -167,9 +167,11 @@ def create(module, name, user, passwd, token, requester_id, service, hours, minu
     request_data = {'maintenance_window': {'start_time': start, 'end_time': end, 'description': desc, 'service_ids': [service]}}
     if requester_id:
         request_data['requester_id'] = requester_id
+    else:
+        if token:
+            module.fail_json(msg="requester_id is required when using a token")
 
     data = json.dumps(request_data)
-
     response, info = fetch_url(module, url, data=data, headers=headers, method='POST')
     if info['status'] != 200:
         module.fail_json(msg="failed to create the window: %s" % info['msg'])