Upgrade RF syntax for v3.2 compatibility
[integration/test.git] / csit / libraries / OvsManager.robot
1 *** Settings ***
2 Documentation     Library to provide ovsdb access to mininet topologies
3 Library           SSHLibrary
4 Library           ${CURDIR}/VsctlListParser.py
5 Library           Collections
6
7 *** Variables ***
8 ${SH_BR_CMD}      ovs-vsctl list Bridge
9 ${SH_CNTL_CMD}    ovs-vsctl list Controller
10 ${SHOW_OVS_VERSION}    sudo ovs-vsctl show | grep version
11 ${GET_LOCAL_IP}    sudo ovs-vsctl list Open_vSwitch | grep local_ip=
12 ${ovs_switch_data}    ${None}
13 ${lprompt}        mininet>
14 ${lcmd_prefix}    sh
15
16 *** Keywords ***
17 Initialize If Shell Used
18     [Arguments]    ${prompt}    ${cmd_prefix}
19     BuiltIn.Set Suite variable    ${lprompt}    ${prompt}
20     BuiltIn.Set Suite variable    ${lcmd_prefix}    ${cmd_prefix}
21
22 Get Ovsdb Data
23     [Arguments]    ${prompt}=mininet>
24     [Documentation]    Gets ovs data and parse them.
25     SSHLibrary.Write    ${lcmd_prefix} ${SH_BR_CMD}
26     ${brstdout}=    SSHLibrary.Read_Until    ${lprompt}
27     Log    ${brstdout}
28     SSHLibrary.Write    ${lcmd_prefix} ${SH_CNTL_CMD}
29     ${cntlstdout}=    SSHLibrary.Read_Until    ${lprompt}
30     Log    ${cntlstdout}
31     ${data}    ${bridegs}    ${controllers}=    VsctlListParser.Parse    ${brstdout}    ${cntlstdout}
32     BuiltIn.Log    ${data}
33     BuiltIn.Set Suite Variable    ${ovs_switch_data}    ${data}
34     BuiltIn.Return From Keyword    ${data}
35
36 Get Controllers Uuid
37     [Arguments]    ${switch}    ${controller}    ${update_data}=${False}
38     [Documentation]    Returns controllers uuid
39     Run Keyword If    ${update_data}==${True}    Get Ovsdb Data
40     ${bridge}=    Collections.Get From Dictionary    ${ovs_switch_data}    ${switch}
41     ${cntls}=    Collections.Get From Dictionary    ${bridge}    controller
42     ${cntl}=    Collections.Get From Dictionary    ${cntls}    ${controller}
43     ${uuid}=    Collections.Get From Dictionary    ${cntl}    _uuid
44     BuiltIn.Return From Keyword    ${uuid}
45
46 Execute OvsVsctl Show Command
47     [Documentation]    Executes ovs-vsctl show command and returns stdout, no check nor change is performed
48     SSHLibrary.Write    ${lcmd_prefix} ovs-vsctl show
49     ${output}=    SSHLibrary.Read_Until    ${lprompt}
50     Log    ${output}
51
52 Set Bridge Controllers
53     [Arguments]    ${bridge}    ${controllers}    ${ofversion}=13    ${disconnected}=${False}
54     [Documentation]    Adds controller to the bridge
55     ${cmd}=    BuiltIn.Set Variable    ${lcmd_prefix} ovs-vsctl set bridge ${bridge} protocols=OpenFlow${ofversion}
56     SSHLibrary.Write    ${cmd}
57     ${output}=    SSHLibrary.Read_Until    ${lprompt}
58     Log    ${output}
59     ${cmd}=    BuiltIn.Set Variable    ${lcmd_prefix} ovs-vsctl set-controller ${bridge}
60     FOR    ${cntl}    IN    @{controllers}
61         ${cmd}=    BuiltIn.Set Variable If    ${disconnected}==${False}    ${cmd} tcp:${cntl}:6653    ${cmd} tcp:${cntl}:6654
62     END
63     BuiltIn.Log    ${cmd}
64     SSHLibrary.Write    ${cmd}
65     ${output}=    SSHLibrary.Read_Until    ${lprompt}
66     Log    ${output}
67
68 Disconnect Switch From Controller And Verify Disconnected
69     [Arguments]    ${switch}    ${controller}    ${update_data}=${False}    ${verify_disconnected}=${True}
70     [Documentation]    Disconnects the switch from the controller by setting the incorrect port
71     Run Keyword If    ${update_data}==${True}    Get Ovsdb Data
72     ${uuid}=    Get Controllers Uuid    ${switch}    ${controller}
73     ${cmd}=    BuiltIn.Set Variable    ${lcmd_prefix} ovs-vsctl set Controller ${uuid} target="tcp\\:${controller}\\:6654"
74     SSHLibrary.Write    ${cmd}
75     ${output}=    SSHLibrary.Read_Until    ${lprompt}
76     Log    ${output}
77     Return From Keyword If    ${verify_disconnected}==${False}
78     BuiltIn.Wait Until Keyword Succeeds    5x    2s    Should Be Disconnected    ${switch}    ${controller}    update_data=${True}
79     [Teardown]    Execute OvsVsctl Show Command
80
81 Reconnect Switch To Controller And Verify Connected
82     [Arguments]    ${switch}    ${controller}    ${update_data}=${False}    ${verify_connected}=${True}
83     [Documentation]    Reconnects the switch back to the controller by setting the correct port
84     Run Keyword If    ${update_data}==${True}    Get Ovsdb Data
85     ${uuid}=    Get Controllers Uuid    ${switch}    ${controller}
86     ${cmd}=    BuiltIn.Set Variable    ${lcmd_prefix} ovs-vsctl set Controller ${uuid} target="tcp\\:${controller}\\:6653"
87     SSHLibrary.Write    ${cmd}
88     ${output}=    SSHLibrary.Read_Until    ${lprompt}
89     Log    ${output}
90     Return From Keyword If    ${verify_connected}==${False}
91     BuiltIn.Wait Until Keyword Succeeds    5x    2s    Should Be Connected    ${switch}    ${controller}    update_data=${True}
92     [Teardown]    Execute OvsVsctl Show Command
93
94 Should Be Connected
95     [Arguments]    ${switch}    ${controller}    ${update_data}=${False}
96     [Documentation]    Check if the switch is connected
97     ${connected}=    OvsManager__Is_Connected    ${switch}    ${controller}    update_data=${update_data}
98     BuiltIn.Should Be True    ${connected}
99
100 Should Be Disconnected
101     [Arguments]    ${switch}    ${controller}    ${update_data}=${False}
102     [Documentation]    Check if the switch is disconnected
103     ${connected}=    OvsManager__Is_Connected    ${switch}    ${controller}    update_data=${update_data}
104     BuiltIn.Should Be Equal    ${connected}    ${False}
105
106 OvsManager__Is_Connected
107     [Arguments]    ${switch}    ${controller}    ${update_data}=${False}
108     [Documentation]    Return is_connected boolean value
109     Run Keyword If    ${update_data}==${True}    Get Ovsdb Data
110     ${bridge}=    Collections.Get From Dictionary    ${ovs_switch_data}    ${switch}
111     ${cntls}=    Collections.Get From Dictionary    ${bridge}    controller
112     ${cntl}=    Collections.Get From Dictionary    ${cntls}    ${controller}
113     ${connected}=    Collections.Get From Dictionary    ${cntl}    is_connected
114     [Teardown]    Execute OvsVsctl Show Command
115     [Return]    ${connected}
116
117 Should Be Master
118     [Arguments]    ${switch}    ${controller}    ${update_data}=${False}
119     [Documentation]    Verifies the master role
120     ${role}    Get Node Role    ${switch}    ${controller}    update_data=${update_data}
121     BuiltIn.Should Be Equal    ${role}    master
122
123 Should Be Slave
124     [Arguments]    ${switch}    ${controller}    ${update_data}=${False}
125     [Documentation]    Verifies the slave role
126     ${role}    Get Node Role    ${switch}    ${controller}    update_data=${update_data}
127     BuiltIn.Should Be Equal    ${role}    slave
128
129 Get Node Role
130     [Arguments]    ${switch}    ${controller}    ${update_data}=${False}
131     [Documentation]    Returns the controllers role
132     Run Keyword If    ${update_data}==${True}    Get Ovsdb Data
133     ${bridge}=    Collections.Get From Dictionary    ${ovs_switch_data}    ${switch}
134     ${cntls}=    Collections.Get From Dictionary    ${bridge}    controller
135     ${cntl}=    Collections.Get From Dictionary    ${cntls}    ${controller}
136     ${role}=    Collections.Get From Dictionary    ${cntl}    role
137     Return From Keyword    ${role}
138
139 Get Master Node
140     [Arguments]    ${switch}    ${update_data}=${False}
141     [Documentation]    Gets controller which is a master
142     ${master}=    BuiltIn.Set Variable    ${None}
143     Run Keyword If    ${update_data}==${True}    Get Ovsdb Data
144     ${bridge}=    Collections.Get From Dictionary    ${ovs_switch_data}    ${switch}
145     ${cntls_dict}=    Collections.Get From Dictionary    ${bridge}    controller
146     ${cntls_items}=    Collections.Get Dictionary Items    ${cntls_dict}
147     FOR    ${key}    ${value}    IN    @{cntls_items}
148         Log    ${key} : ${value}
149         ${role}=    Collections.Get From Dictionary    ${value}    role
150         Run Keyword If    "${role}"=="master"    BuiltIn.Should Be Equal    ${master}    ${None}
151         ${master}=    BuiltIn.Set Variable If    "${role}"=="master"    ${key}    ${master}
152     END
153     BuiltIn.Should Not Be Equal    ${master}    ${None}
154     Return From Keyword    ${master}
155
156 Get Slave Nodes
157     [Arguments]    ${switch}    ${update_data}=${False}
158     [Documentation]    Returns a list of ips of slave nodes for particular switch
159     ${slaves}=    BuiltIn.Create List
160     Run Keyword If    ${update_data}==${True}    Get Ovsdb Data
161     ${bridge}=    Collections.Get From Dictionary    ${ovs_switch_data}    ${switch}
162     ${cntls_dict}=    Collections.Get From Dictionary    ${bridge}    controller
163     ${cntls_items}=    Collections.Get Dictionary Items    ${cntls_dict}
164     FOR    ${key}    ${value}    IN    @{cntls_items}
165         Log    ${key} : ${value}
166         ${role}=    Collections.Get From Dictionary    ${value}    role
167         Run Keyword If    "${role}"=="slave"    Collections.Append To List    ${slaves}    ${key}
168     END
169     Return From Keyword    ${slaves}
170
171 Setup Clustered Controller For Switches
172     [Arguments]    ${switches}    ${controller_ips}    ${verify_connected}=${False}
173     [Documentation]    The idea of this keyword is to setup clustered controller and to be more or less sure that the role is filled correctly. The problem is when
174     ...    more controllers are being set up at once, the role shown in Controller ovsdb table is not the same as we can see from wireshark traces.
175     ...    Now we set disconnected controllers and we will connect them expecting that the first connected controller will be master.
176     FOR    ${switch_name}    IN    @{switches}
177         Set Bridge Controllers    ${switch_name}    ${controller_ips}    disconnected=${True}
178         # now we need to enable one node which will be master
179     END
180     OvsManager.Get Ovsdb Data
181     FOR    ${switch_name}    IN    @{switches}
182         ${own}=    Collections.Get From List    ${controller_ips}    0
183         Reconnect Switch To Controller And Verify Connected    ${switch_name}    ${own}    verify_connected=${False}
184         # now we need to wait till master controllers are connected
185     END
186     BuiltIn.Wait Until Keyword Succeeds    5x    2s    OvsManager__Verify_Masters_Connected    ${switches}    update_data=${True}
187     # now we can enable slaves
188     OvsManager__Enable_Slaves    ${switches}    verify_connected=${verify_connected}
189
190 OvsManager__Verify_Masters_Connected
191     [Arguments]    ${switches}    ${update_data}=${False}
192     [Documentation]    Private keyword, the existence of master means it is verified
193     Run Keyword If    ${update_data}==${True}    Get Ovsdb Data
194     FOR    ${switch_name}    IN    @{switches}
195         Get Master Node    ${switch_name}
196     END
197
198 OvsManager__Enable_Slaves
199     [Arguments]    ${switches}    ${update_data}=${False}    ${verify_connected}=${False}
200     [Documentation]    This is a private keyword to enable diconnected controllers
201     Run Keyword If    ${update_data}==${True}    Get Ovsdb Data
202     FOR    ${switch_name}    IN    @{switches}
203         OvsManager__Enable_Slaves_For_Switch    ${switch_name}    verify_connected=${verify_connected}
204     END
205
206 OvsManager__Enable_Slaves_For_Switch
207     [Arguments]    ${switch}    ${update_data}=${False}    ${verify_connected}=${False}
208     [Documentation]    This is a private keyword, verification is not reliable yet, enables disconnected controllers
209     Run Keyword If    ${update_data}==${True}    Get Ovsdb Data
210     ${bridge}=    Collections.Get From Dictionary    ${ovs_switch_data}    ${switch}
211     ${cntls_dict}=    Collections.Get From Dictionary    ${bridge}    controller
212     ${cntls_items}=    Collections.Get Dictionary Items    ${cntls_dict}
213     FOR    ${cntl_id}    ${cntl_value}    IN    @{cntls_items}
214         Log    ${cntl_id} : ${cntl_value}
215         ${role}=    Collections.Get From Dictionary    ${cntl_value}    role
216         ${connected}=    Collections.Get From Dictionary    ${cntl_value}    is_connected
217         Run Keyword If    ${connected}==${False}    Reconnect Switch To Controller And Verify Connected    ${switch}    ${cntl_id}    verify_connected=${verify_connected}
218     END
219
220 Get Dump Flows Count
221     [Arguments]    ${conn_id}    ${acl_sr_table_id}    ${port_mac}=""
222     [Documentation]    Count the number of dump flows for a given table id
223     ...    and grep with port_mac if provided
224     ${cmd} =    BuiltIn.Set Variable    sudo ovs-ofctl dump-flows br-int -OOpenFlow13 | grep table=${acl_sr_table_id} | grep ${port_mac} | wc -l
225     SSHLibrary.Switch Connection    ${conn_id}
226     ${output} =    Utils.Write Commands Until Expected Prompt    ${cmd}    ${DEFAULT_LINUX_PROMPT_STRICT}
227     @{list} =    String.Split String    ${output}
228     [Return]    ${list[0]}
229
230 Get Packet Count From Table
231     [Arguments]    ${system_ip}    ${br_name}    ${table_no}    ${addtioanal_args}=${EMPTY}
232     [Documentation]    Return packet count for the specific table no.
233     ${flow_output} =    Utils.Run Command On Remote System    ${system_ip}    sudo ovs-ofctl dump-flows -O Openflow13 ${br_name} | grep ${table_no} ${addtioanal_args}
234     @{output} =    String.Split String    ${flow_output}    \r\n
235     ${flow} =    Collections.Get From List    ${output}    0
236     ${packetcountlist} =    String.Get Regexp Matches    ${flow}    n_packets=([0-9]+),    1
237     ${packetcount} =    Collections.Get From List    ${packetcountlist}    0
238     [Return]    ${packetcount}
239
240 Get Packet Count In Table For IP
241     [Arguments]    ${os_compute_ip}    ${table_no}    ${ip_address}    ${additional_args}=${EMPTY}
242     [Documentation]    Capture packetcount for IP in Table
243     ${cmd} =    BuiltIn.Set Variable    sudo ovs-ofctl dump-flows br-int -OOpenFlow13 | grep table=${table_no} | grep ${ip_address} ${additional_args}
244     ${output} =    Utils.Run Command On Remote System And Log    ${os_compute_ip}    ${cmd}
245     @{output_list} =    String.Split String    ${output}    \r\n
246     ${flow} =    Collections.Get From List    ${output_list}    0
247     ${packetcount_list} =    String.Get Regexp Matches    ${flow}    n_packets=([0-9]+)    1
248     ${count} =    Collections.Get From List    ${packetcount_list}    0
249     [Return]    ${count}
250
251 Verify Ovs Version Greater Than Or Equal To
252     [Arguments]    ${ovs_version}    @{nodes}
253     [Documentation]    Get ovs version and verify greater than required version
254     FOR    ${ip}    IN    @{nodes}
255         ${output} =    Utils.Run Command On Remote System    ${ip}    ${SHOW_OVS_VERSION}
256         ${version} =    String.Get Regexp Matches    ${output}    \[0-9].\[0-9]
257         ${result} =    BuiltIn.Convert To Number    ${version[0]}
258         BuiltIn.Should Be True    ${result} >= ${ovs_version}
259     END
260
261 Get OVS Local Ip
262     [Arguments]    ${ip}
263     [Documentation]    Get local ip of compute node ovsdb
264     ${cmd_output} =    Utils.Run Command On Remote System    ${ip}    ${GET_LOCAL_IP}
265     ${localip} =    String.Get Regexp Matches    ${cmd_output}    (\[0-9]+\.\[0-9]+\.\[0-9]+\.\[0-9]+)
266     [Return]    @{localip}[0]