Create OpenStack wrapper for tcpdump
[integration/test.git] / csit / libraries / OpenStackOperations.robot
1 *** Settings ***
2 Documentation     Openstack library. This library is useful for tests to create network, subnet, router and vm instances
3 Library           Collections
4 Library           OperatingSystem
5 Library           RequestsLibrary
6 Library           SSHLibrary
7 Resource          DataModels.robot
8 Resource          DevstackUtils.robot
9 Resource          L2GatewayOperations.robot
10 Resource          OVSDB.robot
11 Resource          SetupUtils.robot
12 Resource          SSHKeywords.robot
13 Resource          Tcpdump.robot
14 Resource          Utils.robot
15 Resource          ../variables/Variables.robot
16 Resource          ../variables/netvirt/Variables.robot
17 Variables         ../variables/netvirt/Modules.py
18
19 *** Keywords ***
20 Get Tenant ID From Security Group
21     [Documentation]    Returns tenant ID by reading it from existing default security-group.
22     ${rc}    ${output}=    Run And Return Rc And Output    openstack security group show default | grep "| tenant_id" | awk '{print $4}'
23     Should Be True    '${rc}' == '0'
24     [Return]    ${output}
25
26 Get Tenant ID From Network
27     [Arguments]    ${network_uuid}
28     [Documentation]    Returns tenant ID by reading it from existing network.
29     ${resp}=    Get_From_Uri    uri=${CONFIG_API}/neutron:neutron/networks/network/${network_uuid}/    accept=${ACCEPT_EMPTY}    session=session
30     ${tenant_id}=    Utils.Extract Value From Content    ${resp}    /network/0/tenant-id    strip
31     [Return]    ${tenant_id}
32
33 Create Network
34     [Arguments]    ${network_name}    ${additional_args}=${EMPTY}    ${verbose}=TRUE
35     [Documentation]    Create Network with neutron request.
36     ${rc}    ${output}=    Run And Return Rc And Output    openstack network create ${network_name} ${additional_args}
37     Log    ${output}
38     Should Be True    '${rc}' == '0'
39     [Return]    ${output}
40
41 Update Network
42     [Arguments]    ${network_name}    ${additional_args}=${EMPTY}
43     [Documentation]    Update Network with neutron request.
44     ${cmd}=    Set Variable If    '${OPENSTACK_BRANCH}'=='stable/newton'    neutron -v net-update ${network_name} ${additional_args}    openstack network set ${network_name} ${additional_args}
45     ${rc}    ${output}=    Run And Return Rc And Output    ${cmd}
46     Log    ${output}
47     Should Be True    '${rc}' == '0'
48     [Return]    ${output}
49
50 Show Network
51     [Arguments]    ${network_name}
52     [Documentation]    Show Network with neutron request.
53     ${rc}    ${output}=    Run And Return Rc And Output    openstack network show ${network_name}
54     Log    ${output}
55     Should Be True    '${rc}' == '0'
56     [Return]    ${output}
57
58 List Networks
59     [Documentation]    List networks and return output with neutron client.
60     ${rc}    ${output}=    Run And Return Rc And Output    openstack network list
61     Log    ${output}
62     Should Be True    '${rc}' == '0'
63     [Return]    ${output}
64
65 List Subnets
66     [Documentation]    List subnets and return output with neutron client.
67     ${rc}    ${output}=    Run And Return Rc And Output    openstack subnet list
68     Log    ${output}
69     Should Be True    '${rc}' == '0'
70     [Return]    ${output}
71
72 Delete Network
73     [Arguments]    ${network_name}
74     [Documentation]    Delete Network with neutron request.
75     ${rc}    ${output}=    Run And Return Rc And Output    openstack network delete ${network_name}
76     Log    ${output}
77     Should Be True    '${rc}' == '0'
78
79 Create SubNet
80     [Arguments]    ${network_name}    ${subnet}    ${range_ip}    ${additional_args}=${EMPTY}
81     [Documentation]    Create SubNet for the Network with neutron request.
82     ${rc}    ${output}=    Run And Return Rc And Output    openstack subnet create --network ${network_name} --subnet-range ${range_ip} ${subnet} ${additional_args}
83     Log    ${output}
84     Should Be True    '${rc}' == '0'
85
86 Update SubNet
87     [Arguments]    ${subnet_name}    ${additional_args}=${EMPTY}
88     [Documentation]    Update subnet with neutron request.
89     ${cmd}=    Set Variable If    '${OPENSTACK_BRANCH}'=='stable/newton'    neutron -v subnet-update ${subnet_name} ${additional_args}    openstack subnet set ${subnet_name} ${additional_args}
90     ${rc}    ${output}=    Run And Return Rc And Output    ${cmd}
91     Log    ${output}
92     Should Be True    '${rc}' == '0'
93     [Return]    ${output}
94
95 Show SubNet
96     [Arguments]    ${subnet_name}
97     [Documentation]    Show subnet with neutron request.
98     ${rc}    ${output}=    Run And Return Rc And Output    openstack subnet show ${subnet_name}
99     Log    ${output}
100     Should Be True    '${rc}' == '0'
101     [Return]    ${output}
102
103 Create Port
104     [Arguments]    ${network_name}    ${port_name}    ${sg}=default    ${additional_args}=${EMPTY}    ${allowed_address_pairs}=${EMPTY}
105     [Documentation]    Create Port with neutron request.
106     # if allowed_address_pairs is not empty we need to create the arguments to pass to the port create command. They are
107     # in a different format with the neutron vs openstack cli.
108     ${address_pair_length}=    Get Length    ${allowed_address_pairs}
109     ${allowed_pairs_argv}=    Set Variable If    '${OPENSTACK_BRANCH}'=='stable/newton' and '${address_pair_length}'=='2'    --allowed-address-pairs type=dict list=true ip_address=@{allowed_address_pairs}[0] ip_address=@{allowed_address_pairs}[1]
110     ${allowed_pairs_argv}=    Set Variable If    '${OPENSTACK_BRANCH}'!='stable/newton' and '${address_pair_length}'=='2'    --allowed-address ip-address=@{allowed_address_pairs}[0] --allowed-address ip-address=@{allowed_address_pairs}[1]    ${allowed_pairs_argv}
111     ${allowed_pairs_argv}=    Set Variable If    '${address_pair_length}'=='0'    ${EMPTY}    ${allowed_pairs_argv}
112     ${cmd}=    Set Variable If    '${OPENSTACK_BRANCH}'=='stable/newton'    neutron -v port-create ${network_name} --name ${port_name} --security-group ${sg} ${additional_args} ${allowed_pairs_argv}    openstack port create --network ${network_name} ${port_name} --security-group ${sg} ${additional_args} ${allowed_pairs_argv}
113     ${rc}    ${output}=    Run And Return Rc And Output    ${cmd}
114     Log    ${output}
115     Should Be True    '${rc}' == '0'
116
117 Update Port
118     [Arguments]    ${port_name}    ${additional_args}=${EMPTY}
119     [Documentation]    Update port with neutron request.
120     ${rc}    ${output}=    Run And Return Rc And Output    openstack port set ${port_name} ${additional_args}
121     Log    ${output}
122     Should Be True    '${rc}' == '0'
123     [Return]    ${output}
124
125 Show Port
126     [Arguments]    ${port_name}
127     [Documentation]    Show port with neutron request.
128     ${rc}    ${output}=    Run And Return Rc And Output    openstack port show ${port_name}
129     Log    ${output}
130     Should Be True    '${rc}' == '0'
131     [Return]    ${output}
132
133 Delete Port
134     [Arguments]    ${port_name}
135     [Documentation]    Delete Port with neutron request.
136     ${rc}    ${output}=    Run And Return Rc And Output    openstack port delete ${port_name}
137     Log    ${output}
138     Should Be True    '${rc}' == '0'
139
140 List Ports
141     [Documentation]    List ports and return output with neutron client.
142     ${rc}    ${output}=    Run And Return Rc And Output    openstack port list
143     Log    ${output}
144     Should Be True    '${rc}' == '0'
145     [Return]    ${output}
146
147 List Nova VMs
148     [Documentation]    List VMs and return output with nova client.
149     ${output}=    OpenStack CLI    openstack server list --all-projects
150     [Return]    ${output}
151
152 Create And Associate Floating IPs
153     [Arguments]    ${external_net}    @{vm_list}
154     [Documentation]    Create and associate floating IPs to VMs with nova request
155     ${ip_list}=    Create List    @{EMPTY}
156     : FOR    ${vm}    IN    @{vm_list}
157     \    ${rc}    ${output}=    Run And Return Rc And Output    openstack floating ip create ${external_net}
158     \    Log    ${output}
159     \    Should Be True    '${rc}' == '0'
160     \    @{ip}    Get Regexp Matches    ${output}    [0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}
161     \    ${ip_length}    Get Length    ${ip}
162     \    Run Keyword If    ${ip_length}>0    Append To List    ${ip_list}    @{ip}[0]
163     \    ...    ELSE    Append To List    ${ip_list}    None
164     \    OpenStack CLI    openstack server add floating ip ${vm} @{ip}[0]
165     [Return]    ${ip_list}
166
167 Delete Floating IP
168     [Arguments]    ${fip}
169     [Documentation]    Delete floating ip with neutron request.
170     ${rc}    ${output}=    Run And Return Rc And Output    openstack floating ip delete ${fip}
171     Log    ${output}
172     Should Be True    '${rc}' == '0'
173
174 Verify Gateway Ips
175     [Documentation]    Verifies the Gateway Ips with dump flow.
176     ${output}=    Write Commands Until Prompt And Log    sudo ovs-ofctl -O OpenFlow13 dump-flows br-int
177     : FOR    ${GatewayIpElement}    IN    @{GATEWAY_IPS}
178     \    Should Contain    ${output}    ${GatewayIpElement}
179
180 Verify Dhcp Ips
181     [Documentation]    Verifies the Dhcp Ips with dump flow.
182     ${output}=    Write Commands Until Prompt And Log    sudo ovs-ofctl -O OpenFlow13 dump-flows br-int
183     : FOR    ${DhcpIpElement}    IN    @{DHCP_IPS}
184     \    Should Contain    ${output}    ${DhcpIpElement}
185
186 Verify No Dhcp Ips
187     [Documentation]    Verifies the Dhcp Ips with dump flow.
188     ${output}=    Write Commands Until Prompt And Log    sudo ovs-ofctl -O OpenFlow13 dump-flows br-int
189     : FOR    ${DhcpIpElement}    IN    @{DHCP_IPS}
190     \    Should Not Contain    ${output}    ${DhcpIpElement}
191
192 Delete SubNet
193     [Arguments]    ${subnet}
194     [Documentation]    Delete SubNet for the Network with neutron request.
195     Log    ${subnet}
196     ${rc}    ${output}=    Run And Return Rc And Output    openstack subnet delete ${subnet}
197     Should Be True    '${rc}' == '0'
198
199 Verify No Gateway Ips
200     [Documentation]    Verifies the Gateway Ips removed with dump flow.
201     ${output}=    Write Commands Until Prompt And Log    sudo ovs-ofctl -O OpenFlow13 dump-flows br-int
202     : FOR    ${GatewayIpElement}    IN    @{GATEWAY_IPS}
203     \    Should Not Contain    ${output}    ${GatewayIpElement}
204
205 Delete Vm Instance
206     [Arguments]    ${vm_name}
207     [Documentation]    Delete Vm instances using instance names.
208     OpenStack CLI    openstack server delete ${vm_name}
209
210 Get Net Id
211     [Arguments]    ${network_name}
212     [Documentation]    Retrieve the net id for the given network name to create specific vm instance
213     ${rc}    ${output}=    Run And Return Rc And Output    openstack network list | grep "${network_name}" | awk '{print $2}'
214     Should Be True    '${rc}' == '0'
215     ${splitted_output}=    Split String    ${output}    ${EMPTY}
216     ${net_id}=    Get from List    ${splitted_output}    0
217     [Return]    ${net_id}
218
219 Get Subnet Id
220     [Arguments]    ${subnet_name}
221     [Documentation]    Retrieve the subnet id for the given subnet name
222     ${rc}    ${output}=    Run And Return Rc And Output    openstack subnet show "${subnet_name}" | grep " id " | awk '{print $4}'
223     Should Be True    '${rc}' == '0'
224     ${splitted_output}=    Split String    ${output}    ${EMPTY}
225     ${subnet_id}=    Get from List    ${splitted_output}    0
226     [Return]    ${subnet_id}
227
228 Get Port Id
229     [Arguments]    ${port_name}
230     [Documentation]    Retrieve the port id for the given port name to attach specific vm instance to a particular port
231     ${rc}    ${output}=    Run And Return Rc And Output    openstack port list | grep "${port_name}" | awk '{print $2}'
232     Should Be True    '${rc}' == '0'
233     ${splitted_output}=    Split String    ${output}    ${EMPTY}
234     ${port_id}=    Get from List    ${splitted_output}    0
235     [Return]    ${port_id}
236
237 Get Router Id
238     [Arguments]    ${router1}
239     [Documentation]    Retrieve the router id for the given router name
240     ${rc}    ${output}=    Run And Return Rc And Output    openstack router list -f table | grep "${router1}" | awk '{print $2}'
241     Should Be True    '${rc}' == '0'
242     ${splitted_output}=    Split String    ${output}    ${EMPTY}
243     ${router_id}=    Get from List    ${splitted_output}    0
244     [Return]    ${router_id}
245
246 Create Vm Instances
247     [Arguments]    ${net_name}    ${vm_instance_names}    ${image}=${EMPTY}    ${flavor}=m1.nano    ${sg}=default    ${min}=1
248     ...    ${max}=1
249     [Documentation]    Create X Vm Instance with the net id of the Netowrk.
250     ${image}    Set Variable If    "${image}"=="${EMPTY}"    ${CIRROS_${OPENSTACK_BRANCH}}    ${image}
251     ${net_id}=    Get Net Id    ${net_name}
252     : FOR    ${VmElement}    IN    @{vm_instance_names}
253     \    OpenStack CLI    openstack server create --image ${image} --flavor ${flavor} --nic net-id=${net_id} ${VmElement} --security-group ${sg} --min ${min} --max ${max}
254
255 Create Vm Instance On Compute Node
256     [Arguments]    ${net_name}    ${vm_name}    ${node_hostname}    ${image}=${EMPTY}    ${flavor}=m1.nano    ${sg}=default
257     [Documentation]    Create a VM instance on a specific compute node.
258     ${image} =    Set Variable If    "${image}"=="${EMPTY}"    ${CIRROS_${OPENSTACK_BRANCH}}    ${image}
259     ${net_id} =    Get Net Id    ${net_name}
260     OpenStack CLI    openstack server create ${vm_name} --image ${image} --flavor ${flavor} --nic net-id=${net_id} --security-group ${sg} --availability-zone nova:${node_hostname}
261
262 Create Vm Instance With Port
263     [Arguments]    ${port_name}    ${vm_instance_name}    ${image}=${EMPTY}    ${flavor}=m1.nano    ${sg}=default
264     [Documentation]    Create One VM instance using given ${port_name} and for given ${compute_node}
265     ${image}    Set Variable If    "${image}"=="${EMPTY}"    ${CIRROS_${OPENSTACK_BRANCH}}    ${image}
266     ${port_id}=    Get Port Id    ${port_name}
267     OpenStack CLI    openstack server create --image ${image} --flavor ${flavor} --nic port-id=${port_id} ${vm_instance_name} --security-group ${sg}
268
269 Create Vm Instance With Ports
270     [Arguments]    ${port_name}    ${port2_name}    ${vm_instance_name}    ${image}=${EMPTY}    ${flavor}=m1.nano    ${sg}=default
271     [Documentation]    Create One VM instance using given ${port_name} and for given ${compute_node}
272     ${image}    Set Variable If    "${image}"=="${EMPTY}"    ${CIRROS_${OPENSTACK_BRANCH}}    ${image}
273     ${port_id}=    Get Port Id    ${port_name}
274     ${port2_id}=    Get Port Id    ${port2_name}
275     OpenStack CLI    openstack server create --image ${image} --flavor ${flavor} --nic port-id=${port_id} --nic port-id=${port2_id} ${vm_instance_name} --security-group ${sg}
276
277 Create Vm Instance With Port On Compute Node
278     [Arguments]    ${port_name}    ${vm_instance_name}    ${node_hostname}    ${image}=${EMPTY}    ${flavor}=m1.nano    ${sg}=default
279     [Documentation]    Create One VM instance using given ${port_name} and for given ${compute_node}
280     ${image}    Set Variable If    "${image}"=="${EMPTY}"    ${CIRROS_${OPENSTACK_BRANCH}}    ${image}
281     ${port_id}=    Get Port Id    ${port_name}
282     OpenStack CLI    openstack server create --image ${image} --flavor ${flavor} --nic port-id=${port_id} --security-group ${sg} --availability-zone nova:${node_hostname} ${vm_instance_name}
283
284 Get Hypervisor Hostname From IP
285     [Arguments]    ${hypervisor_ip}
286     [Documentation]    Returns the hostname found for the given IP address if it's listed in hypervisor list. For debuggability
287     ...    the full listing is logged first, then followed by a grep | cut to focus on the actual hostname to return
288     ${rc}    ${output}    Run And Return Rc And Output    openstack hypervisor list
289     Log    ${output}
290     ${rc}    ${hostname}=    Run And Return Rc And Output    openstack hypervisor list -f value | grep "${hypervisor_ip} " | cut -d" " -f 2
291     Log    ${hostname}
292     Should Be True    '${rc}' == '0'
293     [Return]    ${hostname}
294
295 Create Nano Flavor
296     [Documentation]    Create a nano flavor
297     ${rc}    ${output}=    Run And Return Rc And Output    openstack flavor create m1.nano --id auto --ram 64 --disk 0 --vcpus 1
298     Log    ${output}
299     Should Be True    '${rc}' == '0'
300
301 Verify VM Is ACTIVE
302     [Arguments]    ${vm_name}
303     [Documentation]    Run these commands to check whether the created vm instance is active or not.
304     ${output}=    OpenStack CLI    openstack server show ${vm_name} | grep OS-EXT-STS:vm_state
305     Should Contain    ${output}    active
306
307 Poll VM Is ACTIVE
308     [Arguments]    ${vm_name}    ${retry}=600s    ${retry_interval}=30s
309     [Documentation]    Run these commands to check whether the created vm instance is active or not.
310     Wait Until Keyword Succeeds    ${retry}    ${retry_interval}    Verify VM Is ACTIVE    ${vm_name}
311
312 Collect VM IP Addresses
313     [Arguments]    ${fail_on_none}    @{vm_list}
314     [Documentation]    Using the console-log on the provided ${vm_list} to search for the string "obtained" which
315     ...    correlates to the instance receiving it's IP address via DHCP. Also retrieved is the ip of the nameserver
316     ...    if available in the console-log output. The keyword will also return a list of the learned ips as it
317     ...    finds them in the console log output, and will have "None" for Vms that no ip was found.
318     ${ip_list}    Create List    @{EMPTY}
319     : FOR    ${vm}    IN    @{vm_list}
320     \    ${rc}    ${vm_ip_line}=    Run And Return Rc And Output    openstack console log show ${vm} | grep -i "obtained"
321     \    @{vm_ip}    Get Regexp Matches    ${vm_ip_line}    [0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}
322     \    ${vm_ip_length}    Get Length    ${vm_ip}
323     \    Run Keyword If    ${vm_ip_length}>0    Append To List    ${ip_list}    @{vm_ip}[0]
324     \    ...    ELSE    Append To List    ${ip_list}    None
325     \    ${rc}    ${dhcp_ip_line}=    Run And Return Rc And Output    openstack console log show ${vm} | grep "^nameserver"
326     \    ${dhcp_ip}    Get Regexp Matches    ${dhcp_ip_line}    [0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}
327     \    ${dhcp_ip_length}    Get Length    ${dhcp_ip}
328     \    Run Keyword If    ${dhcp_ip_length}<=0    Append To List    ${dhcp_ip}    None
329     \    ${vm_console_output}=    Run    openstack console log show ${vm}
330     \    Log    ${vm_console_output}
331     ${dhcp_length}    Get Length    ${dhcp_ip}
332     Run Keyword If    '${fail_on_none}' == 'true'    Should Not Contain    ${ip_list}    None
333     Run Keyword If    '${fail_on_none}' == 'true'    Should Not Contain    ${dhcp_ip}    None
334     Should Be True    ${dhcp_length} <= 1
335     Return From Keyword If    ${dhcp_length}==0    ${ip_list}    ${EMPTY}
336     [Return]    ${ip_list}    ${dhcp_ip}
337
338 Get Match
339     [Arguments]    ${text}    ${regexp}    ${index}=0
340     [Documentation]    Wrapper around Get Regexp Matches to return None if not found or the first match if found.
341     @{matches} =    String.Get Regexp Matches    ${text}    ${regexp}
342     ${matches_length} =    Get Length    ${matches}
343     BuiltIn.Set Suite Variable    ${OS_MATCH}    None
344     BuiltIn.Run Keyword If    ${matches_length} > ${index}    BuiltIn.Set Suite Variable    ${OS_MATCH}    @{matches}[${index}]
345     [Return]    ${OS_MATCH}
346
347 Get VM IP
348     [Arguments]    ${fail_on_none}    ${vm}
349     [Documentation]    Get the vm ip address and nameserver by scraping the vm's console log.
350     ...    Get VM IP returns three values: [0] the vm IP, [1] the DHCP IP and [2] the vm console log.
351     ${rc}    ${vm_console_output}=    Run And Return Rc And Output    openstack console log show ${vm}
352     ${vm_ip} =    Set Variable    None
353     ${dhcp_ip} =    Set Variable    None
354     ${match} =    Get Match    ${vm_console_output}    ${REGEX_OBTAINED}
355     ${vm_ip} =    Get Match    ${match}    ${REGEX_IPV4}    0
356     ${match} =    Get Match    ${vm_console_output}    ${REGEX_IPROUTE}
357     ${dhcp_ip} =    Get Match    ${match}    ${REGEX_IPV4}    1
358     BuiltIn.Run Keyword If    '${fail_on_none}' == 'true'    Should Not Contain    ${vm_ip}    None
359     BuiltIn.Run Keyword If    '${fail_on_none}' == 'true'    Should Not Contain    ${dhcp_ip}    None
360     [Return]    ${vm_ip}    ${dhcp_ip}    ${vm_console_output}
361
362 Get VM IPs
363     [Arguments]    @{vms}
364     [Documentation]    Get the instance IP addresses and nameserver address for the list of given vms.
365     ...    First poll for the vm instance to be in the active state, then poll for the vm ip address and nameserver.
366     ...    Get VM IPs returns two things: [0] a list of the ips for the vms passed to this keyword (may contain values
367     ...    of None) and [1] the dhcp ip address found in the last vm checked.
368     ...    TODO: there is a potential issue for a caller that passes in VMs belonging to different networks that
369     ...    may have different dhcp server addresses. Not sure what TODO about that, but noting it here for reference.
370     @{vm_ips}    BuiltIn.Create List    @{EMPTY}
371     : FOR    ${vm}    IN    @{vms}
372     \    Poll VM Is ACTIVE    ${vm}
373     \    ${status}    ${ips_and_console_log}    Run Keyword And Ignore Error    Wait Until Keyword Succeeds    180s    15s
374     \    ...    Get VM IP    true    ${vm}
375     \    # If there is trouble with Get VM IP, the status will be FAIL and the return value will be a string of what went
376     \    # wrong. We need to handle both the PASS and FAIL cases. In the FAIL case we know we wont have access to the
377     \    # console log, as it would not be returned; so we need to grab it again to log it. We also can append 'None' to
378     \    # the vm ip list if status is FAIL.
379     \    Run Keyword If    "${status}" == "PASS"    BuiltIn.Log    ${ips_and_console_log[2]}
380     \    BuiltIn.Run Keyword If    "${status}" == "PASS"    Collections.Append To List    ${vm_ips}    ${ips_and_console_log[0]}
381     \    BuiltIn.Run Keyword If    "${status}" == "FAIL"    Collections.Append To List    ${vm_ips}    None
382     \    ${rc}    ${vm_console_output}=    BuiltIn.Run Keyword If    "${status}" == "FAIL"    Run And Return Rc And Output    openstack console log show ${vm}
383     \    BuiltIn.Run Keyword If    "${status}" == "FAIL"    BuiltIn.Log    ${vm_console_output}
384     Copy DHCP Files From Control Node
385     [Return]    @{vm_ips}    ${ips_and_console_log[1]}
386
387 Collect VM IPv6 SLAAC Addresses
388     [Arguments]    ${fail_on_none}    ${vm_list}    ${network}    ${subnet}
389     [Documentation]    For each VM parse output of "openstack server show" to get its IPv6 address from Neutron DB.
390     ...    Then try to connect to each VM by SSH and execute there "ip -6 a" command. This double-check allows to
391     ...    obtain and compare IP info (Neutron DB vs dnsmasque/ODL DHCP) and to test L2 connectivity as well.
392     ...    Returns an empty list if no IPv6 addresses found or if SSH connection fails.
393     ...    Otherwise, returns a list of IPv6 addresses.
394     ${ipv6_list}    Create List    @{EMPTY}
395     : FOR    ${vm}    IN    @{vm_list}
396     \    ${output}=    OpenStack CLI    openstack server show ${vm} -f shell
397     \    ${pattern}=    Replace String    ${subnet}    ::/64    (:[a-f0-9]{,4}){,4}
398     \    @{vm_ipv6}=    Get Regexp Matches    ${output}    ${pattern}
399     \    ${vm_ip_length}    Get Length    ${vm_ipv6}[0]
400     \    ${ipv6_data_from_vm}=    Run Keyword If    ${vm_ip_length}>0    Execute Command on VM Instance    ${network}    ${vm_ipv6[0]}
401     \    ...    ip -6 a
402     \    @{ipv6}=    Get Regexp Matches    ${ipv6_data_from_vm}    ${pattern}
403     \    ${ipv6_addr_list_length}    Get Length    @{ipv6}
404     \    Run Keyword If    ${ipv6_addr_list_length}>0    Append To List    ${ipv6_list}    ${ipv6[0]}
405     \    ...    ELSE    Append To List    ${ipv6_list}    None
406     [Return]    ${ipv6_list}
407
408 View Vm Console
409     [Arguments]    ${vm_instance_names}
410     [Documentation]    View Console log of the created vm instances using nova show.
411     : FOR    ${VmElement}    IN    @{vm_instance_names}
412     \    OpenStack CLI    openstack server show ${VmElement}
413     \    ${rc}    ${output}=    Run And Return Rc And Output    openstack console log show ${VmElement}
414     \    Log    ${output}
415     \    Should Be True    '${rc}' == '0'
416
417 Ping Vm From DHCP Namespace
418     [Arguments]    ${net_name}    ${vm_ip}
419     [Documentation]    Reach all Vm Instance with the net id of the Netowrk.
420     Get ControlNode Connection
421     ${net_id}=    Get Net Id    ${net_name}
422     ${output}=    Write Commands Until Prompt And Log    sudo ip netns exec qdhcp-${net_id} ping -c 3 ${vm_ip}    20s
423     Should Contain    ${output}    64 bytes
424
425 Ping From DHCP Should Not Succeed
426     [Arguments]    ${net_name}    ${vm_ip}
427     [Documentation]    Should Not Reach Vm Instance with the net id of the Netowrk.
428     Return From Keyword If    "skip_if_${SECURITY_GROUP_MODE}" in @{TEST_TAGS}
429     Get ControlNode Connection
430     ${net_id}=    Get Net Id    ${net_name}
431     ${output}=    Write Commands Until Prompt And Log    sudo ip netns exec qdhcp-${net_id} ping -c 3 ${vm_ip}    20s
432     Should Not Contain    ${output}    64 bytes
433
434 Ping Vm From Control Node
435     [Arguments]    ${vm_floating_ip}    ${additional_args}=${EMPTY}
436     [Documentation]    Ping VM floating IP from control node
437     Get ControlNode Connection
438     ${output}=    Write Commands Until Prompt And Log    ping ${additional_args} -c 3 ${vm_floating_ip}    20s
439     Should Contain    ${output}    64 bytes
440
441 Curl Metadata Server
442     [Documentation]    Ping to the expected destination ip.
443     ${output}=    Write Commands Until Expected Prompt    curl -i http://169.254.169.254    ${OS_SYSTEM_PROMPT}
444     Write Commands Until Prompt    exit
445     Should Contain    ${output}    200
446
447 Close Vm Instance
448     [Documentation]    Exit the vm instance.
449     ${output}=    Write Commands Until Prompt And Log    exit
450
451 Check If Console Is VmInstance
452     [Arguments]    ${console}=cirros
453     [Documentation]    Check if the session has been able to login to the VM instance
454     ${output}=    Write Commands Until Expected Prompt    id    ${OS_SYSTEM_PROMPT}
455     Should Contain    ${output}    ${console}
456
457 Exit From Vm Console
458     [Documentation]    Check if the session has been able to login to the VM instance and exit the instance
459     ${rcode}=    Run Keyword And Return Status    Check If Console Is VmInstance    cirros
460     Run Keyword If    ${rcode}    Write Commands Until Prompt    exit
461
462 Check Ping
463     [Arguments]    ${ip_address}    ${ttl}=64
464     [Documentation]    Run Ping command on the IP available as argument
465     ${ethertype}=    Get Regexp Matches    ${ip_address}    ${IP_REGEX}
466     ${output}=    Run Keyword If    ${ethertype}    Write Commands Until Expected Prompt    ping -t ${ttl} -c 3 ${ip_address}    ${OS_SYSTEM_PROMPT}
467     ...    ELSE    Write Commands Until Expected Prompt    ping6 -t ${ttl} -c 3 ${ip_address}    ${OS_SYSTEM_PROMPT}
468     Should Contain    ${output}    64 bytes
469
470 Check No Ping
471     [Arguments]    ${ip_address}    ${ttl}=64
472     [Documentation]    Run Ping command to the IP given as argument, executing 3 times and expecting NOT to see "64 bytes"
473     ${output}=    Write Commands Until Expected Prompt    ping -t ${ttl} -c 3 ${ip_address}    ${OS_SYSTEM_PROMPT}
474     Should Not Contain    ${output}    64 bytes
475
476 Check Metadata Access
477     [Documentation]    Try curl on the Metadataurl and check if it is okay
478     ${output}=    Write Commands Until Expected Prompt    curl -i http://169.254.169.254    ${OS_SYSTEM_PROMPT}
479     Should Contain    ${output}    200
480
481 Execute Command on VM Instance
482     [Arguments]    ${net_name}    ${vm_ip}    ${cmd}    ${user}=cirros    ${password}=cubswin:)
483     [Documentation]    Login to the vm instance using ssh in the network, executes a command inside the VM and returns the ouput.
484     Get ControlNode Connection
485     ${net_id} =    Get Net Id    ${net_name}
486     ${output} =    Write Commands Until Expected Prompt    sudo ip netns exec qdhcp-${net_id} ssh ${user}@${vm_ip} -o ConnectTimeout=10 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null    password:
487     ${output} =    Write Commands Until Expected Prompt    ${password}    ${OS_SYSTEM_PROMPT}
488     ${rcode} =    Run Keyword And Return Status    Check If Console Is VmInstance
489     ${output} =    Run Keyword If    ${rcode}    Write Commands Until Expected Prompt    ${cmd}    ${OS_SYSTEM_PROMPT}
490     [Teardown]    Exit From Vm Console
491     [Return]    ${output}
492
493 Test Operations From Vm Instance
494     [Arguments]    ${net_name}    ${src_ip}    ${dest_ips}    ${user}=cirros    ${password}=cubswin:)    ${ttl}=64
495     ...    ${ping_should_succeed}=True    ${check_metadata}=True
496     [Documentation]    Login to the vm instance using ssh in the network.
497     Get ControlNode Connection
498     ${net_id}=    Get Net Id    ${net_name}
499     ${output}=    Write Commands Until Expected Prompt    sudo ip netns exec qdhcp-${net_id} ssh -o ConnectTimeout=10 -o StrictHostKeyChecking=no ${user}@${src_ip} -o UserKnownHostsFile=/dev/null    password:
500     ${output}=    Write Commands Until Expected Prompt    ${password}    ${OS_SYSTEM_PROMPT}
501     ${rcode}=    Run Keyword And Return Status    Check If Console Is VmInstance
502     Run Keyword If    ${rcode}    Write Commands Until Expected Prompt    ifconfig    ${OS_SYSTEM_PROMPT}
503     Run Keyword If    ${rcode}    Write Commands Until Expected Prompt    route -n    ${OS_SYSTEM_PROMPT}
504     Run Keyword If    ${rcode}    Write Commands Until Expected Prompt    route -A inet6    ${OS_SYSTEM_PROMPT}
505     Run Keyword If    ${rcode}    Write Commands Until Expected Prompt    arp -an    ${OS_SYSTEM_PROMPT}
506     Run Keyword If    ${rcode}    Write Commands Until Expected Prompt    ip -f inet6 neigh show    ${OS_SYSTEM_PROMPT}
507     : FOR    ${dest_ip}    IN    @{dest_ips}
508     \    ${string_empty}=    Run Keyword And Return Status    Should Be Empty    ${dest_ip}
509     \    Run Keyword If    ${string_empty}    Continue For Loop
510     \    Run Keyword If    ${rcode} and "${ping_should_succeed}" == "True"    Check Ping    ${dest_ip}    ttl=${ttl}
511     \    ...    ELSE    Check No Ping    ${dest_ip}    ttl=${ttl}
512     ${ethertype}=    Get Regexp Matches    ${src_ip}    ${IP_REGEX}
513     Run Keyword If    ${rcode} and "${check_metadata}" and ${ethertype} == "True"    Check Metadata Access
514     [Teardown]    Exit From Vm Console
515
516 Test Netcat Operations From Vm Instance
517     [Arguments]    ${net_name}    ${vm_ip}    ${dest_ip}    ${additional_args}=${EMPTY}    ${port}=12345    ${user}=cirros
518     ...    ${password}=cubswin:)
519     [Documentation]    Use Netcat to test TCP/UDP connections to the controller
520     ${client_data}    Set Variable    Test Client Data
521     ${server_data}    Set Variable    Test Server Data
522     Get ControlNode Connection
523     ${output}=    Write Commands Until Prompt And Log    ( ( echo "${server_data}" | sudo timeout 60 nc -l ${additional_args} ${port} ) & )
524     ${output}=    Write Commands Until Prompt And Log    sudo netstat -nlap | grep ${port}
525     ${nc_output}=    Execute Command on VM Instance    ${net_name}    ${vm_ip}    sudo echo "${client_data}" | nc -v -w 5 ${additional_args} ${dest_ip} ${port}
526     ${output}=    Execute Command on VM Instance    ${net_name}    ${vm_ip}    sudo route -n
527     Log    ${output}
528     ${output}=    Execute Command on VM Instance    ${net_name}    ${vm_ip}    sudo arp -an
529     Log    ${output}
530     Should Match Regexp    ${nc_output}    ${server_data}
531
532 Ping Other Instances
533     [Arguments]    ${list_of_external_dst_ips}
534     [Documentation]    Check reachability with other network's instances.
535     ${rcode}=    Run Keyword And Return Status    Check If Console Is VmInstance
536     : FOR    ${dest_ip}    IN    @{list_of_external_dst_ips}
537     \    Check Ping    ${dest_ip}
538
539 Create Router
540     [Arguments]    ${router_name}
541     [Documentation]    Create Router and Add Interface to the subnets.
542     ${rc}    ${output}=    Run And Return Rc And Output    openstack router create ${router_name}
543     Should Be True    '${rc}' == '0'
544
545 List Routers
546     [Documentation]    List Routers and return output with neutron client.
547     ${rc}    ${output}=    Run And Return Rc And Output    openstack router list -f value
548     Log    ${output}
549     Should Be True    '${rc}' == '0'
550     [Return]    ${output}
551
552 Add Router Interface
553     [Arguments]    ${router_name}    ${interface_name}
554     ${rc}    ${output}=    Run And Return Rc And Output    openstack router add subnet ${router_name} ${interface_name}
555     Should Be True    '${rc}' == '0'
556
557 Show Router Interface
558     [Arguments]    ${router_name}
559     [Documentation]    List Routers interface associated with given Router and return output with neutron client.
560     ${rc}    ${output}=    Run And Return Rc And Output    openstack port list --router ${router_name} -f value
561     Should Be True    '${rc}' == '0'
562     [Return]    ${output}
563
564 Add Router Gateway
565     [Arguments]    ${router_name}    ${external_network_name}
566     ${cmd}=    Set Variable If    '${OPENSTACK_BRANCH}'=='stable/newton'    neutron -v router-gateway-set ${router_name} ${external_network_name}    openstack router set ${router_name} --external-gateway ${external_network_name}
567     ${rc}    ${output}=    Run And Return Rc And Output    ${cmd}
568     Should Be True    '${rc}' == '0'
569
570 Remove Interface
571     [Arguments]    ${router_name}    ${interface_name}
572     [Documentation]    Remove Interface to the subnets.
573     ${rc}    ${output}=    Run And Return Rc And Output    openstack router remove subnet ${router_name} ${interface_name}
574     Should Be True    '${rc}' == '0'
575
576 Remove Gateway
577     [Arguments]    ${router_name}
578     [Documentation]    Remove external gateway from the router.
579     BuiltIn.Log    openstack router unset ${router_name} --external-gateway
580
581 Update Router
582     [Arguments]    ${router_name}    ${cmd}
583     [Documentation]    Update the router with the command. Router name and command should be passed as argument.
584     ${rc}    ${output} =    Run And Return Rc And Output    openstack router set ${router_name} ${cmd}
585     Should Be True    '${rc}' == '0'
586
587 Show Router
588     [Arguments]    ${router_name}    ${options}
589     [Documentation]    Show information of a given router. Router name and optional fields should be sent as arguments.
590     ${rc}    ${output} =    Run And Return Rc And Output    openstack router show ${router_name}
591     Log    ${output}
592
593 Delete Router
594     [Arguments]    ${router_name}
595     [Documentation]    Delete Router and Interface to the subnets.
596     ${rc}    ${output}=    Run And Return Rc And Output    openstack router delete ${router_name}
597     Log    ${output}
598     Should Be True    '${rc}' == '0'
599
600 Get DumpFlows And Ovsconfig
601     [Arguments]    ${conn_id}
602     [Documentation]    Get the OvsConfig and Flow entries from OVS from the Openstack Node
603     SSHLibrary.Switch Connection    ${conn_id}
604     Write Commands Until Expected Prompt    ip -o link    ${DEFAULT_LINUX_PROMPT_STRICT}
605     Write Commands Until Expected Prompt    ip -o addr    ${DEFAULT_LINUX_PROMPT_STRICT}
606     Write Commands Until Expected Prompt    ip route    ${DEFAULT_LINUX_PROMPT_STRICT}
607     Write Commands Until Expected Prompt    arp -an    ${DEFAULT_LINUX_PROMPT_STRICT}
608     ${nslist}=    Write Commands Until Expected Prompt    ip netns list | awk '{print $1}'    ${DEFAULT_LINUX_PROMPT_STRICT}
609     @{lines}    Split To Lines    ${nslist}    end=-1
610     : FOR    ${line}    IN    @{lines}
611     \    Write Commands Until Expected Prompt    sudo ip netns exec ${line} ip -o link    ${DEFAULT_LINUX_PROMPT_STRICT}
612     \    Write Commands Until Expected Prompt    sudo ip netns exec ${line} ip -o addr    ${DEFAULT_LINUX_PROMPT_STRICT}
613     \    Write Commands Until Expected Prompt    sudo ip netns exec ${line} ip route    ${DEFAULT_LINUX_PROMPT_STRICT}
614     Write Commands Until Expected Prompt    sudo ovs-vsctl show    ${DEFAULT_LINUX_PROMPT_STRICT}
615     Write Commands Until Expected Prompt    sudo ovs-vsctl list Open_vSwitch    ${DEFAULT_LINUX_PROMPT_STRICT}
616     Write Commands Until Expected Prompt    sudo ovs-ofctl show br-int -OOpenFlow13    ${DEFAULT_LINUX_PROMPT_STRICT}
617     Write Commands Until Expected Prompt    sudo ovs-ofctl dump-flows br-int -OOpenFlow13    ${DEFAULT_LINUX_PROMPT_STRICT}
618     Write Commands Until Expected Prompt    sudo ovs-ofctl dump-groups br-int -OOpenFlow13    ${DEFAULT_LINUX_PROMPT_STRICT}
619     Write Commands Until Expected Prompt    sudo ovs-ofctl dump-group-stats br-int -OOpenFlow13    ${DEFAULT_LINUX_PROMPT_STRICT}
620
621 Get Karaf Log Type From Test Start
622     [Arguments]    ${ip}    ${test_name}    ${type}    ${user}=${ODL_SYSTEM_USER}    ${password}=${ODL_SYSTEM_PASSWORD}    ${prompt}=${ODL_SYSTEM_PROMPT}
623     ...    ${log_file}=${WORKSPACE}/${BUNDLEFOLDER}/data/log/karaf.log
624     ${cmd}    Set Variable    sed '1,/ROBOT MESSAGE: Starting test ${test_name}/d' ${log_file} | grep '${type}'
625     ${output}    Run Command On Controller    ${ip}    ${cmd}    ${user}    ${password}    ${prompt}
626     [Return]    ${output}
627
628 Get Karaf Log Types From Test Start
629     [Arguments]    ${ip}    ${test_name}    ${types}    ${user}=${ODL_SYSTEM_USER}    ${password}=${ODL_SYSTEM_PASSWORD}    ${prompt}=${ODL_SYSTEM_PROMPT}
630     ...    ${log_file}=${WORKSPACE}/${BUNDLEFOLDER}/data/log/karaf.log
631     : FOR    ${type}    IN    @{types}
632     \    Get Karaf Log Type From Test Start    ${ip}    ${test_name}    ${type}    ${user}    ${password}
633     \    ...    ${prompt}    ${log_file}
634
635 Get Karaf Log Events From Test Start
636     [Arguments]    ${test_name}    ${user}=${ODL_SYSTEM_USER}    ${password}=${ODL_SYSTEM_PASSWORD}    ${prompt}=${ODL_SYSTEM_PROMPT}
637     ${log_types} =    Create List    ERROR    WARN    Exception
638     Run Keyword If    0 < ${NUM_ODL_SYSTEM}    Get Karaf Log Types From Test Start    ${ODL_SYSTEM_IP}    ${test_name}    ${log_types}
639     Run Keyword If    1 < ${NUM_ODL_SYSTEM}    Get Karaf Log Types From Test Start    ${ODL_SYSTEM_2_IP}    ${test_name}    ${log_types}
640     Run Keyword If    2 < ${NUM_ODL_SYSTEM}    Get Karaf Log Types From Test Start    ${ODL_SYSTEM_3_IP}    ${test_name}    ${log_types}
641
642 Get ControlNode Connection
643     SSHLibrary.Switch Connection    ${OS_CNTL_CONN_ID}
644     [Return]    ${OS_CNTL_CONN_ID}
645
646 Get OvsDebugInfo
647     [Documentation]    Get the OvsConfig and Flow entries from all Openstack nodes
648     Run Keyword If    0 < ${NUM_OS_SYSTEM}    Get DumpFlows And Ovsconfig    ${OS_CNTL_CONN_ID}
649     Run Keyword If    1 < ${NUM_OS_SYSTEM}    Get DumpFlows And Ovsconfig    ${OS_CMP1_CONN_ID}
650     Run Keyword If    2 < ${NUM_OS_SYSTEM}    Get DumpFlows And Ovsconfig    ${OS_CMP2_CONN_ID}
651
652 Get Test Teardown Debugs
653     [Arguments]    ${test_name}=${TEST_NAME}
654     Get OvsDebugInfo
655     Run Keyword And Ignore Error    Get Model Dump    ${HA_PROXY_IP}    ${netvirt_data_models}
656     Get Karaf Log Events From Test Start    ${test_name}
657
658 Get Test Teardown Debugs For SFC
659     [Arguments]    ${test_name}=${TEST_NAME}
660     Run Keyword And Ignore Error    Get Model Dump    ${HA_PROXY_IP}    ${netvirt_sfc_data_models}
661
662 Show Debugs
663     [Arguments]    @{vm_indices}
664     [Documentation]    Run these commands for debugging, it can list state of VM instances and ip information in control node
665     Get ControlNode Connection
666     ${output}=    Write Commands Until Prompt And Log    sudo ip netns list
667     : FOR    ${index}    IN    @{vm_indices}
668     \    ${rc}    ${output}=    Run And Return Rc And Output    nova show ${index}
669     \    Log    ${output}
670     List Nova VMs
671     List Routers
672     List Networks
673     List Subnets
674     List Ports
675     List Security Groups
676
677 List Security Groups
678     [Documentation]    Logging keyword to display all security groups using the openstack cli. Assumes openstack
679     ...    credentials are already sourced
680     ${rc}    ${output}=    Run And Return Rc And Output    openstack security group list
681     Log    ${output}
682     Should Be True    '${rc}' == '0'
683     [Return]    ${output}
684
685 Neutron Security Group Show
686     [Arguments]    ${SecurityGroupRuleName}
687     [Documentation]    Displays the neutron security group configurations that belongs to a given neutron security group name
688     ${rc}    ${output}=    Run And Return Rc And Output    openstack security group show ${SecurityGroupRuleName}
689     Log    ${output}
690     Should Be True    '${rc}' == '0'
691     [Return]    ${output}
692
693 Neutron Port Show
694     [Arguments]    ${PortName}
695     [Documentation]    Display the port configuration that belong to a given neutron port
696     ${rc}    ${output}=    Run And Return Rc And Output    openstack port show ${PortName}
697     Log    ${output}
698     Should Be True    '${rc}' == '0'
699     [Return]    ${output}
700
701 Neutron Security Group Create
702     [Arguments]    ${SecurityGroupName}    ${additional_args}=${EMPTY}
703     [Documentation]    Create a security group with specified name ,description & protocol value according to security group template
704     Get ControlNode Connection
705     ${rc}    ${output}=    Run And Return Rc And Output    openstack security group create ${SecurityGroupName} ${additional_args}
706     Log    ${output}
707     Should Be True    '${rc}' == '0'
708     ${sgp_id}=    Should Match Regexp    ${output}    [0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}
709     Log    ${sgp_id}
710     [Return]    ${output}    ${sgp_id}
711
712 Neutron Security Group Update
713     [Arguments]    ${SecurityGroupName}    ${additional_args}=${EMPTY}
714     [Documentation]    Updating security groups
715     ${rc}    ${output}=    Run And Return Rc And Output    openstack security group set ${SecurityGroupName} ${additional_args}
716     Log    ${output}
717     Should Be True    '${rc}' == '0'
718     [Return]    ${output}
719
720 Delete SecurityGroup
721     [Arguments]    ${sg_name}
722     [Documentation]    Delete Security group
723     ${rc}    ${output}=    Run And Return Rc And Output    openstack security group delete ${sg_name}
724     Log    ${output}
725     Should Be True    '${rc}' == '0'
726
727 Neutron Security Group Rule Create
728     [Arguments]    ${Security_group_name}    &{Kwargs}
729     [Documentation]    Creates neutron security rule with Openstack CLI with or without optional params, here security group name is mandatory args, rule with optional params can be created by passing the optional args values ex: direction=${INGRESS_EGRESS}, Then these optional params are catenated with mandatory args, example of usage: "Neutron Security Group Rule Create ${SGP_SSH} direction=${RULE_PARAMS[0]} ethertype=${RULE_PARAMS[1]} ..."
730     Run Keyword If    ${Kwargs}    Log    ${Kwargs}
731     ${description}    Run Keyword If    ${Kwargs}    Pop From Dictionary    ${Kwargs}    description    default=${None}
732     ${direction}    Run Keyword If    ${Kwargs}    Pop From Dictionary    ${Kwargs}    direction    default=${None}
733     ${ethertype}    Run Keyword If    ${Kwargs}    Pop From Dictionary    ${Kwargs}    ethertype    default=${None}
734     ${port_range_max}    Run Keyword If    ${Kwargs}    Pop From Dictionary    ${Kwargs}    port_range_max    default=${None}
735     ${port_range_min}    Run Keyword If    ${Kwargs}    Pop From Dictionary    ${Kwargs}    port_range_min    default=${None}
736     ${protocol}    Run Keyword If    ${Kwargs}    Pop From Dictionary    ${Kwargs}    protocol    default=${None}
737     ${remote_group_id}    Run Keyword If    ${Kwargs}    Pop From Dictionary    ${Kwargs}    remote_group_id    default=${None}
738     ${remote_ip_prefix}    Run Keyword If    ${Kwargs}    Pop From Dictionary    ${Kwargs}    remote_ip_prefix    default=${None}
739     ${cmd}=    Set Variable    openstack security group rule create ${Security_group_name}
740     ${cmd}=    Run Keyword If    '${description}'!='None'    Catenate    ${cmd}    --description ${description}
741     ...    ELSE    Catenate    ${cmd}
742     ${cmd}=    Run Keyword If    '${direction}'!='None'    Catenate    ${cmd}    --${direction}
743     ...    ELSE    Catenate    ${cmd}
744     ${cmd}=    Run Keyword If    '${ethertype}'!='None'    Catenate    ${cmd}    --ethertype ${ethertype}
745     ...    ELSE    Catenate    ${cmd}
746     ${cmd}=    Run Keyword If    '${port_range_min}'!='None' and '${port_range_max}'!='None'    Catenate    ${cmd}    --dst-port ${port_range_min}:${port_range_max}
747     ...    ELSE IF    '${port_range_max}'!='None'    Catenate    ${cmd}    --dst-port ${port_range_max}
748     ...    ELSE IF    '${port_range_min}'!='None'    Catenate    ${cmd}    --dst-port ${port_range_min}
749     ...    ELSE    Catenate    ${cmd}
750     ${cmd}=    Run Keyword If    '${protocol}'!='None'    Catenate    ${cmd}    --protocol ${protocol}
751     ...    ELSE    Catenate    ${cmd}
752     ${cmd}=    Run Keyword If    '${remote_group_id}'!='None'    Catenate    ${cmd}    --remote-group ${remote_group_id}
753     ...    ELSE    Catenate    ${cmd}
754     ${cmd}=    Run Keyword If    '${remote_ip_prefix}'!='None'    Catenate    ${cmd}    --src-ip ${remote_ip_prefix}
755     ...    ELSE    Catenate    ${cmd}
756     ${rc}    ${output}=    Run And Return Rc And Output    ${cmd}
757     ${rule_id}=    Should Match Regexp    ${output}    [0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}
758     Log    ${rule_id}
759     Should Be True    '${rc}' == '0'
760     [Return]    ${output}    ${rule_id}
761
762 Neutron Security Group Rule Create Legacy Cli
763     [Arguments]    ${Security_group_name}    &{Kwargs}
764     [Documentation]    Creates neutron security rule with neutron request with or without optional params, here security group name is mandatory args, rule with optional params can be created by passing the optional args values ex: direction=${INGRESS_EGRESS}, Then these optional params are catenated with mandatory args, example of usage: "Neutron Security Group Rule Create ${SGP_SSH} direction=${RULE_PARAMS[0]} ethertype=${RULE_PARAMS[1]} ..."
765     Run Keyword If    ${Kwargs}    Log    ${Kwargs}
766     ${description}    Run Keyword If    ${Kwargs}    Pop From Dictionary    ${Kwargs}    description    default=${None}
767     ${direction}    Run Keyword If    ${Kwargs}    Pop From Dictionary    ${Kwargs}    direction    default=${None}
768     ${ethertype}    Run Keyword If    ${Kwargs}    Pop From Dictionary    ${Kwargs}    ethertype    default=${None}
769     ${port_range_max}    Run Keyword If    ${Kwargs}    Pop From Dictionary    ${Kwargs}    port_range_max    default=${None}
770     ${port_range_min}    Run Keyword If    ${Kwargs}    Pop From Dictionary    ${Kwargs}    port_range_min    default=${None}
771     ${protocol}    Run Keyword If    ${Kwargs}    Pop From Dictionary    ${Kwargs}    protocol    default=${None}
772     ${remote_group_id}    Run Keyword If    ${Kwargs}    Pop From Dictionary    ${Kwargs}    remote_group_id    default=${None}
773     ${remote_ip_prefix}    Run Keyword If    ${Kwargs}    Pop From Dictionary    ${Kwargs}    remote_ip_prefix    default=${None}
774     ${cmd}=    Set Variable    neutron security-group-rule-create ${Security_group_name}
775     ${cmd}=    Run Keyword If    '${description}'!='None'    Catenate    ${cmd}    --description ${description}
776     ...    ELSE    Catenate    ${cmd}
777     ${cmd}=    Run Keyword If    '${direction}'!='None'    Catenate    ${cmd}    --direction ${direction}
778     ...    ELSE    Catenate    ${cmd}
779     ${cmd}=    Run Keyword If    '${ethertype}'!='None'    Catenate    ${cmd}    --ethertype ${ethertype}
780     ...    ELSE    Catenate    ${cmd}
781     ${cmd}=    Run Keyword If    '${port_range_max}'!='None'    Catenate    ${cmd}    --port_range_max ${port_range_max}
782     ...    ELSE    Catenate    ${cmd}
783     ${cmd}=    Run Keyword If    '${port_range_min}'!='None'    Catenate    ${cmd}    --port_range_min ${port_range_min}
784     ...    ELSE    Catenate    ${cmd}
785     ${cmd}=    Run Keyword If    '${protocol}'!='None'    Catenate    ${cmd}    --protocol ${protocol}
786     ...    ELSE    Catenate    ${cmd}
787     ${cmd}=    Run Keyword If    '${remote_group_id}'!='None'    Catenate    ${cmd}    --remote_group_id ${remote_group_id}
788     ...    ELSE    Catenate    ${cmd}
789     ${cmd}=    Run Keyword If    '${remote_ip_prefix}'!='None'    Catenate    ${cmd}    --remote_ip_prefix ${remote_ip_prefix}
790     ...    ELSE    Catenate    ${cmd}
791     ${rc}    ${output}=    Run And Return Rc And Output    ${cmd}
792     ${rule_id}=    Should Match Regexp    ${output}    [0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}
793     Log    ${rule_id}
794     Should Be True    '${rc}' == '0'
795     [Return]    ${output}    ${rule_id}
796
797 Security Group Create Without Default Security Rules
798     [Arguments]    ${sg_name}    ${additional_args}=${EMPTY}
799     [Documentation]    Create Neutron Security Group with no default rules, using specified name and optional arguments.
800     Neutron Security Group Create    ${sg_name}    ${additional_args}
801     Delete All Security Group Rules    ${sg_name}
802
803 Delete All Security Group Rules
804     [Arguments]    ${sg_name}
805     [Documentation]    Delete all security rules from a specified security group
806     ${rc}    ${sg_rules_output}=    Run And Return Rc And Output    openstack security group rule list ${sg_name} -cID -fvalue
807     Log    ${sg_rules_output}
808     Should Be True    '${rc}' == '0'
809     @{sg_rules}=    Split String    ${sg_rules_output}    \n
810     : FOR    ${rule}    IN    @{sg_rules}
811     \    ${rc}    ${output}=    Run And Return Rc And Output    openstack security group rule delete ${rule}
812     \    Log    ${output}
813     \    Should Be True    '${rc}' == '0'
814
815 Create Allow All SecurityGroup
816     [Arguments]    ${sg_name}    ${ether_type}=IPv4
817     [Documentation]    Allow all TCP/UDP/ICMP packets for this suite
818     Neutron Security Group Create    ${sg_name}
819     Neutron Security Group Rule Create    ${sg_name}    direction=ingress    ethertype=${ether_type}    port_range_max=65535    port_range_min=1    protocol=tcp
820     Neutron Security Group Rule Create    ${sg_name}    direction=egress    ethertype=${ether_type}    port_range_max=65535    port_range_min=1    protocol=tcp
821     Neutron Security Group Rule Create    ${sg_name}    direction=ingress    ethertype=${ether_type}    protocol=icmp
822     Neutron Security Group Rule Create    ${sg_name}    direction=egress    ethertype=${ether_type}    protocol=icmp
823     Neutron Security Group Rule Create    ${sg_name}    direction=ingress    ethertype=${ether_type}    port_range_max=65535    port_range_min=1    protocol=udp
824     Neutron Security Group Rule Create    ${sg_name}    direction=egress    ethertype=${ether_type}    port_range_max=65535    port_range_min=1    protocol=udp
825
826 Create Neutron Port With Additional Params
827     [Arguments]    ${network_name}    ${port_name}    ${additional_args}=${EMPTY}
828     [Documentation]    Create Port With given additional parameters
829     ${rc}    ${output}=    Run And Return Rc And Output    neutron -v port-create ${network_name} --name ${port_name} ${additional_args}
830     Log    ${output}
831     Should Be True    '${rc}' == '0'
832     ${port_id}=    Should Match Regexp    ${OUTPUT}    [0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}
833     Log    ${port_id}
834     [Return]    ${OUTPUT}    ${port_id}
835
836 Get Ports MacAddr
837     [Arguments]    ${portName_list}
838     [Documentation]    Retrieve the port MacAddr for the given list of port name and return the MAC address list.
839     ${MacAddr-list}    Create List
840     : FOR    ${portName}    IN    @{portName_list}
841     \    ${macAddr}=    OpenStackOperations.Get Port Mac    ${portName}
842     \    Append To List    ${MacAddr-list}    ${macAddr}
843     [Return]    ${MacAddr-list}
844
845 Get Port Ip
846     [Arguments]    ${port_name}
847     [Documentation]    Keyword would return the IP of the ${port_name} received.
848     ${rc}    ${output}=    Run And Return Rc And Output    openstack port list | grep "${port_name}" | awk -F\\' '{print $2}'
849     ${splitted_output}=    Split String    ${output}    ${EMPTY}
850     ${port_ip}=    Get from List    ${splitted_output}    0
851     Should Be True    '${rc}' == '0'
852     [Return]    ${port_ip}
853
854 Get Port Mac
855     [Arguments]    ${port_name}
856     [Documentation]    Keyword would return the MAC ID of the ${port_name} received.
857     ${rc}    ${output}=    Run And Return Rc And Output    openstack port show ${port_name} | grep mac_address | awk '{print $4}'
858     ${splitted_output}=    Split String    ${output}    ${EMPTY}
859     ${port_mac}=    Get from List    ${splitted_output}    0
860     Should Be True    '${rc}' == '0'
861     [Return]    ${port_mac}
862
863 Create L2Gateway
864     [Arguments]    ${bridge_name}    ${intf_name}    ${gw_name}
865     [Documentation]    Keyword to create an L2 Gateway ${gw_name} for bridge ${bridge_name} connected to interface ${intf_name} (Using Neutron CLI).
866     ${rc}    ${l2gw_output}=    Run And Return Rc And Output    ${L2GW_CREATE} name=${bridge_name},interface_names=${intf_name} ${gw_name}
867     Log    ${l2gw_output}
868     [Return]    ${l2gw_output}
869
870 Create L2Gateway Connection
871     [Arguments]    ${gw_name}    ${net_name}
872     [Documentation]    Keyword would create a new L2 Gateway Connection for ${gw_name} to ${net_name} (Using Neutron CLI).
873     ${rc}    ${l2gw_output}=    Run And Return Rc And Output    ${L2GW_CONN_CREATE} ${gw_name} ${net_name}
874     Log    ${l2gw_output}
875     Should Be True    '${rc}' == '0'
876     [Return]    ${l2gw_output}
877
878 Get All L2Gateway
879     [Documentation]    Keyword to return all the L2 Gateways available (Using Neutron CLI).
880     ${rc}    ${output}=    Run And Return Rc And Output    ${L2GW_GET_YAML}
881     Should Be True    '${rc}' == '0'
882     [Return]    ${output}
883
884 Get All L2Gateway Connection
885     [Documentation]    Keyword to return all the L2 Gateway connections available (Using Neutron CLI).
886     ${rc}    ${output}=    Run And Return Rc And Output    ${L2GW_GET_CONN_YAML}
887     Should Be True    '${rc}' == '0'
888     [Return]    ${output}
889
890 Get L2Gateway
891     [Arguments]    ${gw_id}
892     [Documentation]    Keyword to check if the ${gw_id} is available in the L2 Gateway list (Using Neutron CLI).
893     ${rc}    ${output}=    Run And Return Rc And Output    ${L2GW_SHOW} ${gw_id}
894     Log    ${output}
895     Should Be True    '${rc}' == '0'
896     [Return]    ${output}
897
898 Get L2gw Id
899     [Arguments]    ${l2gw_name}
900     [Documentation]    Keyword to retrieve the L2 Gateway ID for the ${l2gw_name} (Using Neutron CLI).
901     ${rc}    ${output}=    Run And Return Rc And Output    ${L2GW_GET} | grep "${l2gw_name}" | awk '{print $2}'
902     Log    ${output}
903     Should Be True    '${rc}' == '0'
904     ${splitted_output}=    Split String    ${output}    ${EMPTY}
905     ${l2gw_id}=    Get from List    ${splitted_output}    0
906     [Return]    ${l2gw_id}
907
908 Get L2gw Connection Id
909     [Arguments]    ${l2gw_name}
910     [Documentation]    Keyword to retrieve the L2 Gateway Connection ID for the ${l2gw_name} (Using Neutron CLI).
911     ${l2gw_id}=    OpenStackOperations.Get L2gw Id    ${l2gw_name}
912     ${rc}    ${output}=    Run And Return Rc And Output    ${L2GW_GET_CONN} | grep "${l2gw_id}" | awk '{print $2}'
913     Should Be True    '${rc}' == '0'
914     ${splitted_output}=    Split String    ${output}    ${EMPTY}
915     ${splitted_output}=    Split String    ${output}    ${EMPTY}
916     ${l2gw_conn_id}=    Get from List    ${splitted_output}    0
917     [Return]    ${l2gw_conn_id}
918
919 Neutron Port List Rest
920     [Documentation]    Keyword to get all ports details in Neutron (Using REST).
921     ${resp} =    RequestsLibrary.Get Request    session    ${PORT_URL}
922     Log    ${resp.content}
923     Should Be Equal As Strings    ${resp.status_code}    200
924     [Return]    ${resp.content}
925
926 Get Neutron Port Rest
927     [Arguments]    ${port_id}
928     [Documentation]    Keyword to get the specific port details in Neutron (Using REST).
929     ${resp} =    RequestsLibrary.Get Request    session    ${CONFIG_API}/${GET_PORT_URL}/${port_id}
930     Log    ${resp.content}
931     Should Be Equal As Strings    ${resp.status_code}    200
932     [Return]    ${resp.content}
933
934 Update Port Rest
935     [Arguments]    ${port_id}    ${json_data}
936     [Documentation]    Keyword to update ${port_id} with json data received in ${json_data} (Using REST).
937     Log    ${json_data}
938     ${resp} =    RequestsLibrary.Put Request    session    ${CONFIG_API}/${GET_PORT_URL}/${port_id}    ${json_data}
939     Log    ${resp.content}
940     Should Be Equal As Strings    ${resp.status_code}    200
941     [Return]    ${resp.content}
942
943 Create And Configure Security Group
944     [Arguments]    ${sg-name}
945     [Documentation]    Create Security Group with given name, and default allow rules for TCP/UDP/ICMP protocols.
946     Neutron Security Group Create    ${sg-name}
947     Neutron Security Group Rule Create    ${sg-name}    direction=ingress    port_range_max=65535    port_range_min=1    protocol=tcp    remote_ip_prefix=0.0.0.0/0
948     Neutron Security Group Rule Create    ${sg-name}    direction=egress    port_range_max=65535    port_range_min=1    protocol=tcp    remote_ip_prefix=0.0.0.0/0
949     Neutron Security Group Rule Create    ${sg-name}    direction=ingress    protocol=icmp    remote_ip_prefix=0.0.0.0/0
950     Neutron Security Group Rule Create    ${sg-name}    direction=egress    protocol=icmp    remote_ip_prefix=0.0.0.0/0
951     Neutron Security Group Rule Create    ${sg-name}    direction=ingress    port_range_max=65535    port_range_min=1    protocol=udp    remote_ip_prefix=0.0.0.0/0
952     Neutron Security Group Rule Create    ${sg-name}    direction=egress    port_range_max=65535    port_range_min=1    protocol=udp    remote_ip_prefix=0.0.0.0/0
953
954 Add Security Group To VM
955     [Arguments]    ${vm}    ${sg}
956     [Documentation]    Add the security group provided to the given VM.
957     ${output}=    OpenStack CLI    openstack server add security group ${vm} ${sg}
958
959 Remove Security Group From VM
960     [Arguments]    ${vm}    ${sg}
961     [Documentation]    Remove the security group provided to the given VM.
962     Get ControlNode Connection
963     OpenStack CLI    openstack server remove security group ${vm} ${sg}
964
965 Create SFC Flow Classifier
966     [Arguments]    ${name}    ${src_ip}    ${dest_ip}    ${protocol}    ${dest_port}    ${neutron_src_port}
967     [Documentation]    Create a flow classifier for SFC
968     ${rc}    ${output}=    Run And Return Rc And Output    openstack sfc flow classifier create --ethertype IPv4 --source-ip-prefix ${src_ip}/32 --destination-ip-prefix ${dest_ip}/32 --protocol ${protocol} --destination-port ${dest_port}:${dest_port} --logical-source-port ${neutron_src_port} ${name}
969     Log    ${output}
970     Should Be True    '${rc}' == '0'
971     Should Contain    ${output}    ${name}
972     [Return]    ${output}
973
974 Delete SFC Flow Classifier
975     [Arguments]    ${name}
976     [Documentation]    Delete a SFC flow classifier
977     Get ControlNode Connection
978     ${rc}    ${output}=    Run And Return Rc And Output    openstack sfc flow classifier delete ${name}
979     Log    ${output}
980     Should Be True    '${rc}' == '0'
981     [Return]    ${output}
982
983 Create SFC Port Pair
984     [Arguments]    ${name}    ${port_in}    ${port_out}
985     [Documentation]    Creates a neutron port pair for SFC
986     Get ControlNode Connection
987     ${rc}    ${output}=    Run And Return Rc And Output    openstack sfc port pair create --ingress=${port_in} --egress=${port_out} ${name}
988     Log    ${output}
989     Should Be True    '${rc}' == '0'
990     Should Contain    ${output}    ${name}
991     [Return]    ${output}
992
993 Delete SFC Port Pair
994     [Arguments]    ${name}
995     [Documentation]    Delete a SFC port pair
996     ${rc}    ${output}=    Run And Return Rc And Output    openstack sfc port pair delete ${name}
997     Log    ${output}
998     Should Be True    '${rc}' == '0'
999     [Return]    ${output}
1000
1001 Create SFC Port Pair Group
1002     [Arguments]    ${name}    ${port_pair}
1003     [Documentation]    Creates a port pair group with a single port pair for SFC
1004     ${rc}    ${output}=    Run And Return Rc And Output    openstack sfc port pair group create --port-pair ${port_pair} ${name}
1005     Log    ${output}
1006     Should Be True    '${rc}' == '0'
1007     Should Contain    ${output}    ${name}
1008     [Return]    ${output}
1009
1010 Create SFC Port Pair Group With Two Pairs
1011     [Arguments]    ${name}    ${port_pair1}    ${port_pair2}
1012     [Documentation]    Creates a port pair group with two port pairs for SFC
1013     ${rc}    ${output}=    Run And Return Rc And Output    openstack sfc port pair group create --port-pair ${port_pair1} --port-pair ${port_pair2} ${name}
1014     Log    ${output}
1015     Should Be True    '${rc}' == '0'
1016     Should Contain    ${output}    ${name}
1017     [Return]    ${output}
1018
1019 Delete SFC Port Pair Group
1020     [Arguments]    ${name}
1021     [Documentation]    Delete a SFC port pair group
1022     Get ControlNode Connection
1023     ${rc}    ${output}=    Run And Return Rc And Output    openstack sfc port pair group delete ${name}
1024     Log    ${output}
1025     Should Be True    '${rc}' == '0'
1026     [Return]    ${output}
1027
1028 Create SFC Port Chain
1029     [Arguments]    ${name}    ${pg1}    ${pg2}    ${fc}
1030     [Documentation]    Creates a port pair chain with two port groups and a singel classifier.
1031     ${rc}    ${output}=    Run And Return Rc And Output    openstack sfc port chain create --port-pair-group ${pg1} --port-pair-group ${pg2} --flow-classifier ${fc} ${name}
1032     Log    ${output}
1033     Should Be True    '${rc}' == '0'
1034     Should Contain    ${output}    ${name}
1035     [Return]    ${output}
1036
1037 Delete SFC Port Chain
1038     [Arguments]    ${name}
1039     [Documentation]    Delete a SFC port chain
1040     ${rc}    ${output}=    Run And Return Rc And Output    openstack sfc port chain delete ${name}
1041     Log    ${output}
1042     Should Be True    '${rc}' == '0'
1043     [Return]    ${output}
1044
1045 Reboot Nova VM
1046     [Arguments]    ${vm_name}
1047     [Documentation]    Reboot NOVA VM
1048     OpenStack CLI    openstack server reboot --wait ${vm_name}
1049     Wait Until Keyword Succeeds    35s    10s    Verify VM Is ACTIVE    ${vm_name}
1050
1051 Remove RSA Key From KnownHosts
1052     [Arguments]    ${vm_ip}
1053     [Documentation]    Remove RSA
1054     Get ControlNode Connection
1055     ${output}=    Write Commands Until Prompt And Log    sudo cat /root/.ssh/known_hosts    30s
1056     ${output}=    Write Commands Until Prompt And Log    sudo ssh-keygen -f "/root/.ssh/known_hosts" -R ${vm_ip}    30s
1057     ${output}=    Write Commands Until Prompt    sudo cat "/root/.ssh/known_hosts"    30s
1058
1059 Wait For Routes To Propogate
1060     [Arguments]    ${networks}    ${subnets}
1061     [Documentation]    Check propagated routes
1062     Get ControlNode Connection
1063     : FOR    ${INDEX}    IN RANGE    0    1
1064     \    ${net_id}=    Get Net Id    @{networks}[${INDEX}]
1065     \    ${is_ipv6}=    Get Regexp Matches    @{subnets}[${INDEX}]    ${IP6_REGEX}
1066     \    ${length}=    Get Length    ${is_ipv6}
1067     \    ${cmd}=    Set Variable If    ${length} == 0    ip route    ip -6 route
1068     \    ${output}=    Write Commands Until Expected Prompt    sudo ip netns exec qdhcp-${net_id} ${cmd}    ]>
1069     \    Should Contain    ${output}    @{subnets}[${INDEX}]
1070
1071 Neutron Cleanup
1072     [Arguments]    ${vms}=@{EMPTY}    ${networks}=@{EMPTY}    ${subnets}=@{EMPTY}    ${ports}=@{EMPTY}    ${sgs}=@{EMPTY}
1073     : FOR    ${vm}    IN    @{vms}
1074     \    BuiltIn.Run Keyword And Ignore Error    Delete Vm Instance    ${vm}
1075     : FOR    ${port}    IN    @{ports}
1076     \    BuiltIn.Run Keyword And Ignore Error    Delete Port    ${port}
1077     : FOR    ${subnet}    IN    @{subnets}
1078     \    BuiltIn.Run Keyword And Ignore Error    Delete SubNet    ${subnet}
1079     : FOR    ${network}    IN    @{networks}
1080     \    BuiltIn.Run Keyword And Ignore Error    Delete Network    ${network}
1081     : FOR    ${sg}    IN    @{sgs}
1082     \    BuiltIn.Run Keyword And Ignore Error    Delete SecurityGroup    ${sg}
1083
1084 OpenStack List All
1085     [Documentation]    Get a list of different OpenStack resources that might be in use.
1086     @{modules} =    BuiltIn.Create List    floating ip    server    router    port    network
1087     ...    subnet    security group    security group rule
1088     : FOR    ${module}    IN    @{modules}
1089     \    OpenStack CLI    openstack ${module} list
1090
1091 OpenStack CLI Get List
1092     [Arguments]    ${cmd}
1093     [Documentation]    Return a json list from the output of an OpenStack command.
1094     ${json} =    OpenStack CLI    ${cmd}
1095     @{list} =    RequestsLibrary.To Json    ${json}
1096     BuiltIn.Log    ${list}
1097     [Return]    @{list}
1098
1099 OpenStack CLI
1100     [Arguments]    ${cmd}
1101     [Documentation]    Run the given OpenStack ${cmd}.
1102     ${rc}    ${output} =    OperatingSystem.Run And Return Rc And Output    ${cmd}
1103     BuiltIn.Log    ${output}
1104     Should Be True    '${rc}' == '0'
1105     [Return]    ${output}
1106
1107 OpenStack Cleanup All
1108     [Documentation]    Cleanup all Openstack resources with best effort. The keyword will query for all resources
1109     ...    in use and then attempt to delete them. Errors are ignored to allow the cleanup to continue.
1110     @{fips} =    OpenStack CLI Get List    openstack floating ip list -f json
1111     : FOR    ${fip}    IN    @{fips}
1112     \    BuiltIn.Run Keyword And Ignore Error    Delete Floating IP    ${fip['ID']}
1113     @{vms} =    OpenStack CLI Get List    openstack server list -f json
1114     : FOR    ${vm}    IN    @{vms}
1115     \    BuiltIn.Run Keyword And Ignore Error    Delete Vm Instance    ${vm['ID']}
1116     @{routers} =    OpenStack CLI Get List    openstack router list -f json
1117     : FOR    ${router}    IN    @{routers}
1118     \    BuiltIn.Run Keyword And Ignore Error    Cleanup Router    ${router['ID']}
1119     @{ports} =    OpenStack CLI Get List    openstack port list -f json
1120     : FOR    ${port}    IN    @{ports}
1121     \    BuiltIn.Run Keyword And Ignore Error    Delete Port    ${port['ID']}
1122     @{networks} =    OpenStack CLI Get List    openstack network list -f json
1123     : FOR    ${network}    IN    @{networks}
1124     \    BuiltIn.Run Keyword And Ignore Error    Delete Subnet    ${network['Subnets']}
1125     \    BuiltIn.Run Keyword And Ignore Error    Delete Network    ${network['ID']}
1126     @{security_groups} =    OpenStack CLI Get List    openstack security group list -f json
1127     : FOR    ${security_group}    IN    @{security_groups}
1128     \    BuiltIn.Run Keyword If    "${security_group['Name']}" != "default"    BuiltIn.Run Keyword And Ignore Error    Delete SecurityGroup    ${security_group['ID']}
1129     OpenStack List All
1130
1131 Cleanup Router
1132     [Arguments]    ${id}
1133     [Documentation]    Delete a router, but first remove any interfaces or gateways so that the delete will be successful.
1134     @{ports} =    OpenStack CLI Get List    openstack port list --router ${id} -f json --long
1135     : FOR    ${port}    IN    @{ports}
1136     \    ${subnet_id} =    Get Match    ${port['Fixed IP Addresses']}    [0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}    0
1137     \    BuiltIn.Run Keyword If    "${port['Device Owner']}" == "network:router_gateway"    BuiltIn.Run Keyword And Ignore Error    Remove Gateway    ${id}
1138     \    BuiltIn.Run Keyword If    "${port['Device Owner']}" == "network:router_interface"    BuiltIn.Run Keyword And Ignore Error    Remove Interface    ${id}    ${subnet_id}
1139     BuiltIn.Run Keyword And Ignore Error    Delete Router    ${id}
1140
1141 OpenStack Suite Setup
1142     [Documentation]    Wrapper teardown keyword that can be used in any suite running in an openstack environement
1143     SetupUtils.Setup_Utils_For_Setup_And_Teardown
1144     Run Keyword If    "${PRE_CLEAN_OPENSTACK_ALL}"=="True"    OpenStack Cleanup All
1145     DevstackUtils.Devstack Suite Setup
1146     Add OVS Logging On All OpenStack Nodes
1147
1148 OpenStack Suite Teardown
1149     [Documentation]    Wrapper teardown keyword that can be used in any suite running in an openstack environement
1150     ...    to clean up all openstack resources. For example, all instances, networks, ports, etc will be listed and
1151     ...    and deleted. As other global cleanup tasks are needed, they can be added here and the suites will all
1152     ...    benefit automatically.
1153     OpenStack Cleanup All
1154     SSHLibrary.Close All Connections
1155
1156 Copy DHCP Files From Control Node
1157     [Documentation]    Copy the current DHCP files to the robot vm. The keyword must be called
1158     ...    after the subnet(s) are created and before the subnet(s) are deleted.
1159     ${suite_} =    BuiltIn.Evaluate    """${SUITE_NAME}""".replace(" ","_").replace("/","_").replace(".","_")
1160     ${dstdir} =    Set Variable    /tmp/qdhcp/${suite_}
1161     OperatingSystem.Create Directory    ${dstdir}
1162     Get ControlNode Connection
1163     BuiltIn.Run Keyword And Ignore Error    SSHLibrary.Get Directory    /opt/stack/data/neutron/dhcp    ${dstdir}    recursive=True
1164
1165 Is Feature Installed
1166     [Arguments]    ${features}=none
1167     : FOR    ${feature}    IN    ${features}
1168     \    ${status}    ${output}    Run Keyword And Ignore Error    Builtin.Should Contain    ${CONTROLLERFEATURES}    ${feature}
1169     \    Return From Keyword If    "${status}" == "PASS"    True
1170     [Return]    False
1171
1172 Add OVS Logging On All OpenStack Nodes
1173     [Documentation]    Add higher levels of OVS logging to all the OpenStack nodes
1174     Run Keyword If    0 < ${NUM_OS_SYSTEM}    OVSDB.Add OVS Logging    ${OS_CNTL_CONN_ID}
1175     Run Keyword If    1 < ${NUM_OS_SYSTEM}    OVSDB.Add OVS Logging    ${OS_CMP1_CONN_ID}
1176     Run Keyword If    2 < ${NUM_OS_SYSTEM}    OVSDB.Add OVS Logging    ${OS_CMP2_CONN_ID}
1177
1178 Reset OVS Logging On All OpenStack Nodes
1179     [Documentation]    Reset the OVS logging to all the OpenStack nodes
1180     Run Keyword If    0 < ${NUM_OS_SYSTEM}    OVSDB.Reset OVS Logging    ${OS_CNTL_CONN_ID}
1181     Run Keyword If    1 < ${NUM_OS_SYSTEM}    OVSDB.Reset OVS Logging    ${OS_CMP1_CONN_ID}
1182     Run Keyword If    2 < ${NUM_OS_SYSTEM}    OVSDB.Reset OVS Logging    ${OS_CMP2_CONN_ID}
1183
1184 Start Packet Capture On Nodes
1185     [Arguments]    ${tag}    ${filter}    @{ips}
1186     [Documentation]    Wrapper keyword around the TcpDump packet capture that is catered to the Openstack setup.
1187     ...    The caller must pass the three arguments with a variable number of ips at the end,
1188     ...    but ${EMPTY} can be used for the tag and filter.
1189     ${suite_} =    BuiltIn.Evaluate    """${SUITE_NAME}""".replace(" ","_").replace("/","_").replace(".","_")
1190     ${tag_} =    BuiltIn.Catenate    SEPARATOR=__    ${tag}    ${suite_}
1191     @{capture_conn_ids} =    Tcpdump.Start Packet Capture on Nodes    tag=${tag_}    filter=${filter}    ips=${ips}
1192     BuiltIn.Set Suite Variable    @{capture_conn_ids}
1193
1194 Stop Packet Capture On Nodes
1195     Tcpdump.Stop Packet Capture on Nodes    ${capture_conn_ids}