|
| 1 | +#!/usr/bin/env python |
| 2 | +# |
| 3 | +# Copyright (c) 2018, PagerDuty, Inc. <[email protected]> |
| 4 | +# All rights reserved. |
| 5 | +# |
| 6 | +# Redistribution and use in source and binary forms, with or without |
| 7 | +# modification, are permitted provided that the following conditions are met: |
| 8 | +# * Redistributions of source code must retain the above copyright |
| 9 | +# notice, this list of conditions and the following disclaimer. |
| 10 | +# * Redistributions in binary form must reproduce the above copyright |
| 11 | +# notice, this list of conditions and the following disclaimer in the |
| 12 | +# documentation and/or other materials provided with the distribution. |
| 13 | +# * Neither the name of PagerDuty Inc nor the |
| 14 | +# names of its contributors may be used to endorse or promote products |
| 15 | +# derived from this software without specific prior written permission. |
| 16 | +# |
| 17 | +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
| 18 | +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 19 | +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| 20 | +# ARE DISCLAIMED. IN NO EVENT SHALL PAGERDUTY INC BE LIABLE FOR ANY |
| 21 | +# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| 22 | +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| 23 | +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
| 24 | +# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 | +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
| 26 | +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | + |
| 28 | +# -------------------------------------------------------------------------------- |
| 29 | +# INSTRUCTIONS |
| 30 | +# |
| 31 | +# This script creates a maintenance window on all services. It does not support |
| 32 | +# pagination, so it is limited to 100 services (by default it will sort by name) |
| 33 | +# |
| 34 | +# REQUIRED: API_KEY, EMAIL |
| 35 | +# |
| 36 | +# OPTIONAL: You can specify the delay before starting the maintenance window, as |
| 37 | +# well as the duration. If you prefer, you can instead input the date in `start` |
| 38 | +# and `end` below. |
| 39 | +# |
| 40 | +# # Date format: '2018-09-30T14:00:00' |
| 41 | +# |
| 42 | +# There are also optional parameters for filtering services or maintenance windows. |
| 43 | +# |
| 44 | +# -------------------------------------------------------------------------------- |
| 45 | + |
| 46 | +import requests |
| 47 | +import json |
| 48 | +import datetime |
| 49 | + |
| 50 | +# Update to match your API key |
| 51 | +API_KEY = '' |
| 52 | + |
| 53 | +# Update to match your login email |
| 54 | +EMAIL = '' |
| 55 | + |
| 56 | +# get_services parameters |
| 57 | +TEAM_IDS = [] |
| 58 | +TIME_ZONE = 'UTC' |
| 59 | +SORT_BY = 'name' |
| 60 | +QUERY = '' |
| 61 | +INCLUDE = [] |
| 62 | + |
| 63 | +# set the delay and duration of maintenance windows |
| 64 | +maintenance_start_delay_in_minutes = 0 |
| 65 | +maintenance_duration_in_minutes = 10 |
| 66 | + |
| 67 | +# This gets the timezone of your local server - for UTC, use datetime.datetime.utcnow() |
| 68 | +current_time = datetime.datetime.now() |
| 69 | +start_time = str(current_time + datetime.timedelta(minutes = maintenance_start_delay_in_minutes)) |
| 70 | +end_time = str(current_time + datetime.timedelta(minutes = maintenance_start_delay_in_minutes + maintenance_duration_in_minutes)) |
| 71 | + |
| 72 | +# You can also specify a start or end date here instead (Date format: '2018-09-30T14:00:00') |
| 73 | +start = start_time |
| 74 | +end = end_time |
| 75 | +START_TIME = (start[0:10] + 'T' + start[11:19]) |
| 76 | +END_TIME = (end[0:10] + 'T' + end[11:19]) |
| 77 | +DESCRIPTION = 'This maintenance window was created from a python script' |
| 78 | +TEAMS = [] |
| 79 | +TYPE = 'maintenance_window' |
| 80 | + |
| 81 | +# ----------------------------------------------------------------------- |
| 82 | + |
| 83 | + |
| 84 | +def get_services(): |
| 85 | + print('Getting services...', flush=True) |
| 86 | + url = 'https://api.pagerduty.com/services?total=true' |
| 87 | + headers = { |
| 88 | + 'Accept': 'application/vnd.pagerduty+json;version=2', |
| 89 | + 'Authorization': 'Token token={token}'.format(token=API_KEY) |
| 90 | + } |
| 91 | + payload = { |
| 92 | + 'team_ids[]': TEAM_IDS, |
| 93 | + 'time_zone': TIME_ZONE, |
| 94 | + 'sort_by': SORT_BY, |
| 95 | + 'query': QUERY, |
| 96 | + 'include[]': INCLUDE, |
| 97 | + 'limit': 100 |
| 98 | + } |
| 99 | + r = requests.get(url, headers=headers, params=payload) |
| 100 | + print('\tStatus code: {code}'.format(code=r.status_code)) |
| 101 | + if r.status_code < 200 or r.status_code >= 204: |
| 102 | + print("\tThere was an error getting your services.") |
| 103 | + print("\tPlease ensure that the login email and v2 REST API key in this script are correct.") |
| 104 | + print(r.text) |
| 105 | + SERVICES = [] |
| 106 | + return SERVICES |
| 107 | + #print(r.json()) |
| 108 | + data = json.loads(r.text) |
| 109 | + total_services = data['total'] |
| 110 | + print('Creating maintenance window on {total_services} services...'.format(total_services=total_services)) |
| 111 | + SERVICES = data['services'] |
| 112 | + return SERVICES |
| 113 | + |
| 114 | + |
| 115 | +def create_maintenance_window(SERVICES): |
| 116 | + url = 'https://api.pagerduty.com/maintenance_windows' |
| 117 | + headers = { |
| 118 | + 'Accept': 'application/vnd.pagerduty+json;version=2', |
| 119 | + 'Authorization': 'Token token={token}'.format(token=API_KEY), |
| 120 | + 'Content-type': 'application/json', |
| 121 | + 'From': EMAIL |
| 122 | + } |
| 123 | + |
| 124 | + payload = { |
| 125 | + 'maintenance_window': { |
| 126 | + 'start_time': START_TIME, |
| 127 | + 'end_time': END_TIME, |
| 128 | + 'description': DESCRIPTION, |
| 129 | + 'services': SERVICES, |
| 130 | + 'teams': TEAMS, |
| 131 | + 'type': TYPE |
| 132 | + } |
| 133 | + } |
| 134 | + r = requests.post(url, headers=headers, data=json.dumps(payload)) |
| 135 | + print('\tStatus code: {code}'.format(code=str(r.status_code))) |
| 136 | + if r.status_code >= 200 and r.status_code < 204: |
| 137 | + print("Maintenance window successfully created:") |
| 138 | + print("\tStart: ", START_TIME) |
| 139 | + print("\tEnd: ", END_TIME) |
| 140 | + print("\tServices: ") |
| 141 | + for service in range(int(len(SERVICES))): |
| 142 | + print("\t\t", SERVICES[service]['id']) |
| 143 | + else: |
| 144 | + print("\tThere was an error creating this maintenance window.") |
| 145 | + print("\tPlease ensure that the login email and v2 REST API key in this script have proper permissions") |
| 146 | + # print(r.json()) |
| 147 | + |
| 148 | + |
| 149 | +if __name__ == '__main__': |
| 150 | + if EMAIL == '': |
| 151 | + print("Please add your login email to this script and run it again.") |
| 152 | + elif API_KEY == '': |
| 153 | + print("Please add your v2 REST API key to this script and run it again.") |
| 154 | + else: |
| 155 | + SERVICES = get_services() |
| 156 | + if SERVICES != []: |
| 157 | + create_maintenance_window(SERVICES) |
0 commit comments