Use wildcard *journal
[integration/test.git] / csit / libraries / UtilLibrary.py
1 import requests
2 from SSHLibrary import SSHLibrary
3
4 import robot
5 import time
6 import re
7 import json
8 import warnings
9
10
11 __author__ = "Basheeruddin Ahmed"
12 __copyright__ = "Copyright(c) 2014, Cisco Systems, Inc."
13 __license__ = "New-style BSD"
14 __email__ = "syedbahm@cisco.com"
15
16
17 global _cache
18
19
20 def get(url, userId='admin', password='admin'):
21     """Helps in making GET REST calls"""
22     warnings.warn(
23         "Use the Robot RequestsLibrary rather than this. See DatastoreCRUD.robot for examples",
24         DeprecationWarning
25     )
26     headers = {}
27     headers['Accept'] = 'application/xml'
28
29     # Send the GET request
30     session = _cache.switch("CLUSTERING_GET")
31     resp = session.get(url, headers=headers, auth=(userId, password))
32     # resp = session.get(url,headers=headers,auth={userId,password})
33     # Read the response
34     return resp
35
36
37 def nonprintpost(url, userId, password, data):
38     """Helps in making POST REST calls without outputs"""
39     warnings.warn(
40         "Use the Robot RequestsLibrary rather than this. See DatastoreCRUD.robot for examples",
41         DeprecationWarning
42     )
43
44     if userId is None:
45         userId = 'admin'
46
47     if password is None:
48         password = 'admin'
49
50     headers = {}
51     headers['Content-Type'] = 'application/json'
52     # headers['Accept']= 'application/xml'
53
54     session = _cache.switch("CLUSTERING_POST")
55     resp = session.post(url, data.encode('utf-8'), headers=headers, auth=(userId, password))
56
57     return resp
58
59
60 def post(url, userId, password, data):
61     """Helps in making POST REST calls"""
62     warnings.warn(
63         "Use the Robot RequestsLibrary rather than this. See DatastoreCRUD.robot for examples",
64         DeprecationWarning
65     )
66
67     if userId is None:
68         userId = 'admin'
69
70     if password is None:
71         password = 'admin'
72
73     print("post request with url " + url)
74     print("post request with data " + data)
75     headers = {}
76     headers['Content-Type'] = 'application/json'
77     # headers['Accept'] = 'application/xml'
78     session = _cache.switch("CLUSTERING_POST")
79     resp = session.post(url, data.encode('utf-8'), headers=headers, auth=(userId, password))
80
81     # print(resp.raise_for_status())
82     print(resp.headers)
83     if resp.status_code >= 500:
84         print(resp.text)
85
86     return resp
87
88
89 def delete(url, userId='admin', password='admin'):
90     """Helps in making DELET REST calls"""
91     warnings.warn(
92         "Use the Robot RequestsLibrary rather than this. See DatastoreCRUD.robot for examples",
93         DeprecationWarning
94     )
95     print("delete all resources belonging to url" + url)
96     session = _cache.switch("CLUSTERING_DELETE")
97     resp = session.delete(url, auth=(userId, password))  # noqa
98
99
100 def Should_Not_Be_Type_None(var):
101     '''Keyword to check if the given variable is of type NoneType.  If the
102         variable type does match  raise an assertion so the keyword will fail
103     '''
104     if var is None:
105         raise AssertionError('the variable passed was type NoneType')
106     return 'PASS'
107
108
109 def execute_ssh_command(ip, username, password, command):
110     """Execute SSH Command
111
112     use username and password of controller server for ssh and need
113     karaf distribution location like /root/Documents/dist
114     """
115     print("executing ssh command")
116     lib = SSHLibrary()
117     lib.open_connection(ip)
118     lib.login(username=username, password=password)
119     print("login done")
120     cmd_response = lib.execute_command(command)
121     print("command executed : " + command)
122     lib.close_connection()
123     return cmd_response
124
125
126 def wait_for_controller_up(ip, port="8181"):
127     url = "http://" + ip + ":" + str(port) + \
128           "/restconf/config/opendaylight-inventory:nodes/node/controller-config/yang-ext:mount/config:modules"
129
130     print("Waiting for controller " + ip + " up.")
131     # Try 30*10s=5 minutes for the controller to be up.
132     for i in xrange(30):
133         try:
134             print("attempt %s to url %s" % (str(i), url))
135             resp = get(url, "admin", "admin")
136             print("attempt %s response is %s" % (str(i), str(resp)))
137             print(resp.text)
138             if ('clustering-it-provider' in resp.text):
139                 print("Wait for controller " + ip + " succeeded")
140                 return True
141         except Exception as e:
142             print(e)
143         time.sleep(10)
144
145     print("Wait for controller " + ip + " failed")
146     return False
147
148
149 def startAllControllers(username, password, karafhome, port, *ips):
150     # Start all controllers
151     for ip in ips:
152         execute_ssh_command(ip, username, password, karafhome + "/bin/start")
153
154     # Wait for all of them to be up
155     for ip in ips:
156         rc = wait_for_controller_up(ip, port)
157         if rc is False:
158             return False
159     return True
160
161
162 def startcontroller(ip, username, password, karafhome, port):
163     execute_ssh_command(ip, username, password, karafhome + "/bin/start")
164     return wait_for_controller_up(ip, port)
165
166
167 def stopcontroller(ip, username, password, karafhome):
168     executeStopController(ip, username, password, karafhome)
169
170     wait_for_controller_stopped(ip, username, password, karafhome)
171
172
173 def executeStopController(ip, username, password, karafhome):
174     execute_ssh_command(ip, username, password, karafhome + "/bin/stop")
175
176
177 def stopAllControllers(username, password, karafhome, *ips):
178     for ip in ips:
179         executeStopController(ip, username, password, karafhome)
180
181     for ip in ips:
182         wait_for_controller_stopped(ip, username, password, karafhome)
183
184
185 def wait_for_controller_stopped(ip, username, password, karafHome):
186     lib = SSHLibrary()
187     lib.open_connection(ip)
188     lib.login(username=username, password=password)
189
190     # Wait 1 minute for the controller to stop gracefully
191     tries = 20
192     i = 1
193     while i <= tries:
194         stdout = lib.execute_command("ps -axf | grep karaf | grep -v grep | wc -l")
195         processCnt = stdout[0].strip('\n')
196         print("processCnt: " + processCnt)
197         if processCnt == '0':
198             break
199         i = i + 1
200         time.sleep(3)
201
202     lib.close_connection()
203
204     if i > tries:
205         print("Killing controller")
206         kill_controller(ip, username, password, karafHome)
207
208
209 def clean_journal(ip, username, password, karafHome):
210     execute_ssh_command(ip, username, password, "rm -rf " + karafHome + "/*journal")
211
212
213 def kill_controller(ip, username, password, karafHome):
214     execute_ssh_command(ip, username, password,
215                         "ps axf | grep karaf | grep -v grep | awk '{print \"kill -9 \" $1}' | sh")
216
217
218 def isolate_controller(controllers, username, password, isolated):
219     """ Isolate one controller from the others in the cluster
220
221     :param controllers: A list of ip addresses or host names as strings.
222     :param username: Username for the controller to be isolated.
223     :param password: Password for the controller to be isolated.
224     :param isolated: Number (starting at one) of the controller to be isolated.
225     :return: If successful, returns "pass", otherwise returns the last failed IPTables text.
226     """
227     isolated_controller = controllers[isolated - 1]
228     for controller in controllers:
229         if controller != isolated_controller:
230             base_str = 'sudo iptables -I OUTPUT -p all --source '
231             cmd_str = base_str + isolated_controller + ' --destination ' + controller + ' -j DROP'
232             execute_ssh_command(isolated_controller, username, password, cmd_str)
233             cmd_str = base_str + controller + ' --destination ' + isolated_controller + ' -j DROP'
234             execute_ssh_command(isolated_controller, username, password, cmd_str)
235     ip_tables = execute_ssh_command(isolated_controller, username, password, 'sudo iptables -L')
236     print(ip_tables)
237     iso_result = 'pass'
238     for controller in controllers:
239         controller_regex_string = "[\s\S]*" + isolated_controller + " *" + controller + "[\s\S]*"
240         controller_regex = re.compile(controller_regex_string)
241         if not controller_regex.match(ip_tables):
242             iso_result = ip_tables
243         controller_regex_string = "[\s\S]*" + controller + " *" + isolated_controller + "[\s\S]*"
244         controller_regex = re.compile(controller_regex_string)
245         if not controller_regex.match(ip_tables):
246             iso_result = ip_tables
247     return iso_result
248
249
250 def rejoin_controller(controllers, username, password, isolated):
251     """ Return an isolated controller to the cluster.
252
253     :param controllers: A list of ip addresses or host names as strings.
254     :param username: Username for the isolated controller.
255     :param password: Password for the isolated controller.
256     :param isolated: Number (starting at one) of the isolated controller isolated.
257     :return: If successful, returns "pass", otherwise returns the last failed IPTables text.
258     """
259     isolated_controller = controllers[isolated - 1]
260     for controller in controllers:
261         if controller != isolated_controller:
262             base_str = 'sudo iptables -D OUTPUT -p all --source '
263             cmd_str = base_str + isolated_controller + ' --destination ' + controller + ' -j DROP'
264             execute_ssh_command(isolated_controller, username, password, cmd_str)
265             cmd_str = base_str + controller + ' --destination ' + isolated_controller + ' -j DROP'
266             execute_ssh_command(isolated_controller, username, password, cmd_str)
267     ip_tables = execute_ssh_command(isolated_controller, username, password, 'sudo iptables -L')
268     print(ip_tables)
269     iso_result = 'pass'
270     for controller in controllers:
271         controller_regex_string = "[\s\S]*" + isolated_controller + " *" + controller + "[\s\S]*"
272         controller_regex = re.compile(controller_regex_string)
273         if controller_regex.match(ip_tables):
274             iso_result = ip_tables
275         controller_regex_string = "[\s\S]*" + controller + " *" + isolated_controller + "[\s\S]*"
276         controller_regex = re.compile(controller_regex_string)
277         if controller_regex.match(ip_tables):
278             iso_result = ip_tables
279     return iso_result
280
281
282 def flush_iptables(controllers, username, password):
283     """Removes all entries from IPTables on all controllers.
284
285     :param controllers: A list of ip address or host names as strings.
286     :param username: Username for all controllers.
287     :param password: Password for all controllers.
288     :return: If successful, returns "pass", otherwise returns "fail".
289     """
290     flush_result = 'pass'
291     for controller in controllers:
292         print('Flushing ', controller)
293         cmd_str = 'sudo iptables -v -F'
294         cmd_result = execute_ssh_command(controller, username, password, cmd_str)
295         print(cmd_result)
296         success_string = "Flushing chain `INPUT'" + "\n"
297         success_string += "Flushing chain `FORWARD'" + "\n"
298         success_string += "Flushing chain `OUTPUT'"
299         if not cmd_result == success_string:
300             flush_result = "Failed to flush IPTables. Check Log."
301         print(".")
302         print(".")
303         print(".")
304     return flush_result
305
306
307 def build_elastic_search_JSON_request(query_String):
308     data = {'from': '0',
309             'size': '1',
310             'sort': [{'TimeStamp': {'order': 'desc'}}],
311             'query': {'query_string': {'query': query_String}}}
312     return json.dumps(data)
313
314
315 def create_query_string_search(data_category, metric_name, node_id, rk_node_id):
316     query = 'TSDRDataCategory:'
317     query += data_category
318     query += ' AND MetricName:'
319     query += metric_name
320     query += ' AND NodeID:\"'
321     query += node_id
322     query += '\" AND RecordKeys.KeyValue:\"'
323     query += rk_node_id
324     query += '\" AND RecordKeys.KeyName:Node AND RecordKeys.KeyValue:0 AND RecordKeys.KeyName:Table'
325     return query
326
327
328 def create_query_string_count(data_category):
329     query = 'TSDRDataCategory:'
330     query += data_category
331     return query
332
333
334 def extract_metric_value_search(response):
335     return str(response['hits']['hits'][0]['_source']['MetricValue'])
336
337
338 def extract_metric_value_count(response):
339     return int(response['hits']['total'])
340
341
342 #
343 # main invoked
344 if __name__ != "__main__":
345     _cache = robot.utils.ConnectionCache('No sessions created')
346     # here create one session for each HTTP functions
347     _cache.register(requests.session(), alias='CLUSTERING_GET')
348     _cache.register(requests.session(), alias='CLUSTERING_POST')
349     _cache.register(requests.session(), alias='CLUSTERING_DELETE')