-
Notifications
You must be signed in to change notification settings - Fork 0
/
NSLib.py
250 lines (216 loc) · 11.3 KB
/
NSLib.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
#!/usr/bin/env python
# import system/python libraries
import sys, os, re, logging, traceback
# import helper module generated by wsdl2py
import NSStat_services
import NSConfig_services
# setup some basic logging
logging.basicConfig(level=logging.DEBUG, filename='NSLib.log',
format="%(asctime)s [%(levelname)s] (%(funcName)s() (%(filename)s:%(lineno)d)) %(message)s")
class NSLibError(Exception):
""" Simple custom exception class for all exception we are going to raise """
def __init__(self, error_message):
self.error_message = error_message
def __str__(self):
return repr(self.error_message)
class NSSoapApi(object):
def __init__(self, module=None, hostname=None, username=None, password=None):
""" Initialise locator object and create binder object.
URL address is substituted with the IP from imported configuration.
Logger object is setup """
# creating individual loggers for all methods in the class
self.logger = logging.getLogger()
if not module:
self.logger.critical('This class cannot be used directly without assigning appropriate SOAP module, use NSStatApi or NSConfigApi, or define helper module')
raise NSLibError('helper class not defined')
if not (hostname and username and password):
self.logger.critical('One or more from the following: hostname, username and password, are undefined')
raise NSLibError('hostname, username and password must be defined')
self.username = username
self.password = password
self.hostname = hostname
self.module = module
# locator, binding objects initialised
if self.module.__name__ == 'NSStat_services':
self.logger.debug('Initialising Locator and Binding objects from NSStat_services module')
self.locator = self.module.NSStatServiceLocator()
bad_url = self.locator.getNSStatPortAddress()
good_url = re.sub('netscaler_ip', self.hostname, bad_url)
self.soap = self.locator.getNSStatPort(url=good_url)
elif self.module.__name__ == 'NSConfig_services':
self.logger.debug('Initialising Locator and Binding objects from NSConfig_services module')
self.locator = self.module.NSConfigServiceLocator()
bad_url = self.locator.getNSConfigPortAddress()
good_url = re.sub('netscaler_ip', self.hostname, bad_url)
self.soap = self.locator.getNSConfigPort(url=good_url)
else:
self.logger.critical('Unknown module: %s, do not know how to initialise Locator and Binding objects', self.module.__name__)
raise NSLibError('unknown module: %s' % self.module.__name__)
self.logger.debug('Locator and binding objects initialised; loggers set up')
self.login()
def login(self):
""" Create login request with authentication parameters from imported
configuration and perform SOAP API call for login """
self.logger.debug('Logging in...')
# create request object and assign default values
req = self.module.login()
req._username = self.username
req._password = self.password
try:
# call NS login method, check for error code and raise an exception if not successful
res = self.soap.login(req)._return
if res._rc != 0:
self.logger.critical('Error logging in to NS: error code: %d (%s)', (res._rc, res._message))
raise NSLibError('error logging in to NS: error code: %d (%s)' % (res._rc, res._message))
else:
self.logger.info('Successfuly logged in to %s' % self.hostname)
except NSLibError:
# just silently forward our own exception, it's already logged
raise
except:
# exception while performing API call, log and re-raise
self.logger.critical("An exception occured while logging in", exc_info=True)
raise
class NSStatApi(NSSoapApi):
def __init__(self, hostname=None, username=None, password=None):
super(NSStatApi, self).__init__(hostname=hostname,
username=username,
password=password,
module=NSStat_services)
def system_health_check(self):
""" Read system health indicators: cpuusage, memory usage, temperature system connection rate
return these in a hash array """
self.logger.debug('Reading system health indicators...')
results = {}
# create request to get system health data
try:
req = self.module.statsystem()
res = self.soap.statsystem(req)._return
if res._rc != 0:
self.logger.critical('Error reading system data: error code: %d (%s)', (res._rc, res._message))
raise NSLibError('error reading system data: error code: %d (%s)' % (res._rc, res._message))
else:
self.logger.debug('Successfuly read system data')
results['temp'] = res._List[0]._internaltemp
results['cpu'] = res._List[0]._rescpuusage
results['mem'] = res._List[0]._memusagepcnt
req = self.module.statprotocolhttp()
res = self.soap.statprotocolhttp(req)._return
if res._rc != 0:
self.logger.critical('Error reading system data: error code: %d (%s)', (res._rc, res._message))
raise NSLibError('error reading system data: error code: %d (%s)' % (res._rc, res._message))
else:
self.logger.debug('Successfuly read system data')
results['http_req_rate'] = res._List[0]._httprequestsrate
except NSLibError:
# just silently forward our own exception, it's already logged
raise
except:
# exception while performing API call, log and re-raise
self.logger.critical("An exception occured while reading system data", exc_info=True)
raise
return results
def get_vservers_list(self, name=''):
""" Returns a list of all vservers on the loadbalancer """
self.logger.debug('Retrieving list of virtual servers on the loadbalancer')
result = {}
try:
req = self.module.statlbvserver()
req._name = name
res = self.soap.statlbvserver(req)._return
if res._rc != 0:
self.logger.critical('Error retrieving vserver list: error code: %d (%s)', (res._rc, res._message))
raise NSLibError('error retrieving vserver list: error code: %d (%s)' % (res._rc, res._message))
else:
for e in res._List:
result[e._name.strip('"')] = {
'ip': e._primaryipaddress,
'port': e._primaryport,
'status': e._state,
'health': e._vslbhealth,
'requestsrate': e._requestsrate,
}
except NSLibError:
pass
except:
self.logger.critical("An exception occured while reading system data", exc_info=True)
return result
def get_service_details(self, service):
""" Returns service statistics """
result = {}
try:
req = self.module.statservice()
req._name = service
res = self.soap.statservice(req)._return
if res._rc != 0:
self.logger.critical('Error retrieving service details for service "%s": error code: %d (%s)', (service, res._rc, res._message))
raise NSLibError('error retrieving service details: error code: %d (%s)' % (res._rc, res._message))
else:
result = {
'ip': res._List[0]._primaryipaddress,
'port': res._List[0]._primaryport,
'status': res._List[0]._state,
'requestsrate': res._List[0]._requestsrate,
}
except NSLibError:
pass
except:
self.logger.critical("An exception occured while reading system data", exc_info=True)
return result
class NSConfigApi(NSSoapApi):
def __init__(self, hostname=None, username=None, password=None):
super(NSConfigApi, self).__init__(hostname=hostname,
username=username,
password=password,
module=NSConfig_services)
def get_services_list(self, vserver):
""" Returns a list of all services currently bound to the vserver """
self.logger.debug('Reading list of services bound to: %s', vserver)
result = []
try:
req = self.module.getlbvserver()
req._name = vserver
res = self.soap.getlbvserver(req)._return
if res._rc != 0:
self.logger.critical('Error retrieving services list: error code: %d (%s)', (res._rc, res._message))
raise NSLibError('error retrieving services: error code: %d (%s)' % (res._rc, res._message))
else:
try:
result = [e.strip('"') for e in res._List[0]._servicename]
except TypeError:
pass
except NSLibError:
raise
except:
self.logger.critical("An exception occured while reading system data", exc_info=True)
raise
return result
def set_service_state(self, state, service_list, verbose=False):
""" Sets state to all services in the list. service_list must be a list even if it's only one service being manipulated """
self.logger.info('Setting the state of the services to "%s"', state)
self.logger.debug('Services affected "%s"', repr(service_list))
try:
if state not in ('enable', 'disable'):
raise NSLibError('Unknown service state requested: %s' % state)
for service in service_list:
if verbose:
print 'Changing state of %s to %sd... ' % (service, state)
req = getattr(self.module, '%sservice' % state)()
req._name = service
res = getattr(self.soap, '%sservice' % state)(req)._return
if res._rc != 0:
self.logger.critical('Error changing service %s state to %: error code: %d (%s)', (service, state, res._rc, res._message))
raise NSLibError('error changing service %s state to %s' % (service, state))
else:
self.logger.debug('State for service %s successfuly changed to %s', (service, state))
except NSLibError:
raise
except:
self.logger.critical("An exception occured while setting services state")
raise
return
# this will get executed if we start from the command line
def main():
pass
if __name__ == '__main__':
main()