This repository has been archived by the owner on Oct 3, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 6
/
satprep_shared.py
executable file
·310 lines (247 loc) · 11.1 KB
/
satprep_shared.py
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
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import getpass
import logging
import os
import stat
import sys
import requests
from requests.auth import HTTPBasicAuth
import time
from datetime import datetime, timedelta
import libvirt
from fnmatch import fnmatch
import string
#some global variables
LIBVIRT_USERNAME=""
LIBVIRT_PASSWORD=""
LOGGER = logging.getLogger('satprep-shared')
SUPPORTED_API_LEVELS = ["11.1", "12", "13", "13.0", "14", "14.0", "15", "15.0", "16", "16.0", "17", "17.0"]
class APILevelNotSupportedException(Exception):
pass
def check_if_api_is_supported(client):
#check whether API is supported
api_level = client.api.getVersion()
if api_level not in SUPPORTED_API_LEVELS:
raise APILevelNotSupportedException(
"Your API version ({0}) does not support the required calls. "
"You'll need API version 1.8 (11.1) or higher!".format(api_level)
)
else:
LOGGER.info("Supported API version (" + api_level + ") found.")
def get_credentials(type, input_file=None):
#retrieve credentials
if input_file:
LOGGER.debug("Using authfile")
try:
# check filemode and read file
filemode = oct(stat.S_IMODE(os.lstat(input_file).st_mode))
if filemode == "0600":
LOGGER.debug("File permission matches 0600")
with open(input_file, "r") as auth_file:
s_username = auth_file.readline().replace("\n", "")
s_password = auth_file.readline().replace("\n", "")
return (s_username, s_password)
else:
LOGGER.warning("File permissions (" + filemode + ") not matching 0600!")
#sys.exit(1)
except OSError:
LOGGER.warning("File non-existent or permissions not 0600!")
#sys.exit(1)
LOGGER.debug("Prompting for login credentials as we have a faulty file")
s_username = raw_input(type + " Username: ")
s_password = getpass.getpass(type + " Password: ")
return (s_username, s_password)
elif type.upper()+"_LOGIN" in os.environ and type.upper()+"_PASSWORD" in os.environ:
# shell variables
LOGGER.debug("Checking shell variables")
return (os.environ[type.upper()+"_LOGIN"], os.environ[type.upper()+"_PASSWORD"])
else:
# prompt user
LOGGER.debug("Prompting for login credentials")
s_username = raw_input(type + " Username: ")
s_password = getpass.getpass(type + " Password: ")
return (s_username, s_password)
def has_snapshot(virtURI, hostUsername, hostPassword, vmName, name):
#check whether VM has a snapshot
#authentificate
global LIBVIRT_USERNAME
global LIBVIRT_PASSWORD
LIBVIRT_USERNAME = hostUsername
LIBVIRT_PASSWORD = hostPassword
LOGGER.debug("Checking for snapshots with user '" + hostUsername + "'...")
auth = [[libvirt.VIR_CRED_AUTHNAME, libvirt.VIR_CRED_PASSPHRASE], get_libvirt_credentials, None]
conn = libvirt.openAuth(virtURI, auth, 0)
if conn == None:
LOGGER.error("Unable to establish connection to hypervisor!")
return False
try:
targetVM = conn.lookupByName(vmName)
mySnaps = targetVM.snapshotListNames(0)
if name in mySnaps: return True
except Exception,e:
return False
def is_downtime(url, monUsername, monPassword, host, agent, noAuth=False):
#check whether host is scheduled for downtime
#setup headers
if len(agent) > 0: myHeaders = {'User-Agent': agent}
else: myHeaders = {'User-Agent': 'satprep Toolkit (https://github.com/stdevel/satprep)'}
LOGGER.debug("Setting headers: {0}".format(myHeaders))
#setup HTTP session
s = requests.Session()
if noAuth == False: s.auth = HTTPBasicAuth(monUsername, monPassword)
#send GET request
r = s.get(url+"/cgi-bin/status.cgi?host=all&hostprops=1&style=hostdetail", headers=myHeaders, verify=False)
try:
LOGGER.debug("Result: {0}".format(r.text))
except:
LOGGER.debug("Result: none - check URL/authentification method!")
#check whether request was successful
if r.status_code != 200:
LOGGER.error("Got HTTP status code " + str(r.status_code) + " instead of 200 while checking downtime for host '" + host + "'. Check URL and logon credentials!")
return False
else:
if "error" in r.text.lower(): LOGGER.error("Unable to get downtime for host '" + host + "' - please run again with -d / --debug and check HTML output! (does this host exist?!)")
else:
if host.lower() not in r.text.lower():
LOGGER.info("Host '" + host + "' currently NOT scheduled for downtime.")
return False
else:
LOGGER.info("Host '" + host + "' currently in scheduled downtime.")
return True
def schedule_downtime(url, monUsername, monPassword, host, hours, comment, agent="", noAuth=False, unschedule=False):
#(un)schedule downtime
#setup headers
if len(agent) > 0: myHeaders = {'User-Agent': agent}
else: myHeaders = {'User-Agent': 'satprep Toolkit (https://github.com/stdevel/satprep)'}
LOGGER.debug("Setting headers: {0}".format(myHeaders))
#setup start and end time for downtime
current_time=time.strftime("%Y-%m-%d %H:%M:%S")
end_time=format(datetime.now() + timedelta(hours=int(hours)), '%Y-%m-%d %H:%M:%S')
LOGGER.debug("current_time: {0}".format(current_time))
LOGGER.debug("end_time: {0}".format(end_time))
#setup payload
if unschedule:
payload = {'cmd_typ': '171', 'cmd_mod': '2', 'host': host, 'btnSubmit': 'Commit'}
else:
payload = {'cmd_typ': '55', 'cmd_mod': '2', 'host': host, 'com_data': comment, 'trigger': '0', 'fixed': '1', 'hours': hours, 'minutes': '0', 'start_time': current_time, 'end_time': end_time, 'btnSubmit': 'Commit', 'com_author': monUsername, 'childoptions': '0'}
LOGGER.debug("payload: {0}".format(payload))
#setup HTTP session
s = requests.Session()
if noAuth == False: s.auth = HTTPBasicAuth(monUsername, monPassword)
#send POST request
r = s.post(url+"/cgi-bin/cmd.cgi", data=payload, headers=myHeaders, verify=False)
try:
LOGGER.debug("Result: {0}".format(r.text))
except:
LOGGER.debug("Result: none - check URL/authentification method!")
#check whether request was successful
if r.status_code != 200:
LOGGER.error("Got HTTP status code " + str(r.status_code) + " instead of 200 while (un)scheduling downtime for host '" + host + "'. Check URL and logon credentials!")
return False
else:
if "error" in r.text.lower(): LOGGER.error("Unable to (un)schedule downtime for host '" + host + "' - please run again with -d / --debug and check HTML output! (does this host exist?!)")
else:
if unschedule: print "Successfully unscheduled downtime for host '" + host + "'"
else: print "Successfully scheduled downtime for host '" + host + "'"
return True
def schedule_downtime_hostgroup(url, monUsername, monPassword, hostgroup, hours, comment, agent="", noAuth=False):
#schedule downtime for hostgroup
#setup headers
if len(agent) > 0: myHeaders = {'User-Agent': agent}
else: myHeaders = {'User-Agent': 'satprep Toolkit (https://github.com/stdevel/satprep)'}
LOGGER.debug("Setting headers: {0}".format(myHeaders))
#setup start and end time for downtime
current_time=time.strftime("%Y-%m-%d %H:%M:%S")
end_time=format(datetime.now() + timedelta(hours=int(hours)), '%Y-%m-%d %H:%M:%S')
LOGGER.debug("current_time: {0}".format(current_time))
LOGGER.debug("end_time: {0}".format(end_time))
#setup payload
#NOTE: there is no way to unschedule downtimes for all hosts/services in a hostgroup
payload = {'cmd_typ': '85', 'cmd_mod': '2', 'hostgroup': hostgroup, 'com_data': comment, 'trigger': '0', 'fixed': '1', 'hours': hours, 'minutes': '0', 'start_time': current_time, 'end_time': end_time, 'btnSubmit': 'Commit', 'com_author': monUsername, 'childoptions': '0', 'ahas': 'on'}
LOGGER.debug("payload: {0}".format(payload))
#setup HTTP session
s = requests.Session()
if noAuth == False: s.auth = HTTPBasicAuth(monUsername, monPassword)
#send POST request
r = s.post(url+"/cgi-bin/cmd.cgi", data=payload, headers=myHeaders, verify=False)
try:
LOGGER.debug("Result: {0}".format(r.text))
except:
LOGGER.debug("Result: none - check URL/authentification method!")
#check whether request was successful
if r.status_code != 200:
LOGGER.error("Got HTTP status code " + str(r.status_code) + " instead of 200 while scheduling downtime for hostgroup '" + hostgroup + "'. Check URL and logon credentials!")
return False
else:
if "error" in r.text.lower(): LOGGER.error("Unable to schedule downtime for hostgroup '" + hostgroup + "' - please run again with -d / --debug and check HTML output! (does this host exist?!)")
else:
print "Successfully scheduled downtime for hostgroup '" + hostgroup + "'"
return True
def get_libvirt_credentials(credentials, user_data):
#get credentials for libvirt
global LIBVIRT_USERNAME
global LIBVIRT_PASSWORD
for credential in credentials:
if credential[0] == libvirt.VIR_CRED_AUTHNAME:
# prompt the user to input a authname. display the provided message
#credential[4] = raw_input(credential[1] + ": ")
credential[4] = LIBVIRT_USERNAME
# if the user just hits enter raw_input() returns an empty string.
# in this case return the default result through the last item of
# the list
if len(credential[4]) == 0:
credential[4] = credential[3]
elif credential[0] == libvirt.VIR_CRED_PASSPHRASE:
# use the getpass module to prompt the user to input a password.
# display the provided message and return the result through the
# last item of the list
#credential[4] = getpass.getpass(credential[1] + ": ")
credential[4] = LIBVIRT_PASSWORD
else:
return -1
return 0
def create_snapshot(virtURI, hostUsername, hostPassword, vmName, name, comment, remove=False):
#create/remove snapshot
#authentificate
global LIBVIRT_USERNAME
global LIBVIRT_PASSWORD
LIBVIRT_USERNAME = hostUsername
LIBVIRT_PASSWORD = hostPassword
LOGGER.debug("Creating snapshot with user '" + hostUsername + "'...")
auth = [[libvirt.VIR_CRED_AUTHNAME, libvirt.VIR_CRED_PASSPHRASE], get_libvirt_credentials, None]
conn = libvirt.openAuth(virtURI, auth, 0)
if conn == None:
LOGGER.error("Unable to establish connection to hypervisor!")
#sys.exit(1)
return False
try:
targetVM = conn.lookupByName(vmName)
if remove:
#remove snapshot
targetSnap = targetVM.snapshotLookupByName(name, 0)
return targetSnap.delete(0)
else:
#create snapshot
snapXML = "<domainsnapshot><name>" + name + "</name><description>" + comment + "</description></domainsnapshot>"
return targetVM.snapshotCreateXML(snapXML, 0)
except Exception,e:
#Snapshot 'Before maintenance' already exists
if remove:
LOGGER.error("Unable to remove snapshot: '" + str(e) + "'")
else:
LOGGER.error("Unable to create snapshot: '" + str(e) + "'")
return False
def is_blacklisted(name, list):
#check whether system is blacklisted
for entry in list:
LOGGER.debug("Checking whether {name} is blacklisted by *{entry}*".format(name=name, entry=entry))
if fnmatch(name.lower(), "*{seek}*".format(seek=entry.lower()) ): return True
return False
def get_systems_by_systemgroup(client, key, group):
#get systems by system group
systems = client.systemgroup.listSystems(key, group)
LOGGER.debug(systems)
def escape_string(str):
temp=filter(string.printable.__contains__,str)
return ''.join([c for c in temp if ord(c) > 31 or ord(c) == 9])