blob: d85fa203a4cf5f21a381d8fe345e5ca17b985a6f [file] [log] [blame]
Zack Williams821c5022020-01-15 15:11:46 -07001# Copyright 2017-present Open Networking Foundation
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15*** Settings ***
16Documentation Library for various utilities
17Library SSHLibrary
18Library String
19Library DateTime
20Library Process
21Library Collections
22Library RequestsLibrary
23
24*** Keywords ***
25Login To Remote System
26 [Documentation] SSH into a remote host (and into a container on that host if container_type
27 ... and container_name are specified) and returns connection ID
28 [Arguments] ${ip} ${user} ${pass}=${None}
29 ... ${container_type}=${None} ${container_name}=${None}
30 ... ${prompt}=~$ ${prompt_timeout}=15s ${container_prompt}=#
31 ${conn_id}= SSHLibrary.Open Connection ${ip} prompt=${prompt} timeout=${prompt_timeout}
32 Run Keyword If '${pass}' != '${None}'
33 ... SSHLibrary.Login ${user} ${pass}
34 ... ELSE
35 ... SSHLibrary.Login With Public Key ${user} %{HOME}/.ssh/id_rsa
36 # Login to the lxc container
37 Run Keyword If '${container_type}' == 'LXC' Run Keywords
38 ... SSHLibrary.Write lxc exec ${container_name} /bin/bash
39 ... AND
40 ... SSHLibrary.Read Until ${container_prompt}
41 ... AND
42 ... SSHLibrary.Set Client Configuration prompt=${container_prompt}
43 # Login to the k8s container
44 # FIXME: This fails if /bin/bash isn't installed in the container, run on command
45 Run Keyword If '${container_type}' == 'K8S' Run Keywords
46 ... SSHLibrary.Write kubectl -n $(kubectl get pods --all-namespaces | grep ${container_name} | awk '{print $1}') exec ${container_name} -it /bin/bash
47 ... AND
48 ... SSHLibrary.Read Until ${container_prompt}
49 ... AND
50 ... SSHLibrary.Set Client Configuration prompt=${container_prompt}
51 # Try to switch to root user
52 # FIXME: Is is useful in the LXC/K8S cases?
53 ${conn}= SSHLibrary.Get Connection ${conn_id}
54 Run Keyword And Ignore Error
55 ... SSHLibrary.Write sudo -s
56 ${output}= SSHLibrary.Read Until Regexp \#|${conn.prompt}|password for ${user}:
57 Run Keyword If 'password for ${user}:' not in '''${output}'''
58 ... Return From Keyword ${conn_id}
59 SSHLibrary.Set Client Configuration prompt=\#
60 SSHLibrary.Write ${pass}
61 SSHLibrary.Read Until Prompt
62 [Return] ${conn_id}
63
64Logout From Remote System
65 [Documentation] Exit from the SSH session to a remote host
66 [Arguments] ${conn_id}
67 SSHLibrary.Switch Connection ${conn_id}
68 SSHLibrary.Close Connection
69
70Run Command On Remote System
71 [Documentation] Executes a command on remote host and returns output
72 [Arguments] ${cmd} ${conn_id} ${user} ${pass}=${None}
73 ${conn}= SSHLibrary.Get Connection ${conn_id}
74 SSHLibrary.Switch Connection ${conn_id}
75 SSHLibrary.Write ${cmd}
76 ${output}= SSHLibrary.Read Until Regexp ${conn.prompt}|password for ${user}:
77 Run Keyword If 'password for ${user}:' not in '''${output}'''
78 ... Return From Keyword ${output}
79 SSHLibrary.Write ${pass}
80 ${output}= SSHlibrary.Read Until Prompt
81 [Return] ${output}
82
83Login And Run Command On Remote System
84 [Documentation] SSH into a remote host (and into a container on that host if container_type
85 ... and container_name are specified), switch to root user, executes command, return output
86 [Arguments] ${cmd} ${ip} ${user} ${pass}=${None}
87 ... ${container_type}=${None} ${container_name}=${None}
88 ... ${prompt}=~$ ${prompt_timeout}=50s ${container_prompt}=#
89 ${conn_id} Login To Remote System ${ip} ${user} ${pass}
90 ... ${container_type} ${container_name}
91 ... ${prompt} ${prompt_timeout} ${container_prompt}
92 ${output}= Run Command On Remote System ${cmd} ${conn_id} ${user} ${pass}
93 Log ${output}
94 # FIXME: Look into persisting SSH connection rather than tearing it up/down repeatedly
95 Logout From Remote System ${conn_id}
96 [Return] ${output}
97
98Execute Command Locally
99 [Documentation] Superfluous, use the 'Run' keyword instead which this wraps
100 [Arguments] ${cmd}
101 ${output}= Run ${cmd}
102 [Return] ${output}
103
104Get Docker Container ID
105 [Documentation] Retrieves the id of the requested docker container running locally
106 [Arguments] ${container_name}
107 ${container_id}= Run docker ps | grep ${container_name} | awk '{print $1}'
108 Log ${container_id}
109 [Return] ${container_id}
110
111Remove Value From List
112 [Documentation] Removes a value from a dictionary
113 [Arguments] ${list} ${val}
114 ${length}= Get Length ${list}
115 FOR ${INDEX} IN RANGE 0 ${length}
116 Log ${list[${INDEX}]}
117 ${value}= Get Dictionary Values ${list[${INDEX}]}
118 Log ${value[0]}
119 Run Keyword If '${value[0]}' == '${val}' Remove From List ${list} ${INDEX}
120 Run Keyword If '${value[0]}' == '${val}' Exit For Loop
121 END
122
123Test Ping
124 [Documentation] SSH's into src and attempts to ping dest.
125 ... Status determines if ping should pass | fail
126 [Arguments] ${status} ${src} ${user} ${pass}
127 ... ${dest} ${interface} ${prompt}=$ ${prompt_timeout}=60s
128 ${conn_id}= SSHLibrary.Open Connection
129 ... ${src} prompt=${prompt} timeout=${prompt_timeout}
130 SSHLibrary.Login ${user} ${pass}
131 ${result}= SSHLibrary.Execute Command
132 ... ping -I ${interface} -c 5 ${dest}
133 SSHLibrary.Close Connection
134 Log ${result}
135 Run Keyword If '${status}' == 'PASS'
136 ... Should Contain ${result} 64 bytes
137 Run Keyword If '${status}' == 'PASS'
138 ... Should Contain ${result} 0% packet loss
139 Run Keyword If '${status}' == 'PASS'
140 ... Should Not Contain ${result} 100% packet loss
141 Run Keyword If '${status}' == 'PASS'
142 ... Should Not Contain ${result} 80% packet loss
143 Run Keyword If '${status}' == 'PASS'
144 ... Should Not Contain ${result} 60% packet loss
145 Run Keyword If '${status}' == 'PASS'
146 ... Should Not Contain ${result} 40% packet loss
147 Run Keyword If '${status}' == 'PASS'
148 ... Should Not Contain ${result} 20% packet loss
149 Run Keyword If '${status}' == 'PASS'
150 ... Should Not Contain ${result} Destination Host Unreachable
151 Run Keyword If '${status}' == 'FAIL'
152 ... Should Not Contain ${result} 64 bytes
153 Run Keyword If '${status}' == 'FAIL'
154 ... Should Contain ${result} 100% packet loss
155 Log To Console \n ${result}
156
157Check Ping Result
158 [Documentation] Check the output of the 'ping' command
159 [Arguments] ${reachable} ${result}
160 Run Keyword If '${reachable}' == 'True'
161 ... Should Contain ${result} 64 bytes
162 Run Keyword If '${reachable}' == 'True'
163 ... Should Contain Any ${result} 0% packet loss 0.0% packet loss
164 Run Keyword If '${reachable}' == 'True'
165 ... Should Not Contain Any ${result} 100% packet loss 100.0% packet loss
166 Run Keyword If '${reachable}' == 'False'
167 ... Should Not Contain ${result} 64 bytes
168 Run Keyword If '${reachable}' == 'False'
169 ... Should Contain Any ${result} 100% packet loss 100.0% packet loss
170
171Check Ping
172 [Documentation] Run 'ping' on remote system and check output
173 [Arguments] ${ping_should_pass} ${dst_ip} ${iface} ${ip}
174 ... ${user} ${pass}=${None} ${container_type}=${None} ${container_name}=${None}
175 ${result}= Login And Run Command On Remote System
176 ... ping -I ${iface} -c 3 ${dst_ip}
177 ... ${ip} ${user} ${pass} ${container_type} ${container_name}
178 Check Ping Result ${ping_should_pass} ${result}
179
180Check Remote System Reachability
181 [Documentation] Check if the specified IP address is reachable or not
182 [Arguments] ${reachable} ${ip}
183 ${result}= Run ping -c 3 ${ip}
184 Check Ping Result ${reachable} ${result}
185
186Kill Linux Process
187 [Documentation] Kill a process on a remote system
188 [Arguments] ${process} ${ip} ${user} ${pass}=${None}
189 ... ${container_type}=${None} ${container_name}=${None}
190 ${rc}= Login And Run Command On Remote System
191 ... kill $(ps aux | grep '${process}' | awk '{print $2}'); echo $?
192 ... ${ip} ${user} ${pass} ${container_type} ${container_name}
193 Should Be Equal As Integers ${rc} 0
194
195Check Remote File Contents
196 [Documentation] Check if file on remote system matches a `grep` regex
197 [Arguments] ${file_should_exist} ${file} ${pattern}
198 ... ${ip} ${user} ${pass}=${None}
199 ... ${container_type}=${None} ${container_name}=${None} ${prompt}=~$
200 ${output}= Login And Run Command On Remote System
201 ... cat ${file} | grep '${pattern}'
202 ... ${ip} ${user} ${pass} ${container_type} ${container_name} ${prompt}
203 # FIXME: Comparison against truthy value
204 Run Keyword If '${file_should_exist}' == 'True'
205 ... Should Contain ${output} ${pattern}
206 ... ELSE
207 ... Should Not Contain ${output} ${pattern}
208
209Set Deployment Config Variables
210 [Documentation] Parses through the given deployment config and sets all the "src" and "dst" variables
211 ${source}= Evaluate ${hosts}.get("src")
212 ${length_src}= Get Length ${source}
213 ${src}= Set Variable src
214 FOR ${INDEX} IN RANGE 0 ${length_src}
215 Set Suite Variable ${${src}${INDEX}} ${source[${INDEX}]}
216 END
217 ${destination}= Evaluate ${hosts}.get("dst")
218 ${length_dst}= Get Length ${destination}
219 ${dst}= Set Variable dst
220 FOR ${INDEX} IN RANGE 0 ${length_dst}
221 Set Suite Variable ${${dst}${INDEX}} ${destination[${INDEX}]}
222 END