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