Updated code to match new rules
[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 warnings
8
9
10 __author__ = "Basheeruddin Ahmed"
11 __copyright__ = "Copyright(c) 2014, Cisco Systems, Inc."
12 __license__ = "New-style BSD"
13 __email__ = "syedbahm@cisco.com"
14
15
16 global _cache
17
18
19 def get(url, userId='admin', password='admin'):
20     """Helps in making GET REST calls"""
21     warnings.warn(
22         "Use the Robot RequestsLibrary rather than this. See DatastoreCRUD.robot for examples",
23         DeprecationWarning
24     )
25     headers = {}
26     headers['Accept'] = 'application/xml'
27
28     # Send the GET request
29     session = _cache.switch("CLUSTERING_GET")
30     resp = session.get(url, headers=headers, auth=(userId, password))
31     # resp = session.get(url,headers=headers,auth={userId,password})
32     # Read the response
33     return resp
34
35
36 def nonprintpost(url, userId, password, data):
37     """Helps in making POST REST calls without outputs"""
38     warnings.warn(
39         "Use the Robot RequestsLibrary rather than this. See DatastoreCRUD.robot for examples",
40         DeprecationWarning
41     )
42
43     if userId is None:
44         userId = 'admin'
45
46     if password is None:
47         password = 'admin'
48
49     headers = {}
50     headers['Content-Type'] = 'application/json'
51     # headers['Accept']= 'application/xml'
52
53     session = _cache.switch("CLUSTERING_POST")
54     resp = session.post(url, data.encode('utf-8'), headers=headers, auth=(userId, password))
55
56     return resp
57
58
59 def post(url, userId, password, data):
60     """Helps in making POST REST calls"""
61     warnings.warn(
62         "Use the Robot RequestsLibrary rather than this. See DatastoreCRUD.robot for examples",
63         DeprecationWarning
64     )
65
66     if userId is None:
67         userId = 'admin'
68
69     if password is None:
70         password = 'admin'
71
72     print("post request with url "+url)
73     print("post request with data "+data)
74     headers = {}
75     headers['Content-Type'] = 'application/json'
76     # headers['Accept']= 'application/xml'
77     session = _cache.switch("CLUSTERING_POST")
78     resp = session.post(url, data.encode('utf-8'), headers=headers, auth=(userId, password))
79
80     # print (resp.raise_for_status())
81     print (resp.headers)
82     if resp.status_code >= 500:
83         print(resp.text)
84
85     return resp
86
87
88 def delete(url, userId='admin', password='admin'):
89     """Helps in making DELET REST calls"""
90     warnings.warn(
91         "Use the Robot RequestsLibrary rather than this. See DatastoreCRUD.robot for examples",
92         DeprecationWarning
93     )
94     print("delete all resources belonging to url"+url)
95     session = _cache.switch("CLUSTERING_DELETE")
96     resp = session.delete(url, auth=(userId, password))  # noqa
97
98
99 def Should_Not_Be_Type_None(var):
100     '''Keyword to check if the given variable is of type NoneType.  If the
101         variable type does match  raise an assertion so the keyword will fail
102     '''
103     if var is None:
104         raise AssertionError('the variable passed was type NoneType')
105     return 'PASS'
106
107
108 def execute_ssh_command(ip, username, password, command):
109     """Execute SSH Command
110
111     use username and password of controller server for ssh and need
112     karaf distribution location like /root/Documents/dist
113     """
114     print "executing ssh command"
115     lib = SSHLibrary()
116     lib.open_connection(ip)
117     lib.login(username=username, password=password)
118     print "login done"
119     cmd_response = lib.execute_command(command)
120     print "command executed : " + command
121     lib.close_connection()
122     return cmd_response
123
124
125 def wait_for_controller_up(ip, port="8181"):
126     url = "http://" + ip + ":" + str(port) + \
127           "/restconf/config/opendaylight-inventory:nodes/node/controller-config/yang-ext:mount/config:modules"
128
129     print "Waiting for controller " + ip + " up."
130     # Try 30*10s=5 minutes for the controller to be up.
131     for i in xrange(30):
132         try:
133             print "attempt " + str(i) + " to url " + url
134             resp = get(url, "admin", "admin")
135             print "attempt " + str(i) + " response is " + str(resp)
136             print resp.text
137             if ('clustering-it-provider' in resp.text):
138                 print "Wait for controller " + ip + " succeeded"
139                 return True
140         except Exception as e:
141             print e
142         time.sleep(10)
143
144     print "Wait for controller " + ip + " failed"
145     return False
146
147
148 def startAllControllers(username, password, karafhome, port, *ips):
149     # Start all controllers
150     for ip in ips:
151         execute_ssh_command(ip, username, password, karafhome+"/bin/start")
152
153     # Wait for all of them to be up
154     for ip in ips:
155         rc = wait_for_controller_up(ip, port)
156         if rc is False:
157             return False
158     return True
159
160
161 def startcontroller(ip, username, password, karafhome, port):
162     execute_ssh_command(ip, username, password, karafhome + "/bin/start")
163     return wait_for_controller_up(ip, port)
164
165
166 def stopcontroller(ip, username, password, karafhome):
167     executeStopController(ip, username, password, karafhome)
168
169     wait_for_controller_stopped(ip, username, password, karafhome)
170
171
172 def executeStopController(ip, username, password, karafhome):
173     execute_ssh_command(ip, username, password, karafhome+"/bin/stop")
174
175
176 def stopAllControllers(username, password, karafhome, *ips):
177     for ip in ips:
178         executeStopController(ip, username, password, karafhome)
179
180     for ip in ips:
181         wait_for_controller_stopped(ip, username, password, karafhome)
182
183
184 def wait_for_controller_stopped(ip, username, password, karafHome):
185     lib = SSHLibrary()
186     lib.open_connection(ip)
187     lib.login(username=username, password=password)
188
189     # Wait 1 minute for the controller to stop gracefully
190     tries = 20
191     i = 1
192     while i <= tries:
193         stdout = lib.execute_command("ps -axf | grep karaf | grep -v grep | wc -l")
194         # print "stdout: "+stdout
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 #
308 # main invoked
309 if __name__ != "__main__":
310     _cache = robot.utils.ConnectionCache('No sessions created')
311     # here create one session for each HTTP functions
312     _cache.register(requests.session(), alias='CLUSTERING_GET')
313     _cache.register(requests.session(), alias='CLUSTERING_POST')
314     _cache.register(requests.session(), alias='CLUSTERING_DELETE')