6d4c9598f1ab765074a5da34b02ef9e0729aea53
[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 show "${router1}" |awk '/ id / {print $4}'
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     OpenStack CLI    openstack hypervisor list
289     ${hostname}=    OpenStack CLI    openstack hypervisor list -f value | grep "${hypervisor_ip} " | cut -d" " -f 2
290     [Return]    ${hostname}
291
292 Create Nano Flavor
293     [Documentation]    Create a nano flavor
294     ${rc}    ${output}=    Run And Return Rc And Output    openstack flavor create m1.nano --id auto --ram 64 --disk 0 --vcpus 1
295     Log    ${output}
296     Should Be True    '${rc}' == '0'
297
298 Verify VM Is ACTIVE
299     [Arguments]    ${vm_name}
300     [Documentation]    Run these commands to check whether the created vm instance is active or not.
301     ${output}=    OpenStack CLI    openstack server show ${vm_name} | grep OS-EXT-STS:vm_state
302     Should Contain    ${output}    active
303
304 Poll VM Is ACTIVE
305     [Arguments]    ${vm_name}    ${retry}=600s    ${retry_interval}=30s
306     [Documentation]    Run these commands to check whether the created vm instance is active or not.
307     Wait Until Keyword Succeeds    ${retry}    ${retry_interval}    Verify VM Is ACTIVE    ${vm_name}
308
309 Get Match
310     [Arguments]    ${text}    ${regexp}    ${index}=0
311     [Documentation]    Wrapper around Get Regexp Matches to return None if not found or the first match if found.
312     @{matches} =    String.Get Regexp Matches    ${text}    ${regexp}
313     ${matches_length} =    Get Length    ${matches}
314     BuiltIn.Set Suite Variable    ${OS_MATCH}    None
315     BuiltIn.Run Keyword If    ${matches_length} > ${index}    BuiltIn.Set Suite Variable    ${OS_MATCH}    @{matches}[${index}]
316     [Return]    ${OS_MATCH}
317
318 Get VM IP
319     [Arguments]    ${fail_on_none}    ${vm}
320     [Documentation]    Get the vm ip address and nameserver by scraping the vm's console log.
321     ...    Get VM IP returns three values: [0] the vm IP, [1] the DHCP IP and [2] the vm console log.
322     ${vm_console_output}=    OpenStack CLI    openstack console log show ${vm}    log_output=False
323     ${vm_ip} =    Set Variable    None
324     ${dhcp_ip} =    Set Variable    None
325     ${match} =    Get Match    ${vm_console_output}    ${REGEX_OBTAINED}
326     ${vm_ip} =    Get Match    ${match}    ${REGEX_IPV4}    0
327     ${match} =    Get Match    ${vm_console_output}    ${REGEX_IPROUTE}
328     ${dhcp_ip} =    Get Match    ${match}    ${REGEX_IPV4}    1
329     BuiltIn.Run Keyword If    '${fail_on_none}' == 'true'    Should Not Contain    ${vm_ip}    None
330     BuiltIn.Run Keyword If    '${fail_on_none}' == 'true'    Should Not Contain    ${dhcp_ip}    None
331     [Return]    ${vm_ip}    ${dhcp_ip}    ${vm_console_output}
332
333 Get VM IPs
334     [Arguments]    @{vms}
335     [Documentation]    Get the instance IP addresses and nameserver address for the list of given vms.
336     ...    First poll for the vm instance to be in the active state, then poll for the vm ip address and nameserver.
337     ...    Get VM IPs returns two things: [0] a list of the ips for the vms passed to this keyword (may contain values
338     ...    of None) and [1] the dhcp ip address found in the last vm checked.
339     ...    TODO: there is a potential issue for a caller that passes in VMs belonging to different networks that
340     ...    may have different dhcp server addresses. Not sure what TODO about that, but noting it here for reference.
341     @{vm_ips}    BuiltIn.Create List    @{EMPTY}
342     : FOR    ${vm}    IN    @{vms}
343     \    Poll VM Is ACTIVE    ${vm}
344     \    ${status}    ${ips_and_console_log}    Run Keyword And Ignore Error    Wait Until Keyword Succeeds    180s    15s
345     \    ...    Get VM IP    true    ${vm}
346     \    # If there is trouble with Get VM IP, the status will be FAIL and the return value will be a string of what went
347     \    # wrong. We need to handle both the PASS and FAIL cases. In the FAIL case we know we wont have access to the
348     \    # console log, as it would not be returned; so we need to grab it again to log it. We also can append 'None' to
349     \    # the vm ip list if status is FAIL.
350     \    Run Keyword If    "${status}" == "PASS"    BuiltIn.Log    ${ips_and_console_log[2]}
351     \    BuiltIn.Run Keyword If    "${status}" == "PASS"    Collections.Append To List    ${vm_ips}    ${ips_and_console_log[0]}
352     \    BuiltIn.Run Keyword If    "${status}" == "FAIL"    Collections.Append To List    ${vm_ips}    None
353     \    ${vm_console_output}=    BuiltIn.Run Keyword If    "${status}" == "FAIL"    OpenStack CLI    openstack console log show ${vm}
354     \    BuiltIn.Run Keyword If    "${status}" == "FAIL"    BuiltIn.Log    ${vm_console_output}
355     Copy DHCP Files From Control Node
356     [Return]    @{vm_ips}    ${ips_and_console_log[1]}
357
358 Collect VM IPv6 SLAAC Addresses
359     [Arguments]    ${fail_on_none}    ${vm_list}    ${network}    ${subnet}
360     [Documentation]    For each VM parse output of "openstack server show" to get its IPv6 address from Neutron DB.
361     ...    Then try to connect to each VM by SSH and execute there "ip -6 a" command. This double-check allows to
362     ...    obtain and compare IP info (Neutron DB vs dnsmasque/ODL DHCP) and to test L2 connectivity as well.
363     ...    Returns an empty list if no IPv6 addresses found or if SSH connection fails.
364     ...    Otherwise, returns a list of IPv6 addresses.
365     ${ipv6_list}    Create List    @{EMPTY}
366     : FOR    ${vm}    IN    @{vm_list}
367     \    ${output}=    OpenStack CLI    openstack server show ${vm} -f shell
368     \    ${pattern}=    Replace String    ${subnet}    ::/64    (:[a-f0-9]{,4}){,4}
369     \    @{vm_ipv6}=    Get Regexp Matches    ${output}    ${pattern}
370     \    ${vm_ip_length}    Get Length    ${vm_ipv6}[0]
371     \    ${ipv6_data_from_vm}=    Run Keyword If    ${vm_ip_length}>0    Execute Command on VM Instance    ${network}    ${vm_ipv6[0]}
372     \    ...    ip -6 a
373     \    @{ipv6}=    Get Regexp Matches    ${ipv6_data_from_vm}    ${pattern}
374     \    ${ipv6_addr_list_length}    Get Length    @{ipv6}
375     \    Run Keyword If    ${ipv6_addr_list_length}>0    Append To List    ${ipv6_list}    ${ipv6[0]}
376     \    ...    ELSE    Append To List    ${ipv6_list}    None
377     [Return]    ${ipv6_list}
378
379 View Vm Console
380     [Arguments]    ${vm_instance_names}
381     [Documentation]    View Console log of the created vm instances using nova show.
382     : FOR    ${VmElement}    IN    @{vm_instance_names}
383     \    OpenStack CLI    openstack server show ${VmElement}
384     \    ${output}=    OpenStack CLI    openstack console log show ${VmElement}
385
386 Ping Vm From DHCP Namespace
387     [Arguments]    ${net_name}    ${vm_ip}
388     [Documentation]    Reach all Vm Instance with the net id of the Netowrk.
389     Get ControlNode Connection
390     ${net_id}=    Get Net Id    ${net_name}
391     ${output}=    Write Commands Until Prompt And Log    sudo ip netns exec qdhcp-${net_id} ping -c 3 ${vm_ip}    20s
392     Should Contain    ${output}    64 bytes
393
394 Ping From DHCP Should Not Succeed
395     [Arguments]    ${net_name}    ${vm_ip}
396     [Documentation]    Should Not Reach Vm Instance with the net id of the Netowrk.
397     Return From Keyword If    "skip_if_${SECURITY_GROUP_MODE}" in @{TEST_TAGS}
398     Get ControlNode Connection
399     ${net_id}=    Get Net Id    ${net_name}
400     ${output}=    Write Commands Until Prompt And Log    sudo ip netns exec qdhcp-${net_id} ping -c 3 ${vm_ip}    20s
401     Should Not Contain    ${output}    64 bytes
402
403 Ping Vm From Control Node
404     [Arguments]    ${vm_floating_ip}    ${additional_args}=${EMPTY}
405     [Documentation]    Ping VM floating IP from control node
406     Get ControlNode Connection
407     ${output}=    Write Commands Until Prompt And Log    ping ${additional_args} -c 3 ${vm_floating_ip}    20s
408     Should Contain    ${output}    64 bytes
409
410 Curl Metadata Server
411     [Documentation]    Ping to the expected destination ip.
412     ${output}=    Write Commands Until Expected Prompt    curl -i http://169.254.169.254    ${OS_SYSTEM_PROMPT}
413     Write Commands Until Prompt    exit
414     Should Contain    ${output}    200
415
416 Close Vm Instance
417     [Documentation]    Exit the vm instance.
418     ${output}=    Write Commands Until Prompt And Log    exit
419
420 Check If Console Is VmInstance
421     [Arguments]    ${console}=cirros
422     [Documentation]    Check if the session has been able to login to the VM instance
423     ${output}=    Write Commands Until Expected Prompt    id    ${OS_SYSTEM_PROMPT}
424     Should Contain    ${output}    ${console}
425
426 Exit From Vm Console
427     [Documentation]    Check if the session has been able to login to the VM instance and exit the instance
428     ${rcode}=    Run Keyword And Return Status    Check If Console Is VmInstance    cirros
429     Run Keyword If    ${rcode}    Write Commands Until Prompt    exit
430
431 Check Ping
432     [Arguments]    ${ip_address}    ${ttl}=64
433     [Documentation]    Run Ping command on the IP available as argument
434     ${ethertype}=    Get Regexp Matches    ${ip_address}    ${IP_REGEX}
435     ${output}=    Run Keyword If    ${ethertype}    Write Commands Until Expected Prompt    ping -t ${ttl} -c 3 ${ip_address}    ${OS_SYSTEM_PROMPT}
436     ...    ELSE    Write Commands Until Expected Prompt    ping6 -t ${ttl} -c 3 ${ip_address}    ${OS_SYSTEM_PROMPT}
437     Should Contain    ${output}    64 bytes
438
439 Check No Ping
440     [Arguments]    ${ip_address}    ${ttl}=64
441     [Documentation]    Run Ping command to the IP given as argument, executing 3 times and expecting NOT to see "64 bytes"
442     ${output}=    Write Commands Until Expected Prompt    ping -t ${ttl} -c 3 ${ip_address}    ${OS_SYSTEM_PROMPT}
443     Should Not Contain    ${output}    64 bytes
444
445 Check Metadata Access
446     [Documentation]    Try curl on the Metadataurl and check if it is okay
447     ${output}=    Write Commands Until Expected Prompt    curl -i http://169.254.169.254    ${OS_SYSTEM_PROMPT}
448     Should Contain    ${output}    200
449
450 Execute Command on VM Instance
451     [Arguments]    ${net_name}    ${vm_ip}    ${cmd}    ${user}=cirros    ${password}=cubswin:)
452     [Documentation]    Login to the vm instance using ssh in the network, executes a command inside the VM and returns the ouput.
453     Get ControlNode Connection
454     ${net_id} =    Get Net Id    ${net_name}
455     ${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:
456     ${output} =    Write Commands Until Expected Prompt    ${password}    ${OS_SYSTEM_PROMPT}
457     ${rcode} =    Run Keyword And Return Status    Check If Console Is VmInstance
458     ${output} =    Run Keyword If    ${rcode}    Write Commands Until Expected Prompt    ${cmd}    ${OS_SYSTEM_PROMPT}
459     [Teardown]    Exit From Vm Console
460     [Return]    ${output}
461
462 Test Operations From Vm Instance
463     [Arguments]    ${net_name}    ${src_ip}    ${dest_ips}    ${user}=cirros    ${password}=cubswin:)    ${ttl}=64
464     ...    ${ping_should_succeed}=True    ${check_metadata}=True
465     [Documentation]    Login to the vm instance using ssh in the network.
466     Get ControlNode Connection
467     ${net_id}=    Get Net Id    ${net_name}
468     ${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:
469     ${output}=    Write Commands Until Expected Prompt    ${password}    ${OS_SYSTEM_PROMPT}
470     ${rcode}=    Run Keyword And Return Status    Check If Console Is VmInstance
471     Run Keyword If    ${rcode}    Write Commands Until Expected Prompt    ifconfig    ${OS_SYSTEM_PROMPT}
472     Run Keyword If    ${rcode}    Write Commands Until Expected Prompt    route -n    ${OS_SYSTEM_PROMPT}
473     Run Keyword If    ${rcode}    Write Commands Until Expected Prompt    route -A inet6    ${OS_SYSTEM_PROMPT}
474     Run Keyword If    ${rcode}    Write Commands Until Expected Prompt    arp -an    ${OS_SYSTEM_PROMPT}
475     Run Keyword If    ${rcode}    Write Commands Until Expected Prompt    ip -f inet6 neigh show    ${OS_SYSTEM_PROMPT}
476     : FOR    ${dest_ip}    IN    @{dest_ips}
477     \    ${string_empty}=    Run Keyword And Return Status    Should Be Empty    ${dest_ip}
478     \    Run Keyword If    ${string_empty}    Continue For Loop
479     \    Run Keyword If    ${rcode} and "${ping_should_succeed}" == "True"    Check Ping    ${dest_ip}    ttl=${ttl}
480     \    ...    ELSE    Check No Ping    ${dest_ip}    ttl=${ttl}
481     ${ethertype}=    Get Regexp Matches    ${src_ip}    ${IP_REGEX}
482     Run Keyword If    ${rcode} and "${check_metadata}" and ${ethertype} == "True"    Check Metadata Access
483     [Teardown]    Exit From Vm Console
484
485 Test Netcat Operations From Vm Instance
486     [Arguments]    ${net_name}    ${vm_ip}    ${dest_ip}    ${additional_args}=${EMPTY}    ${port}=12345    ${user}=cirros
487     ...    ${password}=cubswin:)
488     [Documentation]    Use Netcat to test TCP/UDP connections to the controller
489     ${client_data}    Set Variable    Test Client Data
490     ${server_data}    Set Variable    Test Server Data
491     Get ControlNode Connection
492     ${output}=    Write Commands Until Prompt And Log    ( ( echo "${server_data}" | sudo timeout 60 nc -l ${additional_args} ${port} ) & )
493     ${output}=    Write Commands Until Prompt And Log    sudo netstat -nlap | grep ${port}
494     ${nc_output}=    Execute Command on VM Instance    ${net_name}    ${vm_ip}    sudo echo "${client_data}" | nc -v -w 5 ${additional_args} ${dest_ip} ${port}
495     ${output}=    Execute Command on VM Instance    ${net_name}    ${vm_ip}    sudo route -n
496     Log    ${output}
497     ${output}=    Execute Command on VM Instance    ${net_name}    ${vm_ip}    sudo arp -an
498     Log    ${output}
499     Should Match Regexp    ${nc_output}    ${server_data}
500
501 Ping Other Instances
502     [Arguments]    ${list_of_external_dst_ips}
503     [Documentation]    Check reachability with other network's instances.
504     ${rcode}=    Run Keyword And Return Status    Check If Console Is VmInstance
505     : FOR    ${dest_ip}    IN    @{list_of_external_dst_ips}
506     \    Check Ping    ${dest_ip}
507
508 Create Router
509     [Arguments]    ${router_name}
510     [Documentation]    Create Router and Add Interface to the subnets.
511     ${rc}    ${output}=    Run And Return Rc And Output    openstack router create ${router_name}
512     Should Be True    '${rc}' == '0'
513
514 List Routers
515     [Documentation]    List Routers and return output with neutron client.
516     ${rc}    ${output}=    Run And Return Rc And Output    openstack router list -f value
517     Log    ${output}
518     Should Be True    '${rc}' == '0'
519     [Return]    ${output}
520
521 Add Router Interface
522     [Arguments]    ${router_name}    ${interface_name}
523     ${rc}    ${output}=    Run And Return Rc And Output    openstack router add subnet ${router_name} ${interface_name}
524     Should Be True    '${rc}' == '0'
525
526 Show Router Interface
527     [Arguments]    ${router_name}
528     [Documentation]    List Routers interface associated with given Router and return output with neutron client.
529     ${rc}    ${output}=    Run And Return Rc And Output    openstack port list --router ${router_name} -f value
530     Should Be True    '${rc}' == '0'
531     [Return]    ${output}
532
533 Add Router Gateway
534     [Arguments]    ${router_name}    ${external_network_name}
535     ${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}
536     ${rc}    ${output}=    Run And Return Rc And Output    ${cmd}
537     Should Be True    '${rc}' == '0'
538
539 Remove Interface
540     [Arguments]    ${router_name}    ${interface_name}
541     [Documentation]    Remove Interface to the subnets.
542     ${rc}    ${output}=    Run And Return Rc And Output    openstack router remove subnet ${router_name} ${interface_name}
543     Should Be True    '${rc}' == '0'
544
545 Remove Gateway
546     [Arguments]    ${router_name}
547     [Documentation]    Remove external gateway from the router.
548     BuiltIn.Log    openstack router unset ${router_name} --external-gateway
549
550 Update Router
551     [Arguments]    ${router_name}    ${cmd}
552     [Documentation]    Update the router with the command. Router name and command should be passed as argument.
553     ${rc}    ${output} =    Run And Return Rc And Output    openstack router set ${router_name} ${cmd}
554     Should Be True    '${rc}' == '0'
555
556 Show Router
557     [Arguments]    ${router_name}    ${options}
558     [Documentation]    Show information of a given router. Router name and optional fields should be sent as arguments.
559     ${rc}    ${output} =    Run And Return Rc And Output    openstack router show ${router_name}
560     Log    ${output}
561
562 Delete Router
563     [Arguments]    ${router_name}
564     [Documentation]    Delete Router and Interface to the subnets.
565     ${rc}    ${output}=    Run And Return Rc And Output    openstack router delete ${router_name}
566     Log    ${output}
567     Should Be True    '${rc}' == '0'
568
569 Get DumpFlows And Ovsconfig
570     [Arguments]    ${conn_id}
571     [Documentation]    Get the OvsConfig and Flow entries from OVS from the Openstack Node
572     SSHLibrary.Switch Connection    ${conn_id}
573     Write Commands Until Expected Prompt    ip -o link    ${DEFAULT_LINUX_PROMPT_STRICT}
574     Write Commands Until Expected Prompt    ip -o addr    ${DEFAULT_LINUX_PROMPT_STRICT}
575     Write Commands Until Expected Prompt    ip route    ${DEFAULT_LINUX_PROMPT_STRICT}
576     Write Commands Until Expected Prompt    arp -an    ${DEFAULT_LINUX_PROMPT_STRICT}
577     ${nslist}=    Write Commands Until Expected Prompt    ip netns list | awk '{print $1}'    ${DEFAULT_LINUX_PROMPT_STRICT}
578     @{lines}    Split To Lines    ${nslist}    end=-1
579     : FOR    ${line}    IN    @{lines}
580     \    Write Commands Until Expected Prompt    sudo ip netns exec ${line} ip -o link    ${DEFAULT_LINUX_PROMPT_STRICT}
581     \    Write Commands Until Expected Prompt    sudo ip netns exec ${line} ip -o addr    ${DEFAULT_LINUX_PROMPT_STRICT}
582     \    Write Commands Until Expected Prompt    sudo ip netns exec ${line} ip route    ${DEFAULT_LINUX_PROMPT_STRICT}
583     Write Commands Until Expected Prompt    sudo ovs-vsctl show    ${DEFAULT_LINUX_PROMPT_STRICT}
584     Write Commands Until Expected Prompt    sudo ovs-vsctl list Open_vSwitch    ${DEFAULT_LINUX_PROMPT_STRICT}
585     Write Commands Until Expected Prompt    sudo ovs-ofctl show br-int -OOpenFlow13    ${DEFAULT_LINUX_PROMPT_STRICT}
586     Write Commands Until Expected Prompt    sudo ovs-ofctl dump-flows br-int -OOpenFlow13    ${DEFAULT_LINUX_PROMPT_STRICT}
587     Write Commands Until Expected Prompt    sudo ovs-ofctl dump-groups br-int -OOpenFlow13    ${DEFAULT_LINUX_PROMPT_STRICT}
588     Write Commands Until Expected Prompt    sudo ovs-ofctl dump-group-stats br-int -OOpenFlow13    ${DEFAULT_LINUX_PROMPT_STRICT}
589
590 Get Karaf Log Type From Test Start
591     [Arguments]    ${ip}    ${test_name}    ${type}    ${user}=${ODL_SYSTEM_USER}    ${password}=${ODL_SYSTEM_PASSWORD}    ${prompt}=${ODL_SYSTEM_PROMPT}
592     ...    ${log_file}=${WORKSPACE}/${BUNDLEFOLDER}/data/log/karaf.log
593     ${cmd}    Set Variable    sed '1,/ROBOT MESSAGE: Starting test ${test_name}/d' ${log_file} | grep '${type}'
594     ${output}    Run Command On Controller    ${ip}    ${cmd}    ${user}    ${password}    ${prompt}
595     [Return]    ${output}
596
597 Get Karaf Log Types From Test Start
598     [Arguments]    ${ip}    ${test_name}    ${types}    ${user}=${ODL_SYSTEM_USER}    ${password}=${ODL_SYSTEM_PASSWORD}    ${prompt}=${ODL_SYSTEM_PROMPT}
599     ...    ${log_file}=${WORKSPACE}/${BUNDLEFOLDER}/data/log/karaf.log
600     : FOR    ${type}    IN    @{types}
601     \    Get Karaf Log Type From Test Start    ${ip}    ${test_name}    ${type}    ${user}    ${password}
602     \    ...    ${prompt}    ${log_file}
603
604 Get Karaf Log Events From Test Start
605     [Arguments]    ${test_name}    ${user}=${ODL_SYSTEM_USER}    ${password}=${ODL_SYSTEM_PASSWORD}    ${prompt}=${ODL_SYSTEM_PROMPT}
606     ${log_types} =    Create List    ERROR    WARN    Exception
607     Run Keyword If    0 < ${NUM_ODL_SYSTEM}    Get Karaf Log Types From Test Start    ${ODL_SYSTEM_IP}    ${test_name}    ${log_types}
608     Run Keyword If    1 < ${NUM_ODL_SYSTEM}    Get Karaf Log Types From Test Start    ${ODL_SYSTEM_2_IP}    ${test_name}    ${log_types}
609     Run Keyword If    2 < ${NUM_ODL_SYSTEM}    Get Karaf Log Types From Test Start    ${ODL_SYSTEM_3_IP}    ${test_name}    ${log_types}
610
611 Get ControlNode Connection
612     SSHLibrary.Switch Connection    ${OS_CNTL_CONN_ID}
613     [Return]    ${OS_CNTL_CONN_ID}
614
615 Get OvsDebugInfo
616     [Documentation]    Get the OvsConfig and Flow entries from all Openstack nodes
617     Run Keyword If    0 < ${NUM_OS_SYSTEM}    Get DumpFlows And Ovsconfig    ${OS_CNTL_CONN_ID}
618     Run Keyword If    1 < ${NUM_OS_SYSTEM}    Get DumpFlows And Ovsconfig    ${OS_CMP1_CONN_ID}
619     Run Keyword If    2 < ${NUM_OS_SYSTEM}    Get DumpFlows And Ovsconfig    ${OS_CMP2_CONN_ID}
620
621 Get Test Teardown Debugs
622     [Arguments]    ${test_name}=${TEST_NAME}
623     Get OvsDebugInfo
624     Run Keyword And Ignore Error    Get Model Dump    ${HA_PROXY_IP}    ${netvirt_data_models}
625     Get Karaf Log Events From Test Start    ${test_name}
626
627 Get Test Teardown Debugs For SFC
628     [Arguments]    ${test_name}=${TEST_NAME}
629     Run Keyword And Ignore Error    Get Model Dump    ${HA_PROXY_IP}    ${netvirt_sfc_data_models}
630
631 Show Debugs
632     [Arguments]    @{vm_indices}
633     [Documentation]    Run these commands for debugging, it can list state of VM instances and ip information in control node
634     Get ControlNode Connection
635     ${output}=    Write Commands Until Prompt And Log    sudo ip netns list
636     : FOR    ${index}    IN    @{vm_indices}
637     \    ${rc}    ${output}=    Run And Return Rc And Output    nova show ${index}
638     \    Log    ${output}
639     List Nova VMs
640     List Routers
641     List Networks
642     List Subnets
643     List Ports
644     List Security Groups
645
646 List Security Groups
647     [Documentation]    Logging keyword to display all security groups using the openstack cli. Assumes openstack
648     ...    credentials are already sourced
649     ${rc}    ${output}=    Run And Return Rc And Output    openstack security group list
650     Log    ${output}
651     Should Be True    '${rc}' == '0'
652     [Return]    ${output}
653
654 Neutron Security Group Show
655     [Arguments]    ${SecurityGroupRuleName}
656     [Documentation]    Displays the neutron security group configurations that belongs to a given neutron security group name
657     ${rc}    ${output}=    Run And Return Rc And Output    openstack security group show ${SecurityGroupRuleName}
658     Log    ${output}
659     Should Be True    '${rc}' == '0'
660     [Return]    ${output}
661
662 Neutron Port Show
663     [Arguments]    ${PortName}
664     [Documentation]    Display the port configuration that belong to a given neutron port
665     ${rc}    ${output}=    Run And Return Rc And Output    openstack port show ${PortName}
666     Log    ${output}
667     Should Be True    '${rc}' == '0'
668     [Return]    ${output}
669
670 Neutron Security Group Create
671     [Arguments]    ${SecurityGroupName}    ${additional_args}=${EMPTY}
672     [Documentation]    Create a security group with specified name ,description & protocol value according to security group template
673     Get ControlNode Connection
674     ${rc}    ${output}=    Run And Return Rc And Output    openstack security group create ${SecurityGroupName} ${additional_args}
675     Log    ${output}
676     Should Be True    '${rc}' == '0'
677     ${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}
678     Log    ${sgp_id}
679     [Return]    ${output}    ${sgp_id}
680
681 Neutron Security Group Update
682     [Arguments]    ${SecurityGroupName}    ${additional_args}=${EMPTY}
683     [Documentation]    Updating security groups
684     ${rc}    ${output}=    Run And Return Rc And Output    openstack security group set ${SecurityGroupName} ${additional_args}
685     Log    ${output}
686     Should Be True    '${rc}' == '0'
687     [Return]    ${output}
688
689 Delete SecurityGroup
690     [Arguments]    ${sg_name}
691     [Documentation]    Delete Security group
692     ${rc}    ${output}=    Run And Return Rc And Output    openstack security group delete ${sg_name}
693     Log    ${output}
694     Should Be True    '${rc}' == '0'
695
696 Neutron Security Group Rule Create
697     [Arguments]    ${Security_group_name}    &{Kwargs}
698     [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]} ..."
699     Run Keyword If    ${Kwargs}    Log    ${Kwargs}
700     ${description}    Run Keyword If    ${Kwargs}    Pop From Dictionary    ${Kwargs}    description    default=${None}
701     ${direction}    Run Keyword If    ${Kwargs}    Pop From Dictionary    ${Kwargs}    direction    default=${None}
702     ${ethertype}    Run Keyword If    ${Kwargs}    Pop From Dictionary    ${Kwargs}    ethertype    default=${None}
703     ${port_range_max}    Run Keyword If    ${Kwargs}    Pop From Dictionary    ${Kwargs}    port_range_max    default=${None}
704     ${port_range_min}    Run Keyword If    ${Kwargs}    Pop From Dictionary    ${Kwargs}    port_range_min    default=${None}
705     ${protocol}    Run Keyword If    ${Kwargs}    Pop From Dictionary    ${Kwargs}    protocol    default=${None}
706     ${remote_group_id}    Run Keyword If    ${Kwargs}    Pop From Dictionary    ${Kwargs}    remote_group_id    default=${None}
707     ${remote_ip_prefix}    Run Keyword If    ${Kwargs}    Pop From Dictionary    ${Kwargs}    remote_ip_prefix    default=${None}
708     ${cmd}=    Set Variable    openstack security group rule create ${Security_group_name}
709     ${cmd}=    Run Keyword If    '${description}'!='None'    Catenate    ${cmd}    --description ${description}
710     ...    ELSE    Catenate    ${cmd}
711     ${cmd}=    Run Keyword If    '${direction}'!='None'    Catenate    ${cmd}    --${direction}
712     ...    ELSE    Catenate    ${cmd}
713     ${cmd}=    Run Keyword If    '${ethertype}'!='None'    Catenate    ${cmd}    --ethertype ${ethertype}
714     ...    ELSE    Catenate    ${cmd}
715     ${cmd}=    Run Keyword If    '${port_range_min}'!='None' and '${port_range_max}'!='None'    Catenate    ${cmd}    --dst-port ${port_range_min}:${port_range_max}
716     ...    ELSE IF    '${port_range_max}'!='None'    Catenate    ${cmd}    --dst-port ${port_range_max}
717     ...    ELSE IF    '${port_range_min}'!='None'    Catenate    ${cmd}    --dst-port ${port_range_min}
718     ...    ELSE    Catenate    ${cmd}
719     ${cmd}=    Run Keyword If    '${protocol}'!='None'    Catenate    ${cmd}    --protocol ${protocol}
720     ...    ELSE    Catenate    ${cmd}
721     ${cmd}=    Run Keyword If    '${remote_group_id}'!='None'    Catenate    ${cmd}    --remote-group ${remote_group_id}
722     ...    ELSE    Catenate    ${cmd}
723     ${cmd}=    Run Keyword If    '${remote_ip_prefix}'!='None'    Catenate    ${cmd}    --src-ip ${remote_ip_prefix}
724     ...    ELSE    Catenate    ${cmd}
725     ${rc}    ${output}=    Run And Return Rc And Output    ${cmd}
726     ${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}
727     Log    ${rule_id}
728     Should Be True    '${rc}' == '0'
729     [Return]    ${output}    ${rule_id}
730
731 Neutron Security Group Rule Create Legacy Cli
732     [Arguments]    ${Security_group_name}    &{Kwargs}
733     [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]} ..."
734     Run Keyword If    ${Kwargs}    Log    ${Kwargs}
735     ${description}    Run Keyword If    ${Kwargs}    Pop From Dictionary    ${Kwargs}    description    default=${None}
736     ${direction}    Run Keyword If    ${Kwargs}    Pop From Dictionary    ${Kwargs}    direction    default=${None}
737     ${ethertype}    Run Keyword If    ${Kwargs}    Pop From Dictionary    ${Kwargs}    ethertype    default=${None}
738     ${port_range_max}    Run Keyword If    ${Kwargs}    Pop From Dictionary    ${Kwargs}    port_range_max    default=${None}
739     ${port_range_min}    Run Keyword If    ${Kwargs}    Pop From Dictionary    ${Kwargs}    port_range_min    default=${None}
740     ${protocol}    Run Keyword If    ${Kwargs}    Pop From Dictionary    ${Kwargs}    protocol    default=${None}
741     ${remote_group_id}    Run Keyword If    ${Kwargs}    Pop From Dictionary    ${Kwargs}    remote_group_id    default=${None}
742     ${remote_ip_prefix}    Run Keyword If    ${Kwargs}    Pop From Dictionary    ${Kwargs}    remote_ip_prefix    default=${None}
743     ${cmd}=    Set Variable    neutron security-group-rule-create ${Security_group_name}
744     ${cmd}=    Run Keyword If    '${description}'!='None'    Catenate    ${cmd}    --description ${description}
745     ...    ELSE    Catenate    ${cmd}
746     ${cmd}=    Run Keyword If    '${direction}'!='None'    Catenate    ${cmd}    --direction ${direction}
747     ...    ELSE    Catenate    ${cmd}
748     ${cmd}=    Run Keyword If    '${ethertype}'!='None'    Catenate    ${cmd}    --ethertype ${ethertype}
749     ...    ELSE    Catenate    ${cmd}
750     ${cmd}=    Run Keyword If    '${port_range_max}'!='None'    Catenate    ${cmd}    --port_range_max ${port_range_max}
751     ...    ELSE    Catenate    ${cmd}
752     ${cmd}=    Run Keyword If    '${port_range_min}'!='None'    Catenate    ${cmd}    --port_range_min ${port_range_min}
753     ...    ELSE    Catenate    ${cmd}
754     ${cmd}=    Run Keyword If    '${protocol}'!='None'    Catenate    ${cmd}    --protocol ${protocol}
755     ...    ELSE    Catenate    ${cmd}
756     ${cmd}=    Run Keyword If    '${remote_group_id}'!='None'    Catenate    ${cmd}    --remote_group_id ${remote_group_id}
757     ...    ELSE    Catenate    ${cmd}
758     ${cmd}=    Run Keyword If    '${remote_ip_prefix}'!='None'    Catenate    ${cmd}    --remote_ip_prefix ${remote_ip_prefix}
759     ...    ELSE    Catenate    ${cmd}
760     ${rc}    ${output}=    Run And Return Rc And Output    ${cmd}
761     ${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}
762     Log    ${rule_id}
763     Should Be True    '${rc}' == '0'
764     [Return]    ${output}    ${rule_id}
765
766 Security Group Create Without Default Security Rules
767     [Arguments]    ${sg_name}    ${additional_args}=${EMPTY}
768     [Documentation]    Create Neutron Security Group with no default rules, using specified name and optional arguments.
769     Neutron Security Group Create    ${sg_name}    ${additional_args}
770     Delete All Security Group Rules    ${sg_name}
771
772 Delete All Security Group Rules
773     [Arguments]    ${sg_name}
774     [Documentation]    Delete all security rules from a specified security group
775     ${rc}    ${sg_rules_output}=    Run And Return Rc And Output    openstack security group rule list ${sg_name} -cID -fvalue
776     Log    ${sg_rules_output}
777     Should Be True    '${rc}' == '0'
778     @{sg_rules}=    Split String    ${sg_rules_output}    \n
779     : FOR    ${rule}    IN    @{sg_rules}
780     \    ${rc}    ${output}=    Run And Return Rc And Output    openstack security group rule delete ${rule}
781     \    Log    ${output}
782     \    Should Be True    '${rc}' == '0'
783
784 Create Allow All SecurityGroup
785     [Arguments]    ${sg_name}    ${ether_type}=IPv4
786     [Documentation]    Allow all TCP/UDP/ICMP packets for this suite
787     Neutron Security Group Create    ${sg_name}
788     Neutron Security Group Rule Create    ${sg_name}    direction=ingress    ethertype=${ether_type}    port_range_max=65535    port_range_min=1    protocol=tcp
789     Neutron Security Group Rule Create    ${sg_name}    direction=egress    ethertype=${ether_type}    port_range_max=65535    port_range_min=1    protocol=tcp
790     Neutron Security Group Rule Create    ${sg_name}    direction=ingress    ethertype=${ether_type}    protocol=icmp
791     Neutron Security Group Rule Create    ${sg_name}    direction=egress    ethertype=${ether_type}    protocol=icmp
792     Neutron Security Group Rule Create    ${sg_name}    direction=ingress    ethertype=${ether_type}    port_range_max=65535    port_range_min=1    protocol=udp
793     Neutron Security Group Rule Create    ${sg_name}    direction=egress    ethertype=${ether_type}    port_range_max=65535    port_range_min=1    protocol=udp
794
795 Create Neutron Port With Additional Params
796     [Arguments]    ${network_name}    ${port_name}    ${additional_args}=${EMPTY}
797     [Documentation]    Create Port With given additional parameters
798     ${rc}    ${output}=    Run And Return Rc And Output    neutron -v port-create ${network_name} --name ${port_name} ${additional_args}
799     Log    ${output}
800     Should Be True    '${rc}' == '0'
801     ${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}
802     Log    ${port_id}
803     [Return]    ${OUTPUT}    ${port_id}
804
805 Get Ports MacAddr
806     [Arguments]    ${portName_list}
807     [Documentation]    Retrieve the port MacAddr for the given list of port name and return the MAC address list.
808     ${MacAddr-list}    Create List
809     : FOR    ${portName}    IN    @{portName_list}
810     \    ${macAddr}=    OpenStackOperations.Get Port Mac    ${portName}
811     \    Append To List    ${MacAddr-list}    ${macAddr}
812     [Return]    ${MacAddr-list}
813
814 Get Port Ip
815     [Arguments]    ${port_name}
816     [Documentation]    Keyword would return the IP of the ${port_name} received.
817     ${rc}    ${output}=    Run And Return Rc And Output    openstack port list | grep "${port_name}" | awk -F\\' '{print $2}'
818     ${splitted_output}=    Split String    ${output}    ${EMPTY}
819     ${port_ip}=    Get from List    ${splitted_output}    0
820     Should Be True    '${rc}' == '0'
821     [Return]    ${port_ip}
822
823 Get Port Mac
824     [Arguments]    ${port_name}
825     [Documentation]    Keyword would return the MAC ID of the ${port_name} received.
826     ${rc}    ${output}=    Run And Return Rc And Output    openstack port show ${port_name} | grep mac_address | awk '{print $4}'
827     ${splitted_output}=    Split String    ${output}    ${EMPTY}
828     ${port_mac}=    Get from List    ${splitted_output}    0
829     Should Be True    '${rc}' == '0'
830     [Return]    ${port_mac}
831
832 Create L2Gateway
833     [Arguments]    ${bridge_name}    ${intf_name}    ${gw_name}
834     [Documentation]    Keyword to create an L2 Gateway ${gw_name} for bridge ${bridge_name} connected to interface ${intf_name} (Using Neutron CLI).
835     ${rc}    ${l2gw_output}=    Run And Return Rc And Output    ${L2GW_CREATE} name=${bridge_name},interface_names=${intf_name} ${gw_name}
836     Log    ${l2gw_output}
837     [Return]    ${l2gw_output}
838
839 Create L2Gateway Connection
840     [Arguments]    ${gw_name}    ${net_name}
841     [Documentation]    Keyword would create a new L2 Gateway Connection for ${gw_name} to ${net_name} (Using Neutron CLI).
842     ${rc}    ${l2gw_output}=    Run And Return Rc And Output    ${L2GW_CONN_CREATE} ${gw_name} ${net_name}
843     Log    ${l2gw_output}
844     Should Be True    '${rc}' == '0'
845     [Return]    ${l2gw_output}
846
847 Get All L2Gateway
848     [Documentation]    Keyword to return all the L2 Gateways available (Using Neutron CLI).
849     ${rc}    ${output}=    Run And Return Rc And Output    ${L2GW_GET_YAML}
850     Should Be True    '${rc}' == '0'
851     [Return]    ${output}
852
853 Get All L2Gateway Connection
854     [Documentation]    Keyword to return all the L2 Gateway connections available (Using Neutron CLI).
855     ${rc}    ${output}=    Run And Return Rc And Output    ${L2GW_GET_CONN_YAML}
856     Should Be True    '${rc}' == '0'
857     [Return]    ${output}
858
859 Get L2Gateway
860     [Arguments]    ${gw_id}
861     [Documentation]    Keyword to check if the ${gw_id} is available in the L2 Gateway list (Using Neutron CLI).
862     ${rc}    ${output}=    Run And Return Rc And Output    ${L2GW_SHOW} ${gw_id}
863     Log    ${output}
864     Should Be True    '${rc}' == '0'
865     [Return]    ${output}
866
867 Get L2gw Id
868     [Arguments]    ${l2gw_name}
869     [Documentation]    Keyword to retrieve the L2 Gateway ID for the ${l2gw_name} (Using Neutron CLI).
870     ${rc}    ${output}=    Run And Return Rc And Output    ${L2GW_GET} | grep "${l2gw_name}" | awk '{print $2}'
871     Log    ${output}
872     Should Be True    '${rc}' == '0'
873     ${splitted_output}=    Split String    ${output}    ${EMPTY}
874     ${l2gw_id}=    Get from List    ${splitted_output}    0
875     [Return]    ${l2gw_id}
876
877 Get L2gw Connection Id
878     [Arguments]    ${l2gw_name}
879     [Documentation]    Keyword to retrieve the L2 Gateway Connection ID for the ${l2gw_name} (Using Neutron CLI).
880     ${l2gw_id}=    OpenStackOperations.Get L2gw Id    ${l2gw_name}
881     ${rc}    ${output}=    Run And Return Rc And Output    ${L2GW_GET_CONN} | grep "${l2gw_id}" | awk '{print $2}'
882     Should Be True    '${rc}' == '0'
883     ${splitted_output}=    Split String    ${output}    ${EMPTY}
884     ${splitted_output}=    Split String    ${output}    ${EMPTY}
885     ${l2gw_conn_id}=    Get from List    ${splitted_output}    0
886     [Return]    ${l2gw_conn_id}
887
888 Neutron Port List Rest
889     [Documentation]    Keyword to get all ports details in Neutron (Using REST).
890     ${resp} =    RequestsLibrary.Get Request    session    ${PORT_URL}
891     Log    ${resp.content}
892     Should Be Equal As Strings    ${resp.status_code}    200
893     [Return]    ${resp.content}
894
895 Get Neutron Port Rest
896     [Arguments]    ${port_id}
897     [Documentation]    Keyword to get the specific port details in Neutron (Using REST).
898     ${resp} =    RequestsLibrary.Get Request    session    ${CONFIG_API}/${GET_PORT_URL}/${port_id}
899     Log    ${resp.content}
900     Should Be Equal As Strings    ${resp.status_code}    200
901     [Return]    ${resp.content}
902
903 Update Port Rest
904     [Arguments]    ${port_id}    ${json_data}
905     [Documentation]    Keyword to update ${port_id} with json data received in ${json_data} (Using REST).
906     Log    ${json_data}
907     ${resp} =    RequestsLibrary.Put Request    session    ${CONFIG_API}/${GET_PORT_URL}/${port_id}    ${json_data}
908     Log    ${resp.content}
909     Should Be Equal As Strings    ${resp.status_code}    200
910     [Return]    ${resp.content}
911
912 Create And Configure Security Group
913     [Arguments]    ${sg-name}
914     [Documentation]    Create Security Group with given name, and default allow rules for TCP/UDP/ICMP protocols.
915     Neutron Security Group Create    ${sg-name}
916     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
917     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
918     Neutron Security Group Rule Create    ${sg-name}    direction=ingress    protocol=icmp    remote_ip_prefix=0.0.0.0/0
919     Neutron Security Group Rule Create    ${sg-name}    direction=egress    protocol=icmp    remote_ip_prefix=0.0.0.0/0
920     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
921     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
922
923 Add Security Group To VM
924     [Arguments]    ${vm}    ${sg}
925     [Documentation]    Add the security group provided to the given VM.
926     ${output}=    OpenStack CLI    openstack server add security group ${vm} ${sg}
927
928 Remove Security Group From VM
929     [Arguments]    ${vm}    ${sg}
930     [Documentation]    Remove the security group provided to the given VM.
931     Get ControlNode Connection
932     OpenStack CLI    openstack server remove security group ${vm} ${sg}
933
934 Create SFC Flow Classifier
935     [Arguments]    ${name}    ${src_ip}    ${dest_ip}    ${protocol}    ${dest_port}    ${neutron_src_port}
936     [Documentation]    Create a flow classifier for SFC
937     ${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}
938     Log    ${output}
939     Should Be True    '${rc}' == '0'
940     Should Contain    ${output}    ${name}
941     [Return]    ${output}
942
943 Delete SFC Flow Classifier
944     [Arguments]    ${name}
945     [Documentation]    Delete a SFC flow classifier
946     Get ControlNode Connection
947     ${rc}    ${output}=    Run And Return Rc And Output    openstack sfc flow classifier delete ${name}
948     Log    ${output}
949     Should Be True    '${rc}' == '0'
950     [Return]    ${output}
951
952 Create SFC Port Pair
953     [Arguments]    ${name}    ${port_in}    ${port_out}
954     [Documentation]    Creates a neutron port pair for SFC
955     Get ControlNode Connection
956     ${rc}    ${output}=    Run And Return Rc And Output    openstack sfc port pair create --ingress=${port_in} --egress=${port_out} ${name}
957     Log    ${output}
958     Should Be True    '${rc}' == '0'
959     Should Contain    ${output}    ${name}
960     [Return]    ${output}
961
962 Delete SFC Port Pair
963     [Arguments]    ${name}
964     [Documentation]    Delete a SFC port pair
965     ${rc}    ${output}=    Run And Return Rc And Output    openstack sfc port pair delete ${name}
966     Log    ${output}
967     Should Be True    '${rc}' == '0'
968     [Return]    ${output}
969
970 Create SFC Port Pair Group
971     [Arguments]    ${name}    ${port_pair}
972     [Documentation]    Creates a port pair group with a single port pair for SFC
973     ${rc}    ${output}=    Run And Return Rc And Output    openstack sfc port pair group create --port-pair ${port_pair} ${name}
974     Log    ${output}
975     Should Be True    '${rc}' == '0'
976     Should Contain    ${output}    ${name}
977     [Return]    ${output}
978
979 Create SFC Port Pair Group With Two Pairs
980     [Arguments]    ${name}    ${port_pair1}    ${port_pair2}
981     [Documentation]    Creates a port pair group with two port pairs for SFC
982     ${rc}    ${output}=    Run And Return Rc And Output    openstack sfc port pair group create --port-pair ${port_pair1} --port-pair ${port_pair2} ${name}
983     Log    ${output}
984     Should Be True    '${rc}' == '0'
985     Should Contain    ${output}    ${name}
986     [Return]    ${output}
987
988 Delete SFC Port Pair Group
989     [Arguments]    ${name}
990     [Documentation]    Delete a SFC port pair group
991     Get ControlNode Connection
992     ${rc}    ${output}=    Run And Return Rc And Output    openstack sfc port pair group delete ${name}
993     Log    ${output}
994     Should Be True    '${rc}' == '0'
995     [Return]    ${output}
996
997 Create SFC Port Chain
998     [Arguments]    ${name}    ${pg1}    ${pg2}    ${fc}
999     [Documentation]    Creates a port pair chain with two port groups and a singel classifier.
1000     ${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}
1001     Log    ${output}
1002     Should Be True    '${rc}' == '0'
1003     Should Contain    ${output}    ${name}
1004     [Return]    ${output}
1005
1006 Delete SFC Port Chain
1007     [Arguments]    ${name}
1008     [Documentation]    Delete a SFC port chain
1009     ${rc}    ${output}=    Run And Return Rc And Output    openstack sfc port chain delete ${name}
1010     Log    ${output}
1011     Should Be True    '${rc}' == '0'
1012     [Return]    ${output}
1013
1014 Reboot Nova VM
1015     [Arguments]    ${vm_name}
1016     [Documentation]    Reboot NOVA VM
1017     OpenStack CLI    openstack server reboot --wait ${vm_name}
1018     Wait Until Keyword Succeeds    35s    10s    Verify VM Is ACTIVE    ${vm_name}
1019
1020 Remove RSA Key From KnownHosts
1021     [Arguments]    ${vm_ip}
1022     [Documentation]    Remove RSA
1023     Get ControlNode Connection
1024     ${output}=    Write Commands Until Prompt And Log    sudo cat /root/.ssh/known_hosts    30s
1025     ${output}=    Write Commands Until Prompt And Log    sudo ssh-keygen -f "/root/.ssh/known_hosts" -R ${vm_ip}    30s
1026     ${output}=    Write Commands Until Prompt    sudo cat "/root/.ssh/known_hosts"    30s
1027
1028 Wait For Routes To Propogate
1029     [Arguments]    ${networks}    ${subnets}
1030     [Documentation]    Check propagated routes
1031     Get ControlNode Connection
1032     : FOR    ${INDEX}    IN RANGE    0    1
1033     \    ${net_id}=    Get Net Id    @{networks}[${INDEX}]
1034     \    ${is_ipv6}=    Get Regexp Matches    @{subnets}[${INDEX}]    ${IP6_REGEX}
1035     \    ${length}=    Get Length    ${is_ipv6}
1036     \    ${cmd}=    Set Variable If    ${length} == 0    ip route    ip -6 route
1037     \    ${output}=    Write Commands Until Expected Prompt    sudo ip netns exec qdhcp-${net_id} ${cmd}    ]>
1038     \    Should Contain    ${output}    @{subnets}[${INDEX}]
1039
1040 Neutron Cleanup
1041     [Arguments]    ${vms}=@{EMPTY}    ${networks}=@{EMPTY}    ${subnets}=@{EMPTY}    ${ports}=@{EMPTY}    ${sgs}=@{EMPTY}
1042     : FOR    ${vm}    IN    @{vms}
1043     \    BuiltIn.Run Keyword And Ignore Error    Delete Vm Instance    ${vm}
1044     : FOR    ${port}    IN    @{ports}
1045     \    BuiltIn.Run Keyword And Ignore Error    Delete Port    ${port}
1046     : FOR    ${subnet}    IN    @{subnets}
1047     \    BuiltIn.Run Keyword And Ignore Error    Delete SubNet    ${subnet}
1048     : FOR    ${network}    IN    @{networks}
1049     \    BuiltIn.Run Keyword And Ignore Error    Delete Network    ${network}
1050     : FOR    ${sg}    IN    @{sgs}
1051     \    BuiltIn.Run Keyword And Ignore Error    Delete SecurityGroup    ${sg}
1052
1053 OpenStack List All
1054     [Documentation]    Get a list of different OpenStack resources that might be in use.
1055     @{modules} =    BuiltIn.Create List    server    port    network    subnet    security group
1056     ...    security group rule
1057     Run Keyword If    "${ODL_ENABLE_L3_FWD}"=="yes"    Append To List    ${modules}    floating ip    router
1058     : FOR    ${module}    IN    @{modules}
1059     \    OpenStack CLI    openstack ${module} list
1060
1061 OpenStack CLI Get List
1062     [Arguments]    ${cmd}
1063     [Documentation]    Return a json list from the output of an OpenStack command.
1064     @{list} =    BuiltIn.Create List
1065     ${json} =    OpenStack CLI    ${cmd}
1066     @{list} =    RequestsLibrary.To Json    ${json}
1067     BuiltIn.Log    ${list}
1068     [Return]    @{list}
1069
1070 OpenStack CLI
1071     [Arguments]    ${cmd}    ${log_output}=True
1072     [Documentation]    Run the given OpenStack ${cmd}.
1073     ${rc}    ${output} =    OperatingSystem.Run And Return Rc And Output    ${cmd}
1074     Run Keyword If    "${log_output}"=="True"    BuiltIn.Log    ${output}
1075     Should Be True    '${rc}' == '0'
1076     [Return]    ${output}
1077
1078 OpenStack Cleanup All
1079     [Documentation]    Cleanup all Openstack resources with best effort. The keyword will query for all resources
1080     ...    in use and then attempt to delete them. Errors are ignored to allow the cleanup to continue.
1081     @{fips} =    Run Keyword If    "${ODL_ENABLE_L3_FWD}"=="yes"    OpenStack CLI Get List    openstack floating ip list -f json
1082     ...    ELSE    Create List    @{EMPTY}
1083     : FOR    ${fip}    IN    @{fips}
1084     \    BuiltIn.Run Keyword And Ignore Error    Delete Floating IP    ${fip['ID']}
1085     @{vms} =    OpenStack CLI Get List    openstack server list -f json
1086     : FOR    ${vm}    IN    @{vms}
1087     \    BuiltIn.Run Keyword And Ignore Error    Delete Vm Instance    ${vm['ID']}
1088     @{routers} =    Run Keyword If    "${ODL_ENABLE_L3_FWD}"=="yes"    OpenStack CLI Get List    openstack router list -f json
1089     ...    ELSE    Create List    @{EMPTY}
1090     : FOR    ${router}    IN    @{routers}
1091     \    BuiltIn.Run Keyword And Ignore Error    Cleanup Router    ${router['ID']}
1092     @{ports} =    OpenStack CLI Get List    openstack port list -f json
1093     : FOR    ${port}    IN    @{ports}
1094     \    BuiltIn.Run Keyword And Ignore Error    Delete Port    ${port['ID']}
1095     @{networks} =    OpenStack CLI Get List    openstack network list -f json
1096     : FOR    ${network}    IN    @{networks}
1097     \    BuiltIn.Run Keyword And Ignore Error    Delete Subnet    ${network['Subnets']}
1098     \    BuiltIn.Run Keyword And Ignore Error    Delete Network    ${network['ID']}
1099     @{security_groups} =    OpenStack CLI Get List    openstack security group list -f json
1100     : FOR    ${security_group}    IN    @{security_groups}
1101     \    BuiltIn.Run Keyword If    "${security_group['Name']}" != "default"    BuiltIn.Run Keyword And Ignore Error    Delete SecurityGroup    ${security_group['ID']}
1102     OpenStack List All
1103
1104 Cleanup Router
1105     [Arguments]    ${id}
1106     [Documentation]    Delete a router, but first remove any interfaces or gateways so that the delete will be successful.
1107     @{ports} =    OpenStack CLI Get List    openstack port list --router ${id} -f json --long
1108     : FOR    ${port}    IN    @{ports}
1109     \    ${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
1110     \    BuiltIn.Run Keyword If    "${port['Device Owner']}" == "network:router_gateway"    BuiltIn.Run Keyword And Ignore Error    Remove Gateway    ${id}
1111     \    BuiltIn.Run Keyword If    "${port['Device Owner']}" == "network:router_interface"    BuiltIn.Run Keyword And Ignore Error    Remove Interface    ${id}    ${subnet_id}
1112     BuiltIn.Run Keyword And Ignore Error    Delete Router    ${id}
1113
1114 OpenStack Suite Setup
1115     [Documentation]    Wrapper teardown keyword that can be used in any suite running in an openstack environement
1116     SetupUtils.Setup_Utils_For_Setup_And_Teardown
1117     @{tcpdump_port_6653_conn_ids} =    OpenStackOperations.Start Packet Capture On Nodes    tcpdump_port_6653    port 6653    ${OS_CONTROL_NODE_IP}    ${OS_COMPUTE_1_IP}    ${OS_COMPUTE_2_IP}
1118     BuiltIn.Set Suite Variable    @{tcpdump_port_6653_conn_ids}
1119     Run Keyword If    "${PRE_CLEAN_OPENSTACK_ALL}"=="True"    OpenStack Cleanup All
1120     DevstackUtils.Devstack Suite Setup
1121     Add OVS Logging On All OpenStack Nodes
1122
1123 OpenStack Suite Teardown
1124     [Documentation]    Wrapper teardown keyword that can be used in any suite running in an openstack environement
1125     ...    to clean up all openstack resources. For example, all instances, networks, ports, etc will be listed and
1126     ...    and deleted. As other global cleanup tasks are needed, they can be added here and the suites will all
1127     ...    benefit automatically.
1128     OpenStack Cleanup All
1129     OpenStackOperations.Stop Packet Capture On Nodes    ${tcpdump_port_6653_conn_ids}
1130     SSHLibrary.Close All Connections
1131
1132 Copy DHCP Files From Control Node
1133     [Documentation]    Copy the current DHCP files to the robot vm. The keyword must be called
1134     ...    after the subnet(s) are created and before the subnet(s) are deleted.
1135     ${suite_} =    BuiltIn.Evaluate    """${SUITE_NAME}""".replace(" ","_").replace("/","_").replace(".","_")
1136     ${dstdir} =    Set Variable    /tmp/qdhcp/${suite_}
1137     OperatingSystem.Create Directory    ${dstdir}
1138     Get ControlNode Connection
1139     BuiltIn.Run Keyword And Ignore Error    SSHLibrary.Get Directory    /opt/stack/data/neutron/dhcp    ${dstdir}    recursive=True
1140
1141 Is Feature Installed
1142     [Arguments]    ${features}=none
1143     : FOR    ${feature}    IN    @{features}
1144     \    ${status}    ${output}    Run Keyword And Ignore Error    Builtin.Should Contain    ${CONTROLLERFEATURES}    ${feature}
1145     \    Return From Keyword If    "${status}" == "PASS"    True
1146     [Return]    False
1147
1148 Add OVS Logging On All OpenStack Nodes
1149     [Documentation]    Add higher levels of OVS logging to all the OpenStack nodes
1150     Run Keyword If    0 < ${NUM_OS_SYSTEM}    OVSDB.Add OVS Logging    ${OS_CNTL_CONN_ID}
1151     Run Keyword If    1 < ${NUM_OS_SYSTEM}    OVSDB.Add OVS Logging    ${OS_CMP1_CONN_ID}
1152     Run Keyword If    2 < ${NUM_OS_SYSTEM}    OVSDB.Add OVS Logging    ${OS_CMP2_CONN_ID}
1153
1154 Reset OVS Logging On All OpenStack Nodes
1155     [Documentation]    Reset the OVS logging to all the OpenStack nodes
1156     Run Keyword If    0 < ${NUM_OS_SYSTEM}    OVSDB.Reset OVS Logging    ${OS_CNTL_CONN_ID}
1157     Run Keyword If    1 < ${NUM_OS_SYSTEM}    OVSDB.Reset OVS Logging    ${OS_CMP1_CONN_ID}
1158     Run Keyword If    2 < ${NUM_OS_SYSTEM}    OVSDB.Reset OVS Logging    ${OS_CMP2_CONN_ID}
1159
1160 Start Packet Capture On Nodes
1161     [Arguments]    ${tag}    ${filter}    @{ips}
1162     [Documentation]    Wrapper keyword around the TcpDump packet capture that is catered to the Openstack setup.
1163     ...    The caller must pass the three arguments with a variable number of ips at the end,
1164     ...    but ${EMPTY} can be used for the tag and filter.
1165     ${suite_} =    BuiltIn.Evaluate    """${SUITE_NAME}""".replace(" ","_").replace("/","_").replace(".","_")
1166     ${tag_} =    BuiltIn.Catenate    SEPARATOR=__    ${tag}    ${suite_}
1167     @{conn_ids} =    Tcpdump.Start Packet Capture on Nodes    tag=${tag_}    filter=${filter}    ips=${ips}
1168     [Return]    @{conn_ids}
1169
1170 Stop Packet Capture On Nodes
1171     [Arguments]    ${conn_ids}=@{EMPTY}
1172     Tcpdump.Stop Packet Capture on Nodes    ${conn_ids}