Clean up PcepOperations
[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
4 Library             Collections
5 Library             Process
6 Library             OperatingSystem
7 Library             RequestsLibrary
8 Library             SSHLibrary
9 Library             String
10 Resource            DataModels.robot
11 Resource            DevstackUtils.robot
12 Resource            KarafKeywords.robot
13 Resource            L2GatewayOperations.robot
14 Resource            ODLTools.robot
15 Resource            OVSDB.robot
16 Resource            SetupUtils.robot
17 Resource            SSHKeywords.robot
18 Resource            Tcpdump.robot
19 Resource            Utils.robot
20 Resource            ../variables/Variables.robot
21 Resource            ../variables/openflowplugin/Variables.robot
22
23
24 *** Variables ***
25 @{VALIDATION_KEYWORDS}
26 ...                         Verify Services
27 ...                         Verify Expected Default Tunnels
28 ...                         Verify Expected Default Tables On Nodes
29 ${VALIDATION_FILE}          /tmp/validations.txt
30 @{DIAG_SERVICES}    OPENFLOW    IFM    ITM    DATASTORE    ELAN    OVSDB
31
32
33 *** Keywords ***
34 Get Tenant ID From Security Group
35     [Documentation]    Returns tenant ID by reading it from existing default security-group.
36     ${output} =    OpenStack CLI    openstack security group show default | grep "| tenant_id" | awk '{print $4}'
37     RETURN    ${output}
38
39 Get Tenant ID From Network
40     [Documentation]    Returns tenant ID by reading it from existing network.
41     [Arguments]    ${network_uuid}
42     ${resp} =    TemplatedRequests.Get_From_Uri
43     ...    uri=${CONFIG_API}/neutron:neutron/networks/network/${network_uuid}/
44     ...    accept=${ACCEPT_EMPTY}
45     ...    session=session
46     ${temp_vars} =    BuiltIn.Set Variable    ['network'][0]['tenant-id']
47     ${tenant_id} =    Utils.Extract Value From Content    ${resp}    ${temp_vars}
48     RETURN    ${tenant_id}
49
50 Create Network
51     [Documentation]    Create Network with openstack request.
52     [Arguments]    ${network_name}    ${additional_args}=${EMPTY}    ${verbose}=TRUE
53     ${output} =    OpenStack CLI    openstack network create ${network_name} ${additional_args}
54     RETURN    ${output}
55
56 Create Multiple Networks
57     [Documentation]    Create required number of networks and return a list of the resulting network ids
58     [Arguments]    @{name_of_networks}
59     ${net_list_ids} =    BuiltIn.Create List    @{EMPTY}
60     FOR    ${net}    IN    @{name_of_networks}
61         ${output} =    OpenStackOperations.Create Network    ${net}
62         ${net_id} =    Get Regexp Matches    ${output}    ${REGEX_UUID}
63         Collections.Append To List    ${net_list_ids}    ${net_id}
64     END
65     RETURN    @{net_list_ids}
66
67 Update Network
68     [Documentation]    Update Network with neutron request.
69     [Arguments]    ${network_name}    ${additional_args}=${EMPTY}
70     ${output} =    OpenStack CLI    openstack network set ${network_name} ${additional_args}
71     RETURN    ${output}
72
73 Show Network
74     [Documentation]    Show Network with neutron request.
75     [Arguments]    ${network_name}
76     ${output} =    OpenStack CLI    openstack network show ${network_name}
77     RETURN    ${output}
78
79 List Networks
80     [Documentation]    List networks and return output with neutron client.
81     ${output} =    OpenStack CLI    openstack network list
82     RETURN    ${output}
83
84 List Subnets
85     [Documentation]    List subnets and return output with neutron client.
86     ${output} =    OpenStack CLI    openstack subnet list
87     RETURN    ${output}
88
89 Delete Network
90     [Documentation]    Delete Network with neutron request.
91     [Arguments]    ${network_name}
92     ${output} =    OpenStack CLI    openstack network delete ${network_name}
93
94 Create SubNet
95     [Documentation]    Create SubNet for the Network with neutron request.
96     [Arguments]    ${network_name}    ${subnet_name}    ${range_ip}    ${additional_args}=${EMPTY}
97     ${output} =    OpenStack CLI
98     ...    openstack subnet create --network ${network_name} --subnet-range ${range_ip} ${subnet_name} ${additional_args}
99
100 Create Multiple Subnets
101     [Documentation]    Create required number of subnets for previously created networks and return subnet id
102     [Arguments]    ${network_names}    ${subnet_names}    ${subnet_cidr}
103     ${number_of_networks} =    BuiltIn.Get Length    ${network_names}
104     @{subnet_id_list} =    BuiltIn.Create List    @{EMPTY}
105     FOR    ${index}    IN RANGE    ${number_of_networks}
106         OpenStackOperations.Create SubNet
107         ...    ${network_names[${index}]}
108         ...    ${subnet_names[${index}]}
109         ...    ${subnet_cidr[${index}]}
110     END
111     ${sub_list} =    OpenStackOperations.List Subnets
112     FOR    ${index}    IN RANGE    ${number_of_networks}
113         BuiltIn.Should Contain    ${sub_list}    ${subnet_names[${index}]}
114         ${subnet_id} =    OpenStackOperations.Get Subnet Id    ${subnet_names[${index}]}
115         Collections.Append To List    ${subnet_id_list}    ${subnet_id}
116     END
117     RETURN    @{subnet_id_list}
118
119 Update SubNet
120     [Documentation]    Update subnet with openstack subnet set request.
121     [Arguments]    ${subnet_name}    ${additional_args}=${EMPTY}
122     ${output} =    OpenStack CLI    openstack subnet set ${subnet_name} ${additional_args}
123     RETURN    ${output}
124
125 Unset SubNet
126     [Documentation]    Update subnet with openstack subnet unset request
127     [Arguments]    ${subnet_name}    ${additional_args}=${EMPTY}
128     ${output} =    OpenStack CLI    openstack subnet unset ${subnet_name} ${additional_args}
129     RETURN    ${output}
130
131 Show SubNet
132     [Documentation]    Show subnet with neutron request.
133     [Arguments]    ${subnet_name}
134     ${output} =    OpenStack CLI    openstack subnet show ${subnet_name}
135     RETURN    ${output}
136
137 Create Port
138     [Documentation]    Create Port with neutron request.
139     [Arguments]    ${network_name}    ${port_name}    ${sg}=default    ${additional_args}=${EMPTY}    ${allowed_address_pairs}=${EMPTY}
140     # if allowed_address_pairs is not empty we need to create the arguments to pass to the port create command. They are
141     # in a different format with the neutron vs openstack cli.
142     ${address_pair_length} =    BuiltIn.Get Length    ${allowed_address_pairs}
143     ${allowed_pairs_argv} =    BuiltIn.Set Variable    ${EMPTY}
144     ${allowed_pairs_argv} =    BuiltIn.Set Variable If
145     ...    '${address_pair_length}'=='2'
146     ...    --allowed-address ip-address=${allowed_address_pairs}[0] --allowed-address ip-address=${allowed_address_pairs}[1]
147     ...    ${allowed_pairs_argv}
148     ${output} =    OpenStack CLI
149     ...    openstack port create --network ${network_name} ${port_name} --security-group ${sg} ${additional_args} ${allowed_pairs_argv}
150
151 Update Port
152     [Documentation]    Update port with neutron request.
153     [Arguments]    ${port_name}    ${additional_args}=${EMPTY}
154     ${output} =    OpenStack CLI    openstack port set ${port_name} ${additional_args}
155     RETURN    ${output}
156
157 Show Port
158     [Documentation]    Show port with neutron request.
159     [Arguments]    ${port_name}
160     ${output} =    OpenStack CLI    openstack port show ${port_name}
161     RETURN    ${output}
162
163 Delete Port
164     [Documentation]    Delete Port with neutron request.
165     [Arguments]    ${port_name}
166     ${output} =    OpenStack CLI    openstack port delete ${port_name}
167
168 List Ports
169     [Documentation]    List ports and return output with neutron client.
170     ${output} =    OpenStack CLI    openstack port list
171     RETURN    ${output}
172
173 List Nova VMs
174     [Documentation]    List VMs and return output with nova client.
175     ${output} =    OpenStack CLI    openstack server list --all-projects
176     RETURN    ${output}
177
178 Create And Associate Floating IPs
179     [Documentation]    Create and associate floating IPs to VMs with nova request
180     [Arguments]    ${external_net}    @{vm_list}
181     ${ip_list} =    BuiltIn.Create List    @{EMPTY}
182     FOR    ${vm}    IN    @{vm_list}
183         ${output} =    OpenStack CLI    openstack floating ip create ${external_net}
184         @{ip} =    String.Get Regexp Matches    ${output}    [0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}
185         ${ip_length} =    BuiltIn.Get Length    ${ip}
186         IF    ${ip_length}>0
187             Collections.Append To List    ${ip_list}    ${ip}[0]
188         ELSE
189             Collections.Append To List    ${ip_list}    None
190         END
191         ${vm_ip} =    OpenStack CLI
192         ...    openstack server show ${vm} | grep "addresses" | awk '{print $4}' | cut -d"=" -f 2
193         ${port_id} =    OpenStack CLI
194         ...    openstack port list | grep "ip_address='${vm_ip}'" | awk '{print $2}' | cut -d"=" -f 2
195         IF    '${OPENSTACK_BRANCH}' == 'stable/rocky'
196             ${output} =    OpenStack CLI    openstack floating ip set --port ${port_id} ${ip}[0]
197         ELSE
198             ${output} =    OpenStack CLI    openstack server add floating ip ${vm} ${ip}[0]
199         END
200     END
201     RETURN    ${ip_list}
202
203 Remove Floating Ip From Vm
204     [Documentation]    Remove the Floating IP From VM Instance
205     [Arguments]    ${vm_name}    ${fip}
206     ${vm_ip} =    OpenStack CLI
207     ...    openstack server show ${vm_name} | grep "addresses" | awk '{print $4}' | cut -d"=" -f 2
208     ${port_id} =    OpenStack CLI
209     ...    openstack port list | grep "ip_address='${vm_ip}'" | awk '{print $2}' | cut -d"=" -f 2
210     IF    '${OPENSTACK_BRANCH}' == 'stable/rocky'
211         ${output} =    OpenStack CLI    openstack floating ip unset --port ${port_id} ${fip}
212     ELSE
213         ${output} =    OpenStack CLI    openstack server remove floating ip ${vm_name} ${fip}
214     END
215
216 Delete Floating IP
217     [Documentation]    Delete floating ip with neutron request.
218     [Arguments]    ${fip}
219     ${output} =    OpenStack CLI    openstack floating ip delete ${fip}
220
221 Delete SubNet
222     [Documentation]    Delete SubNet for the Network with neutron request.
223     [Arguments]    ${subnet}
224     ${output} =    OpenStack CLI    openstack subnet delete ${subnet}
225
226 Delete Vm Instance
227     [Documentation]    Delete Vm instances using instance names.
228     [Arguments]    ${vm_name}
229     ${output} =    OpenStack CLI    openstack server delete ${vm_name}
230
231 Get Net Id
232     [Documentation]    Retrieve the net id for the given network name to create specific vm instance
233     [Arguments]    ${network_name}
234     ${output} =    OpenStack CLI    openstack network list | grep "${network_name}" | awk '{print $2}'
235     ${splitted_output} =    String.Split String    ${output}    ${EMPTY}
236     ${net_id} =    Collections.Get from List    ${splitted_output}    0
237     RETURN    ${net_id}
238
239 Get Subnet Id
240     [Documentation]    Retrieve the subnet id for the given subnet name
241     [Arguments]    ${subnet_name}
242     ${output} =    OpenStack CLI    openstack subnet show "${subnet_name}" | grep " id " | awk '{print $4}'
243     ${splitted_output} =    String.Split String    ${output}    ${EMPTY}
244     ${subnet_id} =    Collections.Get from List    ${splitted_output}    0
245     RETURN    ${subnet_id}
246
247 Get Port Id
248     [Documentation]    Retrieve the port id for the given port name to attach specific vm instance to a particular port
249     [Arguments]    ${port_name}
250     ${output} =    OpenStack CLI    openstack port list | grep "${port_name}" | awk '{print $2}'
251     ${splitted_output} =    String.Split String    ${output}    ${EMPTY}
252     ${port_id} =    Collections.Get from List    ${splitted_output}    0
253     RETURN    ${port_id}
254
255 Get Sub Port Id
256     [Documentation]    Retrieve the first 10 chars of the UUID for the given port name
257     [Arguments]    ${portname}
258     ${port_id} =    OpenStackOperations.Get Port Id    ${portname}
259     ${output} =    String.Get Regexp Matches    ${port_id}    \\w{8}-\\w{2}
260     ${subport_id} =    Collections.Get from List    ${output}    0
261     RETURN    ${subport_id}
262
263 Get Router Id
264     [Documentation]    Retrieve the router id for the given router name
265     [Arguments]    ${router1}
266     ${output} =    OpenStack CLI    openstack router show "${router1}" |awk '/ id / {print $4}'
267     ${splitted_output} =    String.Split String    ${output}    ${EMPTY}
268     ${router_id} =    Collections.Get from List    ${splitted_output}    0
269     RETURN    ${router_id}
270
271 Get VMs OVS Port Number
272     [Documentation]    Get the port number for given portname
273     [Arguments]    ${ip_address}    ${portname}
274     ${subportid} =    OpenStackOperations.Get Sub Port Id    ${portname}
275     ${vm_port_number} =    OVSDB.Get Port Number    ${subportid}    ${ip_address}
276     RETURN    ${vm_port_number}
277
278 Add New Image From Url
279     [Documentation]    To add new qcow2 images for testing.
280     [Arguments]    ${image_url}    ${image_name}
281     ${rc}    ${output} =    OperatingSystem.Run And Return Rc And Output    wget ${image_url} -O /tmp/new_image.qcow2
282     BuiltIn.Log    ${output}
283     BuiltIn.Should Be True    '${rc}' == '0'
284     ${output} =    OpenStack CLI
285     ...    openstack image create ${image_name} --file /tmp/new_image.qcow2 --disk-format qcow2 --container-format bare --public
286
287 Create Flavor
288     [Documentation]    To create new flavors for instance deployment and testing
289     [Arguments]    ${flavor_name}    ${ram_in_mb}    ${disk_in_gb}    ${ncpu}=1
290     ${output} =    OpenStack CLI
291     ...    openstack flavor create ${flavor_name} --ram ${ram_in_mb} --disk ${disk_in_gb} --vcpus ${ncpu}
292
293 Create Keypair
294     [Documentation]    To add keypairs to Openstack that can be used when ssh to instances using publickey authentication
295     [Arguments]    ${keyname}    ${public_key_file}
296     ${output} =    OpenStack CLI    openstack keypair create ${keyname} --public-key ${public_key_file}
297
298 Generate And Add Keypair
299     [Documentation]    To generate keypair using ssh-keygen and add them to Openstack
300     [Arguments]    ${keyname}    ${keyfilename}
301     ${result} =    Process.Run Process
302     ...    ssh-keygen -b 2048 -t rsa -f ${JENKINS_WORKSPACE}/${keyfilename} -q -N ""
303     ...    shell=True
304     BuiltIn.Log    ${result.stdout}
305     BuiltIn.Log    ${result.stderr}
306     BuiltIn.Should Be True    '${result.rc}' == '0'
307     OpenStackOperations.Create Keypair    ${keyname}    ${JENKINS_WORKSPACE}/${keyfilename}.pub
308     OpenStackOperations.Get ControlNode Connection
309     SSHLibrary.Put_File    ${JENKINS_WORKSPACE}/${keyfilename}    /tmp
310
311 Create Vm Instances
312     [Documentation]    Create X Vm Instance with the net id of the Netowrk.
313     [Arguments]    ${net_name}    ${vm_instance_names}    ${image}=${EMPTY}    ${flavor}=m1.nano    ${sg}=default    ${min}=1
314     ..    ${max}=1
315     ${image} =    BuiltIn.Set Variable If    "${image}"=="${EMPTY}"    ${CIRROS_${OPENSTACK_BRANCH}}    ${image}
316     ${net_id} =    OpenStackOperations.Get Net Id    ${net_name}
317     FOR    ${vm}    IN    @{vm_instance_names}
318         ${output} =    OpenStack CLI
319         ...    openstack server create --image ${image} --flavor ${flavor} --nic net-id=${net_id} ${vm} --security-group ${sg} --min ${min} --max ${max}
320     END
321
322 Create Vm Instance On Compute Node
323     [Documentation]    Create a VM instance on a specific compute node.
324     [Arguments]    ${net_name}    ${vm_name}    ${node_hostname}    ${image}=${EMPTY}    ${flavor}=m1.nano    ${sg}=default
325     ${image} =    BuiltIn.Set Variable If    "${image}"=="${EMPTY}"    ${CIRROS_${OPENSTACK_BRANCH}}    ${image}
326     ${net_id} =    OpenStackOperations.Get Net Id    ${net_name}
327     ${output} =    OpenStack CLI
328     ...    openstack server create ${vm_name} --image ${image} --flavor ${flavor} --nic net-id=${net_id} --security-group ${sg} --availability-zone nova:${node_hostname}
329
330 Create Vm Instance With Port
331     [Documentation]    Create One VM instance using given ${port_name} and for given ${compute_node}
332     [Arguments]    ${port_name}    ${vm_instance_name}    ${image}=${EMPTY}    ${flavor}=m1.nano    ${sg}=default
333     ${image} =    BuiltIn.Set Variable If    "${image}"=="${EMPTY}"    ${CIRROS_${OPENSTACK_BRANCH}}    ${image}
334     ${output} =    OpenStack CLI
335     ...    openstack server create --image ${image} --flavor ${flavor} --port ${port_name} --security-group ${sg} ${vm_instance_name}
336
337 Create Vm Instance With Ports And Key On Compute Node
338     [Documentation]    Create One VM instance using given ${port1_name} and ${port2_name} with keyname for ssh and also on a specific compute node
339     [Arguments]    ${port1_name}    ${port2_name}    ${vm_instance_name}    ${node_hostname}    ${image}=${EMPTY}    ${flavor}=m1.nano
340     ...    ${sg}=default    ${keyname}=${EMPTY}
341     ${image} =    BuiltIn.Set Variable If    "${image}"=="${EMPTY}"    ${CIRROS_${OPENSTACK_BRANCH}}    ${image}
342     ${output} =    OpenStack CLI
343     ...    openstack server create --image ${image} --flavor ${flavor} --port ${port1_name} --port ${port2_name} ${vm_instance_name} --security-group ${sg} --availability-zone nova:${node_hostname} --key-name ${keyname}
344
345 Create Vm Instance With Port On Compute Node
346     [Documentation]    Create One VM instance using given ${port_name} and for given ${node_hostname}
347     [Arguments]    ${port_name}    ${vm_instance_name}    ${node_hostname}    ${image}=${EMPTY}    ${flavor}=m1.nano    ${sg}=default
348     ${image} =    BuiltIn.Set Variable If    "${image}"=="${EMPTY}"    ${CIRROS_${OPENSTACK_BRANCH}}    ${image}
349     ${output} =    OpenStack CLI
350     ...    openstack server create --image ${image} --flavor ${flavor} --port ${port_name} --security-group ${sg} --availability-zone nova:${node_hostname} ${vm_instance_name}
351
352 Remove Security Group From Vm Instance
353     [Documentation]    Delete the Security Group from the VM Instance.
354     [Arguments]    ${vm_instance_name}    ${security_group}
355     ${output} =    OpenStack CLI    openstack server remove security group ${vm_instance_name} ${security_group}
356
357 Create Vm Instance With Ports On Compute Node
358     [Documentation]    Create One VM instance using given ${port1_name}, ${port2_name} and for given ${node_hostname} with no keys (cirros like)
359     [Arguments]    ${port1_name}    ${port2_name}    ${vm_instance_name}    ${node_hostname}    ${image}=${EMPTY}    ${flavor}=m1.nano
360     ...    ${sg}=default
361     ${image} =    BuiltIn.Set Variable If    "${image}"=="${EMPTY}"    ${CIRROS_${OPENSTACK_BRANCH}}    ${image}
362     ${port1_id} =    OpenStackOperations.Get Port Id    ${port1_name}
363     ${port2_id} =    OpenStackOperations.Get Port Id    ${port2_name}
364     ${output} =    OpenStack CLI
365     ...    openstack server create --image ${image} --flavor ${flavor} --nic port-id=${port1_id} --nic port-id=${port2_id} --security-group ${sg} --availability-zone nova:${node_hostname} ${vm_instance_name}
366
367 Get Hypervisor Hostname From IP
368     [Documentation]    Returns the hostname found for the given IP address if it's listed in hypervisor list. For debuggability
369     ...    the full listing is logged first, then followed by a grep | cut to focus on the actual hostname to return
370     [Arguments]    ${hypervisor_ip}
371     ${output} =    OpenStack CLI    openstack hypervisor list
372     ${hostname} =    OpenStack CLI    openstack hypervisor list -f value | grep "${hypervisor_ip} " | cut -d" " -f 2
373     RETURN    ${hostname}
374
375 Create Nano Flavor
376     [Documentation]    Create a nano flavor
377     ${output} =    OpenStack CLI    openstack flavor create m1.nano --id auto --ram 64 --disk 0 --vcpus 1
378
379 Verify VM Is ACTIVE
380     [Documentation]    Run these commands to check whether the created vm instance is active or not.
381     [Arguments]    ${vm_name}
382     OpenStack CLI    openstack server show ${vm_name}
383     ${output} =    OpenStack CLI    openstack server show ${vm_name} | grep OS-EXT-STS:vm_state
384     BuiltIn.Should Contain    ${output}    active
385
386 Poll VM Is ACTIVE
387     [Documentation]    Run these commands to check whether the created vm instance is active or not.
388     [Arguments]    ${vm_name}    ${retry}=600s    ${retry_interval}=30s
389     BuiltIn.Wait Until Keyword Succeeds
390     ...    ${retry}
391     ...    ${retry_interval}
392     ...    OpenStackOperations.Verify VM Is ACTIVE
393     ...    ${vm_name}
394
395 Get Match
396     [Documentation]    Wrapper around String.Get Regexp Matches to return None if not found or the first match if found.
397     [Arguments]    ${text}    ${regexp}    ${index}=0
398     @{matches} =    String.Get Regexp Matches    ${text}    ${regexp}
399     ${matches_length} =    BuiltIn.Get Length    ${matches}
400     BuiltIn.Set Suite Variable    ${OS_MATCH}    None
401     IF    ${matches_length} > ${index}
402         BuiltIn.Set Suite Variable    ${OS_MATCH}    ${matches}[${index}]
403     END
404     RETURN    ${OS_MATCH}
405
406 Get VM IP
407     [Documentation]    Get the vm ip address and nameserver by scraping the vm's console log.
408     ...    Get VM IP returns three values: [0] the vm IP, [1] the DHCP IP and [2] the vm console log.
409     [Arguments]    ${fail_on_none}    ${vm}
410     ${vm_console_output} =    OpenStack CLI With No Log    openstack console log show ${vm}
411     ${vm_ip} =    BuiltIn.Set Variable    None
412     ${dhcp_ip} =    BuiltIn.Set Variable    None
413     ${match} =    OpenStackOperations.Get Match    ${vm_console_output}    ${REGEX_OBTAINED}
414     ${vm_ip} =    OpenStackOperations.Get Match    ${match}    ${REGEX_IPV4}    0
415     ${match} =    OpenStackOperations.Get Match    ${vm_console_output}    ${REGEX_IPROUTE}
416     ${dhcp_ip} =    OpenStackOperations.Get Match    ${match}    ${REGEX_IPV4}    1
417     IF    '${fail_on_none}' == 'true'
418         BuiltIn.Should Not Contain    ${vm_ip}    None
419     END
420     IF    '${fail_on_none}' == 'true'
421         BuiltIn.Should Not Contain    ${dhcp_ip}    None
422     END
423     RETURN    ${vm_ip}    ${dhcp_ip}    ${vm_console_output}
424
425 Verify If Instance Is Arpingable From DHCP Namespace
426     [Documentation]    Get the Port IP and check the arp -a from DHCP NS to ensure that the VM's have been assigned IP's
427     [Arguments]    ${net_name}    ${mac}    ${ip}
428     OpenStackOperations.Get ControlNode Connection
429     ${net_id} =    OpenStackOperations.Get Net Id    ${net_name}
430     ${output} =    Utils.Write Commands Until Expected Prompt
431     ...    sudo ip netns exec qdhcp-${net_id} arping ${ip} -c3
432     ...    ${DEFAULT_LINUX_PROMPT_STRICT}
433     ...    timeout=60s
434     ${mac_uppercase} =    String.Convert To Upper Case    ${mac}
435     BuiltIn.Should Contain    ${output}    [${mac_uppercase}]
436
437 Check If Instance Is Ready For Ssh Login Using PublicKey
438     [Documentation]    Ensure the VM is reachable from ssh as tests would require. This keyword will use publickey authentication
439     [Arguments]    ${net_name}    ${vm_ip}    ${user}=centos    ${idfile}=/tmp/odlkey    ${console}=cirros
440     ${output} =    Execute Command on VM Instance with PublicKey Auth
441     ...    ${net_name}
442     ...    ${vm_ip}
443     ...    ifconfig
444     ...    user=${user}
445     ...    idfile=${idfile}
446     ...    console=${console}
447     BuiltIn.Should Contain    ${output}    ${vm_ip}
448
449 Check If Instance Is Ready For Ssh Login Using Password
450     [Documentation]    Ensure the VM is reachable from ssh as tests would require. This keyword will use password authentication
451     [Arguments]    ${net_name}    ${vm_ip}    ${user}=cirros    ${password}=${EMPTY}    ${console}=cirros
452     ${password} =    BuiltIn.Set Variable If    "${password}"=="${EMPTY}"    ${PASSWORD_CIRROS_${OPENSTACK_BRANCH}}
453     ${output} =    Execute Command on VM Instance    ${net_name}    ${vm_ip}    ifconfig    ${user}    ${password}
454     ...    console=${console}
455     BuiltIn.Should Contain    ${output}    ${vm_ip}
456
457 Get VM IPs
458     [Documentation]    Get the instance IP addresses and nameserver address for the list of given vms.
459     ...    First poll for the vm instance to be in the active state, then poll for the vm ip address and nameserver.
460     ...    Get VM IPs returns two things: [0] a list of the ips for the vms passed to this keyword (may contain values
461     ...    of None) and [1] the dhcp ip address found in the last vm checked.
462     ...    TODO: there is a potential issue for a caller that passes in VMs belonging to different networks that
463     ...    may have different dhcp server addresses. Not sure what TODO about that, but noting it here for reference.
464     [Arguments]    @{vms}
465     @{vm_ips} =    BuiltIn.Create List    @{EMPTY}
466     FOR    ${vm}    IN    @{vms}
467         OpenStackOperations.Poll VM Is ACTIVE    ${vm}
468         ${status}    ${ips_and_console_log} =    BuiltIn.Run Keyword And Ignore Error
469         ...    BuiltIn.Wait Until Keyword Succeeds
470         ...    180s
471         ...    15s
472         ...    OpenStackOperations.Get VM IP
473         ...    true
474         ...    ${vm}
475         # If there is trouble with Get VM IP, the status will be FAIL and the return value will be a string of what went
476         # wrong. We need to handle both the PASS and FAIL cases. In the FAIL case we know we wont have access to the
477         # console log, as it would not be returned; so we need to grab it again to log it. We also can append 'None' to
478         # the vm ip list if status is FAIL.
479         IF    "${status}" == "PASS"    BuiltIn.Log    ${ips_and_console_log[2]}
480         IF    "${status}" == "PASS"
481             Collections.Append To List    ${vm_ips}    ${ips_and_console_log[0]}
482         END
483         IF    "${status}" == "FAIL"
484             Collections.Append To List    ${vm_ips}    None
485         END
486         IF    "${status}" == "FAIL"
487             ${vm_console_output} =    OpenStack CLI    openstack console log show ${vm}
488         ELSE
489             ${vm_console_output} =    Set Variable    ${None}
490         END
491         IF    "${status}" == "FAIL"    BuiltIn.Log    ${vm_console_output}
492     END
493     OpenStackOperations.Copy DHCP Files From Control Node
494     RETURN    @{vm_ips}    ${ips_and_console_log[1]}
495
496 Get All VM IP Addresses
497     [Documentation]    Show information of a given two port VM and grep for two ip address. VM name should be sent as arguments.
498     [Arguments]    ${conn_id}    ${vm_name}
499     SSHLibrary.Switch Connection    ${conn_id}
500     ${cmd} =    BuiltIn.Set Variable    openstack server show ${vm_name}
501     ${output} =    OpenStackOperations.OpenStack CLI    ${cmd}
502     BuiltIn.Log    ${output}
503     ${address_output} =    OpenStackOperations.OpenStack CLI    ${cmd} | grep "addresses" | awk '{print $4$5}'
504     @{vm_ips} =    String.Get Regexp Matches    ${address_output}    ${REGEX_IPV4}
505     RETURN    @{vm_ips}
506
507 Get Subnet Gateway Ip
508     [Documentation]    Show information of a subnet and grep for subnet gateway ip address
509     [Arguments]    ${subnet_name}
510     ${output} =    OpenStackOperations.OpenStack CLI
511     ...    openstack subnet show ${subnet_name} | grep gateway_ip | awk '{print $4}'
512     ${splitted_output} =    String.Split String    ${output}    ${EMPTY}
513     ${matches} =    Collections.Get Matches    ${splitted_output}    regexp=(\\d\.)+
514     ${subnet_gateway_ip} =    String.Strip String    ${matches[0]}    characters=','
515     RETURN    ${subnet_gateway_ip}
516
517 Collect VM IPv6 SLAAC Addresses
518     [Documentation]    For each VM parse output of "openstack server show" to get its IPv6 address from Neutron DB.
519     ...    Then try to connect to each VM by SSH and execute there "ip -6 a" command. This double-check allows to
520     ...    obtain and compare IP info (Neutron DB vs dnsmasque/ODL DHCP) and to test L2 connectivity as well.
521     ...    Returns an empty list if no IPv6 addresses found or if SSH connection fails.
522     ...    Otherwise, returns a list of IPv6 addresses.
523     [Arguments]    ${fail_on_none}    ${vm_list}    ${network}    ${subnet}
524     ${ipv6_list} =    BuiltIn.Create List    @{EMPTY}
525     FOR    ${vm}    IN    @{vm_list}
526         ${output} =    OpenStack CLI    openstack server show ${vm} -f shell
527         ${pattern} =    String.Replace String    ${subnet}    ::/64    (:[a-f0-9]{,4}){,4}
528         @{vm_ipv6} =    String.Get Regexp Matches    ${output}    ${pattern}
529         ${vm_ip_length} =    BuiltIn.Get Length    ${vm_ipv6}[0]
530         IF    ${vm_ip_length}>0
531             ${ipv6_data_from_vm} =    OpenStackOperations.Execute Command on VM Instance
532             ...    ${network}
533             ...    ${vm_ipv6[0]}
534             ...    ip -6 a
535         ELSE
536             ${ipv6_data_from_vm} =    Set Variable    ${None}
537         END
538         @{ipv6} =    String.Get Regexp Matches    ${ipv6_data_from_vm}    ${pattern}
539         ${ipv6_addr_list_length} =    BuiltIn.Get Length    @{ipv6}
540         IF    ${ipv6_addr_list_length}>0
541             Collections.Append To List    ${ipv6_list}    ${ipv6[0]}
542         ELSE
543             Collections.Append To List    ${ipv6_list}    None
544         END
545     END
546     RETURN    ${ipv6_list}
547
548 View Vm Console
549     [Documentation]    View Console log of the created vm instances using nova show.
550     [Arguments]    ${vm_instance_names}
551     FOR    ${vm}    IN    @{vm_instance_names}
552         ${output} =    OpenStack CLI    openstack server show ${vm}
553         ${output} =    OpenStack CLI    openstack console log show ${vm}
554     END
555
556 Ping Vm From DHCP Namespace
557     [Documentation]    Reach all Vm Instance with the net id of the Netowrk.
558     [Arguments]    ${net_name}    ${vm_ip}
559     OpenStackOperations.Get ControlNode Connection
560     ${net_id} =    OpenStackOperations.Get Net Id    ${net_name}
561     ${output} =    DevstackUtils.Write Commands Until Prompt And Log
562     ...    sudo ip netns exec qdhcp-${net_id} ping -c 3 ${vm_ip}
563     ...    20s
564     BuiltIn.Should Contain    ${output}    64 bytes
565
566 Ping From DHCP Should Not Succeed
567     [Documentation]    Should Not Reach Vm Instance with the net id of the Netowrk.
568     [Arguments]    ${net_name}    ${vm_ip}
569     IF    "skip_if_${SECURITY_GROUP_MODE}" in @{TEST_TAGS}    RETURN
570     OpenStackOperations.Get ControlNode Connection
571     ${net_id} =    OpenStackOperations.Get Net Id    ${net_name}
572     ${output} =    DevstackUtils.Write Commands Until Prompt And Log
573     ...    sudo ip netns exec qdhcp-${net_id} ping -c 3 ${vm_ip}
574     ...    20s
575     BuiltIn.Should Not Contain    ${output}    64 bytes
576
577 Ping Vm From Control Node
578     [Documentation]    Ping VM floating IP from control node
579     [Arguments]    ${vm_floating_ip}    ${additional_args}=${EMPTY}
580     OpenStackOperations.Get ControlNode Connection
581     ${output} =    DevstackUtils.Write Commands Until Prompt And Log
582     ...    ping ${additional_args} -c 3 ${vm_floating_ip}
583     ...    20s
584     BuiltIn.Should Contain    ${output}    64 bytes
585
586 Curl Metadata Server
587     [Documentation]    Ping to the expected destination ip.
588     ${output} =    Utils.Write Commands Until Expected Prompt    curl -i http://169.254.169.254    ${OS_SYSTEM_PROMPT}
589     DevstackUtils.Write Commands Until Prompt    exit
590     BuiltIn.Should Contain    ${output}    200
591
592 Close Vm Instance
593     [Documentation]    Exit the vm instance.
594     ${output} =    DevstackUtils.Write Commands Until Prompt And Log    exit
595
596 Check If Console Is VmInstance
597     [Documentation]    Check if the session has been able to login to the VM instance
598     [Arguments]    ${console}=cirros
599     ${output} =    Utils.Write Commands Until Expected Prompt    id    ${OS_SYSTEM_PROMPT}
600     BuiltIn.Should Contain    ${output}    ${console}
601
602 Exit From Vm Console
603     [Documentation]    Check if the session has been able to login to the VM instance and exit the instance
604     [Arguments]    ${console}=cirros
605     ${rcode} =    BuiltIn.Run Keyword And Return Status
606     ...    OpenStackOperations.Check If Console Is VmInstance
607     ...    ${console}
608     IF    ${rcode}    DevstackUtils.Write Commands Until Prompt    exit
609
610 Check Ping
611     [Documentation]    Run Ping command on the IP available as argument
612     [Arguments]    ${ip_address}    ${ttl}=64    ${ping_tries}=3
613     ${ethertype} =    String.Get Regexp Matches    ${ip_address}    ${IP_REGEX}
614     ${ping} =    BuiltIn.Set Variable If    ${ethertype}    ping    ping6
615     ${cmd} =    BuiltIn.Set Variable
616     ...    rc=0; for count in `seq 1 ${ping_tries}`; do ${ping} -W1 -t${ttl} -c5 ${ip_address}; rc=$?; if [ $rc -eq 0 ]; then break; fi; done; echo ping_rc=$rc
617     ${output} =    Utils.Write Commands Until Expected Regexp    ${cmd}    ping_rc=\\d+    120
618     BuiltIn.Log    output: ${output}
619     BuiltIn.Should Contain    ${output}    64 bytes
620
621 Check No Ping
622     [Documentation]    Run Ping command to the IP given as argument, executing 3 times and expecting NOT to see "64 bytes"
623     [Arguments]    ${ip_address}    ${ttl}=64
624     ${output} =    Utils.Write Commands Until Expected Prompt
625     ...    ping -t ${ttl} -c 3 ${ip_address}
626     ...    ${OS_SYSTEM_PROMPT}
627     BuiltIn.Should Not Contain    ${output}    64 bytes
628
629 Check Metadata Access
630     [Documentation]    Try curl on the Metadataurl and check if it is okay
631     ${output} =    Utils.Write Commands Until Expected Prompt    curl -i http://169.254.169.254    ${OS_SYSTEM_PROMPT}
632     BuiltIn.Should Contain    ${output}    200
633
634 Execute Command on VM Instance
635     [Documentation]    Login to the vm instance using ssh in the network, executes a command inside the VM and returns the ouput.
636     [Arguments]    ${net_name}    ${vm_ip}    ${cmd}    ${user}=cirros    ${password}=${EMPTY}    ${cmd_timeout}=30s
637     ...    ${console}=cirros
638     ${password} =    BuiltIn.Set Variable If    "${password}"=="${EMPTY}"    ${PASSWORD_CIRROS_${OPENSTACK_BRANCH}}
639     OpenStackOperations.Get ControlNode Connection
640     ${net_id} =    OpenStackOperations.Get Net Id    ${net_name}
641     ${output} =    Utils.Write Commands Until Expected Prompt
642     ...    sudo ip netns exec qdhcp-${net_id} ssh ${user}@${vm_ip} -o MACs=hmac-sha1 -o ConnectTimeout=5 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o PreferredAuthentications=password
643     ...    password:
644     ${output} =    Utils.Write Commands Until Expected Prompt    ${password}    ${OS_SYSTEM_PROMPT}
645     ${rcode} =    BuiltIn.Run Keyword And Return Status
646     ...    OpenStackOperations.Check If Console Is VmInstance
647     ...    ${console}
648     IF    ${rcode}
649         ${output} =    Utils.Write Commands Until Expected Prompt
650         ...    ${cmd}
651         ...    ${OS_SYSTEM_PROMPT}
652         ...    timeout=${cmd_timeout}
653     ELSE
654         ${output} =    Set Variable    ${None}
655     END
656     RETURN    ${output}
657     [Teardown]    Exit From Vm Console    ${console}
658
659 Execute Command on VM Instance With PublicKey Auth
660     [Documentation]    Login to the vm instance using ssh publickey in the network, executes a command inside the VM and returns the ouput.
661     [Arguments]    ${net_name}    ${vm_ip}    ${cmd}    ${user}=centos    ${idfile}=/tmp/odlkey    ${console}=cirros
662     OpenStackOperations.Get ControlNode Connection
663     ${net_id} =    OpenStackOperations.Get Net Id    ${net_name}
664     ${output} =    Utils.Write Commands Until Expected Prompt
665     ...    sudo ip netns exec qdhcp-${net_id} ssh -i ${idfile} ${user}@${vm_ip} -o MACs=hmac-sha1 -o ConnectTimeout=5 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o PreferredAuthentications=publickey
666     ...    prompt=${OS_SYSTEM_PROMPT}
667     ...    timeout=60s
668     ${rcode} =    BuiltIn.Run Keyword And Return Status
669     ...    OpenStackOperations.Check If Console Is VmInstance
670     ...    ${console}
671     IF    ${rcode}
672         ${output} =    Utils.Write Commands Until Expected Prompt    ${cmd}    ${OS_SYSTEM_PROMPT}
673     ELSE
674         ${output} =    Set Variable    ${None}
675     END
676     RETURN    ${output}
677     [Teardown]    Exit From Vm Console    ${console}
678
679 Copy File To VM Instance With PublicKey Auth
680     [Documentation]    Login to the vm instance using ssh publickey in the network, executes a command inside the VM and returns the ouput.
681     [Arguments]    ${net_name}    ${vm_ip}    ${file_to_copy}    ${user}=centos    ${idfile}=/tmp/odlkey
682     OpenStackOperations.Get ControlNode Connection
683     ${net_id} =    OpenStackOperations.Get Net Id    ${net_name}
684     ${rc} =    SSHLibrary.Execute Command
685     ...    sudo ip netns exec qdhcp-${net_id} scp -i ${idfile} -o MACs=hmac-sha1 -o ConnectTimeout=5 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o PreferredAuthentications=publickey ${file_to_copy} ${user}@${vm_ip}:/tmp/
686     ...    return_stdout=False
687     ...    return_rc=True
688     BuiltIn.Should Be True    '${rc}' == '0'
689
690 Test Operations From Vm Instance
691     [Documentation]    Login to the vm instance using ssh in the network.
692     [Arguments]    ${net_name}    ${src_ip}    ${dest_ips}    ${user}=cirros    ${password}=${EMPTY}    ${ttl}=64
693     ...    ${ping_should_succeed}=True    ${check_metadata}=True    ${console}=cirros    ${ping_tries}=3
694     ${password} =    BuiltIn.Set Variable If    "${password}"=="${EMPTY}"    ${PASSWORD_CIRROS_${OPENSTACK_BRANCH}}
695     OpenStackOperations.Get ControlNode Connection
696     ${net_id} =    OpenStackOperations.Get Net Id    ${net_name}
697     ${output} =    Utils.Write Commands Until Expected Prompt
698     ...    sudo ip netns exec qdhcp-${net_id} ssh -o MACs=hmac-sha1 -o ConnectTimeout=5 -o StrictHostKeyChecking=no ${user}@${src_ip} -o UserKnownHostsFile=/dev/null
699     ...    password:
700     ...    10s
701     ${output} =    Utils.Write Commands Until Expected Prompt    ${password}    ${OS_SYSTEM_PROMPT}
702     ${rcode} =    BuiltIn.Run Keyword And Return Status
703     ...    OpenStackOperations.Check If Console Is VmInstance
704     ...    ${console}
705     IF    ${rcode}
706         Utils.Write Commands Until Expected Prompt    ifconfig    ${OS_SYSTEM_PROMPT}
707     END
708     IF    ${rcode}
709         Utils.Write Commands Until Expected Prompt    route -n    ${OS_SYSTEM_PROMPT}
710     END
711     IF    ${rcode}
712         Utils.Write Commands Until Expected Prompt    route -A inet6    ${OS_SYSTEM_PROMPT}
713     END
714     IF    ${rcode}
715         Utils.Write Commands Until Expected Prompt    arp -an    ${OS_SYSTEM_PROMPT}
716     END
717     IF    ${rcode}
718         Utils.Write Commands Until Expected Prompt    ip -f inet6 neigh show    ${OS_SYSTEM_PROMPT}
719     END
720     FOR    ${dest_ip}    IN    @{dest_ips}
721         ${string_empty} =    BuiltIn.Run Keyword And Return Status    Should Be Empty    ${dest_ip}
722         IF    ${string_empty}            CONTINUE
723         IF    ${rcode} and "${ping_should_succeed}" == "True"
724             OpenStackOperations.Check Ping    ${dest_ip}    ttl=${ttl}    ping_tries=${ping_tries}
725         ELSE
726             OpenStackOperations.Check No Ping    ${dest_ip}    ttl=${ttl}
727         END
728     END
729     ${ethertype} =    String.Get Regexp Matches    ${src_ip}    ${IP_REGEX}
730     IF    ${rcode} and "${check_metadata}" and ${ethertype} == "True"
731         OpenStackOperations.Check Metadata Access
732     END
733     [Teardown]    Exit From Vm Console    ${console}
734
735 Test Netcat Operations From Vm Instance
736     [Documentation]    Use Netcat to test TCP/UDP connections to the controller
737     [Arguments]    ${net_name}    ${vm_ip}    ${dest_ip}    ${additional_args}=${EMPTY}    ${port}=12345    ${user}=cirros
738     ...    ${password}=${EMPTY}
739     ${password} =    BuiltIn.Set Variable If    "${password}"=="${EMPTY}"    ${PASSWORD_CIRROS_${OPENSTACK_BRANCH}}
740     ${client_data} =    BuiltIn.Set Variable    Test Client Data
741     ${server_data} =    BuiltIn.Set Variable    Test Server Data
742     OpenStackOperations.Get ControlNode Connection
743     ${output} =    DevstackUtils.Write Commands Until Prompt And Log
744     ...    ( ( echo "${server_data}" | sudo timeout 60 nc -l ${additional_args} ${port} ) & )
745     ${output} =    DevstackUtils.Write Commands Until Prompt And Log    sudo netstat -nlap | grep ${port}
746     ${nc_output} =    OpenStackOperations.Execute Command on VM Instance
747     ...    ${net_name}
748     ...    ${vm_ip}
749     ...    sudo echo "${client_data}" | nc -v -w 5 ${additional_args} ${dest_ip} ${port}
750     BuiltIn.Log    ${output}
751     ${output} =    OpenStackOperations.Execute Command on VM Instance    ${net_name}    ${vm_ip}    sudo route -n
752     BuiltIn.Log    ${output}
753     ${output} =    OpenStackOperations.Execute Command on VM Instance    ${net_name}    ${vm_ip}    sudo arp -an
754     BuiltIn.Log    ${output}
755     BuiltIn.Should Match Regexp    ${nc_output}    ${server_data}
756
757 Ping Other Instances
758     [Documentation]    Check reachability with other network's instances.
759     [Arguments]    ${list_of_external_dst_ips}    ${console}=cirros
760     ${rcode} =    BuiltIn.Run Keyword And Return Status
761     ...    OpenStackOperations.Check If Console Is VmInstance
762     ...    ${console}
763     FOR    ${dest_ip}    IN    @{list_of_external_dst_ips}
764         OpenStackOperations.Check Ping    ${dest_ip}
765     END
766
767 Create Router
768     [Documentation]    Create Router and Add Interface to the subnets.
769     [Arguments]    ${router_name}
770     ${output} =    OpenStack CLI    openstack router create ${router_name}
771
772 List Routers
773     [Documentation]    List Routers and return output with neutron client.
774     ${output} =    OpenStack CLI    openstack router list -f value
775     RETURN    ${output}
776
777 Add Router Interface
778     [Arguments]    ${router_name}    ${interface_name}
779     ${output} =    OpenStack CLI    openstack router add subnet ${router_name} ${interface_name}
780
781 Show Router Interface
782     [Documentation]    List Routers interface associated with given Router and return output with neutron client.
783     [Arguments]    ${router_name}
784     ${output} =    OpenStack CLI    openstack port list --router ${router_name} -f value
785     RETURN    ${output}
786
787 Add Router Gateway
788     [Arguments]    ${router_name}    ${external_network_name}    ${additional_args}=${EMPTY}
789     ${output} =    OpenStack CLI
790     ...    openstack router set ${router_name} --external-gateway ${external_network_name} ${additional_args}
791
792 Remove Interface
793     [Documentation]    Remove Interface to the subnets.
794     [Arguments]    ${router_name}    ${interface_name}
795     ${output} =    OpenStack CLI    openstack router remove subnet ${router_name} ${interface_name}
796
797 Remove Gateway
798     [Documentation]    Remove external gateway from the router.
799     [Arguments]    ${router_name}
800     ${output} =    OpenStack CLI    openstack router unset ${router_name} --external-gateway
801
802 Update Router
803     [Documentation]    Update the router with the command. Router name and command should be passed as argument.
804     [Arguments]    ${router_name}    ${cmd}
805     ${output} =    OpenStack CLI    openstack router set ${router_name} ${cmd}
806
807 Show Router
808     [Documentation]    Show information of a given router. Router name and optional fields should be sent as arguments.
809     [Arguments]    ${router_name}    ${additional_args}=${EMPTY}
810     ${output} =    OpenStack CLI    openstack router show ${router_name} ${additional_args}
811     RETURN    ${output}
812
813 Delete Router
814     [Documentation]    Delete Router and Interface to the subnets.
815     [Arguments]    ${router_name}
816     ${output} =    OpenStack CLI    openstack router delete ${router_name}
817
818 Get DumpFlows And Ovsconfig
819     [Documentation]    Get the OvsConfig and Flow entries from OVS from the Openstack Node
820     [Arguments]    ${conn_id}
821     SSHLibrary.Switch Connection    ${conn_id}
822     Utils.Write Commands Until Expected Prompt    ip -o link    ${DEFAULT_LINUX_PROMPT_STRICT}
823     Utils.Write Commands Until Expected Prompt    ip -o addr    ${DEFAULT_LINUX_PROMPT_STRICT}
824     Utils.Write Commands Until Expected Prompt    ip route    ${DEFAULT_LINUX_PROMPT_STRICT}
825     Utils.Write Commands Until Expected Prompt    arp -an    ${DEFAULT_LINUX_PROMPT_STRICT}
826     ${nslist} =    Utils.Write Commands Until Expected Prompt
827     ...    ip netns list | awk '{print $1}'
828     ...    ${DEFAULT_LINUX_PROMPT_STRICT}
829     @{lines} =    Split To Lines    ${nslist}    end=-1
830     FOR    ${line}    IN    @{lines}
831         Utils.Write Commands Until Expected Prompt
832         ...    sudo ip netns exec ${line} ip -o link
833         ...    ${DEFAULT_LINUX_PROMPT_STRICT}
834         Utils.Write Commands Until Expected Prompt
835         ...    sudo ip netns exec ${line} ip -o addr
836         ...    ${DEFAULT_LINUX_PROMPT_STRICT}
837         Utils.Write Commands Until Expected Prompt
838         ...    sudo ip netns exec ${line} ip route
839         ...    ${DEFAULT_LINUX_PROMPT_STRICT}
840     END
841     Utils.Write Commands Until Expected Prompt    sudo ovs-vsctl show    ${DEFAULT_LINUX_PROMPT_STRICT}
842     Utils.Write Commands Until Expected Prompt    sudo ovs-vsctl list Open_vSwitch    ${DEFAULT_LINUX_PROMPT_STRICT}
843     Utils.Write Commands Until Expected Prompt
844     ...    sudo ovs-ofctl show ${INTEGRATION_BRIDGE} -OOpenFlow13
845     ...    ${DEFAULT_LINUX_PROMPT_STRICT}
846     Utils.Write Commands Until Expected Prompt
847     ...    sudo ovs-ofctl dump-flows ${INTEGRATION_BRIDGE} -OOpenFlow13
848     ...    ${DEFAULT_LINUX_PROMPT_STRICT}
849     Utils.Write Commands Until Expected Prompt
850     ...    sudo ovs-ofctl dump-groups ${INTEGRATION_BRIDGE} -OOpenFlow13
851     ...    ${DEFAULT_LINUX_PROMPT_STRICT}
852     Utils.Write Commands Until Expected Prompt
853     ...    sudo ovs-ofctl dump-group-stats ${INTEGRATION_BRIDGE} -OOpenFlow13
854     ...    ${DEFAULT_LINUX_PROMPT_STRICT}
855
856 Get ControlNode Connection
857     SSHLibrary.Switch Connection    ${OS_CNTL_CONN_ID}
858     RETURN    ${OS_CNTL_CONN_ID}
859
860 Get OvsDebugInfo
861     [Documentation]    Get the OvsConfig and Flow entries from all Openstack nodes
862     FOR    ${conn_id}    IN    @{OS_ALL_CONN_IDS}
863         OpenStackOperations.Get DumpFlows And Ovsconfig    ${conn_id}
864     END
865
866 Show Debugs
867     [Documentation]    Run these commands for debugging, it can list state of VM instances and ip information in control node
868     [Arguments]    @{vm_indices}
869     OpenStackOperations.Get ControlNode Connection
870     ${output} =    DevstackUtils.Write Commands Until Prompt And Log    sudo ip netns list
871     FOR    ${index}    IN    @{vm_indices}
872         ${rc}    ${output} =    OperatingSystem.Run And Return Rc And Output    nova show ${index}
873         BuiltIn.Log    ${output}
874     END
875     OpenStackOperations.List Nova VMs
876     OpenStackOperations.List Routers
877     OpenStackOperations.List Networks
878     OpenStackOperations.List Subnets
879     OpenStackOperations.List Ports
880     OpenStackOperations.List Security Groups
881
882 List Security Groups
883     [Documentation]    Logging keyword to display all security groups using the openstack cli. Assumes openstack
884     ...    credentials are already sourced
885     ${output} =    OpenStack CLI    openstack security group list
886     RETURN    ${output}
887
888 Neutron Security Group Show
889     [Documentation]    Displays the neutron security group configurations that belongs to a given neutron security group name
890     [Arguments]    ${SecurityGroupRuleName}
891     ${output} =    OpenStack CLI    openstack security group show ${SecurityGroupRuleName}
892     RETURN    ${output}
893
894 Neutron Port Show
895     [Documentation]    Display the port configuration that belong to a given neutron port
896     [Arguments]    ${PortName}
897     ${output} =    OpenStack CLI    openstack port show ${PortName}
898     RETURN    ${output}
899
900 Neutron Security Group Create
901     [Documentation]    Create a security group with specified name ,description & protocol value according to security group template
902     [Arguments]    ${SecurityGroupName}    ${additional_args}=${EMPTY}
903     OpenStackOperations.Get ControlNode Connection
904     ${output} =    OpenStack CLI    openstack security group create ${SecurityGroupName} ${additional_args}
905     ${sgp_id} =    BuiltIn.Should Match Regexp    ${output}    ${REGEX_UUID}
906     RETURN    ${output}    ${sgp_id}
907
908 Neutron Security Group Update
909     [Documentation]    Updating security groups
910     [Arguments]    ${SecurityGroupName}    ${additional_args}=${EMPTY}
911     ${output} =    OpenStack CLI    openstack security group set ${SecurityGroupName} ${additional_args}
912     RETURN    ${output}
913
914 Delete SecurityGroup
915     [Documentation]    Delete Security group
916     [Arguments]    ${sg_name}
917     ${output} =    OpenStack CLI    openstack security group delete ${sg_name}
918
919 Neutron Security Group Rule Create
920     [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 BuiltIn.Catenated with mandatory args, example of usage: "OpenStack Neutron Security Group Rule Create ${SGP_SSH} direction=${RULE_PARAMS[0]} ethertype=${RULE_PARAMS[1]} ..."
921     [Arguments]    ${Security_group_name}    &{Kwargs}
922     IF    ${Kwargs}    BuiltIn.Log    ${Kwargs}
923     IF    ${Kwargs}
924         ${description} =    Collections.Pop From Dictionary    ${Kwargs}    description    default=${None}
925     ELSE
926         ${description} =    Set Variable    ${None}
927     END
928     IF    ${Kwargs}
929         ${direction} =    Collections.Pop From Dictionary    ${Kwargs}    direction    default=${None}
930     ELSE
931         ${direction} =    Set Variable    ${None}
932     END
933     IF    ${Kwargs}
934         ${ethertype} =    Collections.Pop From Dictionary    ${Kwargs}    ethertype    default=${None}
935     ELSE
936         ${ethertype} =    Set Variable    ${None}
937     END
938     IF    ${Kwargs}
939         ${port_range_max} =    Collections.Pop From Dictionary    ${Kwargs}    port_range_max    default=${None}
940     ELSE
941         ${port_range_max} =    Set Variable    ${None}
942     END
943     IF    ${Kwargs}
944         ${port_range_min} =    Collections.Pop From Dictionary    ${Kwargs}    port_range_min    default=${None}
945     ELSE
946         ${port_range_min} =    Set Variable    ${None}
947     END
948     IF    ${Kwargs}
949         ${protocol} =    Collections.Pop From Dictionary    ${Kwargs}    protocol    default=${None}
950     ELSE
951         ${protocol} =    Set Variable    ${None}
952     END
953     IF    ${Kwargs}
954         ${remote_group_id} =    Collections.Pop From Dictionary    ${Kwargs}    remote_group_id    default=${None}
955     ELSE
956         ${remote_group_id} =    Set Variable    ${None}
957     END
958     IF    ${Kwargs}
959         ${remote_ip_prefix} =    Collections.Pop From Dictionary    ${Kwargs}    remote_ip_prefix    default=${None}
960     ELSE
961         ${remote_ip_prefix} =    Set Variable    ${None}
962     END
963     IF    ${Kwargs}
964         ${remote_ip} =    Collections.Pop From Dictionary    ${Kwargs}    remote_ip    default=${None}
965     ELSE
966         ${remote_ip} =    Set Variable    ${None}
967     END
968     ${cmd} =    BuiltIn.Set Variable    openstack security group rule create ${Security_group_name}
969     IF    '${description}'!='None'
970         ${cmd} =    BuiltIn.Catenate    ${cmd}    --description ${description}
971     ELSE
972         ${cmd} =    BuiltIn.Catenate    ${cmd}
973     END
974     IF    '${direction}'!='None'
975         ${cmd} =    BuiltIn.Catenate    ${cmd}    --${direction}
976     ELSE
977         ${cmd} =    BuiltIn.Catenate    ${cmd}
978     END
979     IF    '${ethertype}'!='None'
980         ${cmd} =    BuiltIn.Catenate    ${cmd}    --ethertype ${ethertype}
981     ELSE
982         ${cmd} =    BuiltIn.Catenate    ${cmd}
983     END
984     IF    '${port_range_min}'!='None' and '${port_range_max}'!='None'
985         ${cmd} =    BuiltIn.Catenate    ${cmd}    --dst-port ${port_range_min}:${port_range_max}
986     ELSE IF    '${port_range_max}'!='None'
987         ${cmd} =    BuiltIn.Catenate    ${cmd}    --dst-port ${port_range_max}
988     ELSE IF    '${port_range_min}'!='None'
989         ${cmd} =    BuiltIn.Catenate    ${cmd}    --dst-port ${port_range_min}
990     ELSE
991         ${cmd} =    BuiltIn.Catenate    ${cmd}
992     END
993     IF    '${protocol}'!='None'
994         ${cmd} =    BuiltIn.Catenate    ${cmd}    --protocol ${protocol}
995     ELSE
996         ${cmd} =    BuiltIn.Catenate    ${cmd}
997     END
998     IF    '${remote_group_id}'!='None'
999         ${cmd} =    BuiltIn.Catenate    ${cmd}    --remote-group ${remote_group_id}
1000     ELSE
1001         ${cmd} =    BuiltIn.Catenate    ${cmd}
1002     END
1003     IF    '${remote_ip_prefix}'!='None'
1004         ${cmd} =    BuiltIn.Catenate    ${cmd}    --src-ip ${remote_ip_prefix}
1005     ELSE
1006         ${cmd} =    BuiltIn.Catenate    ${cmd}
1007     END
1008     IF    '${remote_ip}'!='None'
1009         ${cmd} =    BuiltIn.Catenate    ${cmd}    --remote-ip ${remote_ip}
1010     ELSE
1011         ${cmd} =    BuiltIn.Catenate    ${cmd}
1012     END
1013     ${output} =    OpenStack CLI    ${cmd}
1014     ${rule_id} =    BuiltIn.Should Match Regexp    ${output}    ${REGEX_UUID}
1015     RETURN    ${output}    ${rule_id}
1016
1017 Security Group Create Without Default Security Rules
1018     [Documentation]    Create Neutron Security Group with no default rules, using specified name and optional arguments.
1019     [Arguments]    ${sg_name}    ${additional_args}=${EMPTY}
1020     OpenStackOperations.Neutron Security Group Create    ${sg_name}    ${additional_args}
1021     Delete All Security Group Rules    ${sg_name}
1022
1023 Delete All Security Group Rules
1024     [Documentation]    Delete all security rules from a specified security group
1025     [Arguments]    ${sg_name}
1026     ${sg_rules_output} =    OpenStack CLI    openstack security group rule list ${sg_name} -cID -fvalue
1027     @{sg_rules} =    String.Split String    ${sg_rules_output}    \n
1028     FOR    ${rule}    IN    @{sg_rules}
1029         ${output} =    OpenStack CLI    openstack security group rule delete ${rule}
1030     END
1031
1032 Create Allow All SecurityGroup
1033     [Documentation]    Allow all TCP/UDP/ICMP packets for this suite
1034     [Arguments]    ${sg_name}    ${ether_type}=IPv4    ${dual}=False
1035     OpenStackOperations.Neutron Security Group Create    ${sg_name}
1036     OpenStackOperations.Neutron Security Group Rule Create
1037     ...    ${sg_name}
1038     ...    direction=ingress
1039     ...    ethertype=${ether_type}
1040     ...    port_range_max=65535
1041     ...    port_range_min=1
1042     ...    protocol=tcp
1043     OpenStackOperations.Neutron Security Group Rule Create
1044     ...    ${sg_name}
1045     ...    direction=egress
1046     ...    ethertype=${ether_type}
1047     ...    port_range_max=65535
1048     ...    port_range_min=1
1049     ...    protocol=tcp
1050     OpenStackOperations.Neutron Security Group Rule Create
1051     ...    ${sg_name}
1052     ...    direction=ingress
1053     ...    ethertype=${ether_type}
1054     ...    protocol=icmp
1055     OpenStackOperations.Neutron Security Group Rule Create
1056     ...    ${sg_name}
1057     ...    direction=egress
1058     ...    ethertype=${ether_type}
1059     ...    protocol=icmp
1060     OpenStackOperations.Neutron Security Group Rule Create
1061     ...    ${sg_name}
1062     ...    direction=ingress
1063     ...    ethertype=${ether_type}
1064     ...    port_range_max=65535
1065     ...    port_range_min=1
1066     ...    protocol=udp
1067     OpenStackOperations.Neutron Security Group Rule Create
1068     ...    ${sg_name}
1069     ...    direction=egress
1070     ...    ethertype=${ether_type}
1071     ...    port_range_max=65535
1072     ...    port_range_min=1
1073     ...    protocol=udp
1074     IF    "${dual}"=="True"
1075         OpenStackOperations.Neutron Security Group Rule Create
1076         ...    ${sg_name}
1077         ...    direction=ingress
1078         ...    ethertype=IPv6
1079         ...    port_range_max=65535
1080         ...    port_range_min=1
1081         ...    protocol=tcp
1082         OpenStackOperations.Neutron Security Group Rule Create
1083         ...    ${sg_name}
1084         ...    direction=egress
1085         ...    ethertype=IPv6
1086         ...    port_range_max=65535
1087         ...    port_range_min=1
1088         ...    protocol=tcp
1089         OpenStackOperations.Neutron Security Group Rule Create
1090         ...    ${sg_name}
1091         ...    direction=ingress
1092         ...    ethertype=IPv6
1093         ...    protocol=icmp
1094         OpenStackOperations.Neutron Security Group Rule Create
1095         ...    ${sg_name}
1096         ...    direction=egress
1097         ...    ethertype=IPv6
1098         ...    protocol=icmp
1099         OpenStackOperations.Neutron Security Group Rule Create
1100         ...    ${sg_name}
1101         ...    direction=ingress
1102         ...    ethertype=IPv6
1103         ...    port_range_max=65535
1104         ...    port_range_min=1
1105         ...    protocol=udp
1106         OpenStackOperations.Neutron Security Group Rule Create
1107         ...    ${sg_name}
1108         ...    direction=egress
1109         ...    ethertype=IPv6
1110         ...    port_range_max=65535
1111         ...    port_range_min=1
1112         ...    protocol=udp
1113     END
1114
1115 Create Neutron Port With Additional Params
1116     [Documentation]    Create Port With given additional parameters
1117     [Arguments]    ${network_name}    ${port_name}    ${additional_args}=${EMPTY}
1118     ${rc}    ${output} =    OperatingSystem.Run And Return Rc And Output
1119     ...    neutron -v port-create ${network_name} --name ${port_name} ${additional_args}
1120     BuiltIn.Log    ${output}
1121     BuiltIn.Should Be True    '${rc}' == '0'
1122     ${port_id} =    BuiltIn.Should Match Regexp    ${OUTPUT}    ${REGEX_UUID}
1123     RETURN    ${OUTPUT}    ${port_id}
1124
1125 Get Ports MacAddr
1126     [Documentation]    Retrieve the port MacAddr for the given list of port name and return the MAC address list.
1127     [Arguments]    ${ports}
1128     ${macs} =    BuiltIn.Create List
1129     FOR    ${port}    IN    @{ports}
1130         ${mac} =    OpenStackOperations.Get Port Mac    ${port}
1131         Collections.Append To List    ${macs}    ${mac}
1132     END
1133     RETURN    ${macs}
1134
1135 Get Port Ip
1136     [Documentation]    Keyword would return the IP of the ${port_name} received.
1137     [Arguments]    ${port_name}
1138     ${output} =    OpenStack CLI    openstack port list | grep "${port_name}" | awk -F\\' '{print $2}'
1139     ${splitted_output} =    String.Split String    ${output}    ${EMPTY}
1140     ${port_ip} =    Collections.Get from List    ${splitted_output}    0
1141     RETURN    ${port_ip}
1142
1143 Get Port Mac
1144     [Documentation]    Keyword would return the MAC ID of the ${port_name} received.
1145     [Arguments]    ${port_name}
1146     ${output} =    OpenStack CLI    openstack port show ${port_name} | grep mac_address | awk '{print $4}'
1147     ${splitted_output} =    String.Split String    ${output}    ${EMPTY}
1148     ${port_mac} =    Collections.Get from List    ${splitted_output}    0
1149     RETURN    ${port_mac}
1150
1151 Get Port Mac Address From Ip
1152     [Documentation]    Retrieve the mac address for a port that matches any given ip.
1153     [Arguments]    ${ip}
1154     ${output} =    OpenStack CLI    openstack port list | grep -w ${ip} | awk '{print $5}'
1155     ${splitted_output} =    String.Split String    ${output}    ${EMPTY}
1156     ${mac_addr} =    Collections.Get from List    ${splitted_output}    0
1157     RETURN    ${mac_addr}
1158
1159 Create L2Gateway
1160     [Documentation]    Keyword to create an L2 Gateway ${gw_name} for bridge ${bridge_name} connected to interface ${intf_name} (Using Neutron CLI).
1161     [Arguments]    ${bridge_name}    ${intf_name}    ${gw_name}
1162     ${rc}    ${l2gw_output} =    OperatingSystem.Run And Return Rc And Output
1163     ...    ${L2GW_CREATE} name=${bridge_name},interface_names=${intf_name} ${gw_name}
1164     BuiltIn.Log    ${l2gw_output}
1165     RETURN    ${l2gw_output}
1166
1167 Update L2Gateway
1168     [Documentation]    Keyword to add {intf_name_list} to an existing L2 Gateway ${gw_name} (Using Neutron CLI).
1169     [Arguments]    ${bridge_name}    ${gw_name}    ${intf_name_1}    ${intf_name_2}
1170     ${rc}    ${l2gw_output} =    Run And Return Rc And Output
1171     ...    ${L2GW_UPDATE} name=${bridge_name},interface_names="${intf_name_1};${intf_name_2}" ${gw_name}
1172     Log    ${l2gw_output}
1173     RETURN    ${l2gw_output}
1174
1175 Create L2Gateway Connection
1176     [Documentation]    Keyword would create a new L2 Gateway Connection for ${gw_name} to ${net_name} (Using Neutron CLI).
1177     [Arguments]    ${gw_name}    ${net_name}
1178     ${rc}    ${l2gw_output} =    OperatingSystem.Run And Return Rc And Output
1179     ...    ${L2GW_CONN_CREATE} ${gw_name} ${net_name}
1180     BuiltIn.Log    ${l2gw_output}
1181     BuiltIn.Should Be True    '${rc}' == '0'
1182     RETURN    ${l2gw_output}
1183
1184 Get All L2Gateway
1185     [Documentation]    Keyword to return all the L2 Gateways available (Using Neutron CLI).
1186     ${rc}    ${output} =    OperatingSystem.Run And Return Rc And Output    ${L2GW_GET_YAML}
1187     BuiltIn.Should Be True    '${rc}' == '0'
1188     RETURN    ${output}
1189
1190 Get All L2Gateway Connection
1191     [Documentation]    Keyword to return all the L2 Gateway connections available (Using Neutron CLI).
1192     ${rc}    ${output} =    OperatingSystem.Run And Return Rc And Output    ${L2GW_GET_CONN_YAML}
1193     BuiltIn.Should Be True    '${rc}' == '0'
1194     RETURN    ${output}
1195
1196 Get L2Gateway
1197     [Documentation]    Keyword to check if the ${gw_id} is available in the L2 Gateway list (Using Neutron CLI).
1198     [Arguments]    ${gw_id}
1199     ${rc}    ${output} =    OperatingSystem.Run And Return Rc And Output    ${L2GW_SHOW} ${gw_id}
1200     BuiltIn.Log    ${output}
1201     BuiltIn.Should Be True    '${rc}' == '0'
1202     RETURN    ${output}
1203
1204 Get L2gw Id
1205     [Documentation]    Keyword to retrieve the L2 Gateway ID for the ${l2gw_name} (Using Neutron CLI).
1206     [Arguments]    ${l2gw_name}
1207     ${rc}    ${output} =    OperatingSystem.Run And Return Rc And Output
1208     ...    ${L2GW_GET} | grep "${l2gw_name}" | awk '{print $2}'
1209     BuiltIn.Log    ${output}
1210     BuiltIn.Should Be True    '${rc}' == '0'
1211     ${splitted_output} =    String.Split String    ${output}    ${EMPTY}
1212     ${l2gw_id} =    Collections.Get from List    ${splitted_output}    0
1213     RETURN    ${l2gw_id}
1214
1215 Get L2gw Connection Id
1216     [Documentation]    Keyword to retrieve the L2 Gateway Connection ID for the ${l2gw_name} (Using Neutron CLI).
1217     [Arguments]    ${l2gw_name}
1218     ${l2gw_id} =    OpenStackOperations.Get L2gw Id    ${l2gw_name}
1219     ${rc}    ${output} =    OperatingSystem.Run And Return Rc And Output
1220     ...    ${L2GW_GET_CONN} | grep "${l2gw_id}" | awk '{print $2}'
1221     BuiltIn.Should Be True    '${rc}' == '0'
1222     ${splitted_output} =    String.Split String    ${output}    ${EMPTY}
1223     ${splitted_output} =    String.Split String    ${output}    ${EMPTY}
1224     ${l2gw_conn_id} =    Collections.Get from List    ${splitted_output}    0
1225     RETURN    ${l2gw_conn_id}
1226
1227 Neutron Port List Rest
1228     [Documentation]    Keyword to get all ports details in Neutron (Using REST).
1229     ${resp} =    RequestsLibrary.Get Request    session    ${PORT_URL}
1230     BuiltIn.Log    ${resp.text}
1231     BuiltIn.Should Be Equal As Strings    ${resp.status_code}    200
1232     RETURN    ${resp.text}
1233
1234 Get Neutron Port Rest
1235     [Documentation]    Keyword to get the specific port details in Neutron (Using REST).
1236     [Arguments]    ${port_id}
1237     ${resp} =    RequestsLibrary.Get Request    session    ${CONFIG_API}/${GET_PORT_URL}/${port_id}
1238     BuiltIn.Log    ${resp.text}
1239     BuiltIn.Should Be Equal As Strings    ${resp.status_code}    200
1240     RETURN    ${resp.text}
1241
1242 Update Port Rest
1243     [Documentation]    Keyword to update ${port_id} with json data received in ${json_data} (Using REST).
1244     [Arguments]    ${port_id}    ${json_data}
1245     BuiltIn.Log    ${json_data}
1246     ${resp} =    RequestsLibrary.Put Request    session    ${CONFIG_API}/${GET_PORT_URL}/${port_id}    ${json_data}
1247     BuiltIn.Log    ${resp.text}
1248     BuiltIn.Should Be Equal As Strings    ${resp.status_code}    200
1249     RETURN    ${resp.text}
1250
1251 Get Neutron Network Rest
1252     [Documentation]    Keyword to get the specific network details in Neutron (Using REST).
1253     [Arguments]    ${net_id}
1254     ${resp} =    RequestsLibrary.Get Request    session    ${NETWORK_URL}/network/${net_id}
1255     BuiltIn.Log    ${resp.text}
1256     BuiltIn.Should Be Equal As Strings    ${resp.status_code}    200
1257     RETURN    ${resp.text}
1258
1259 Create And Configure Security Group
1260     [Documentation]    Create Security Group with given name, and default allow rules for TCP/UDP/ICMP protocols.
1261     [Arguments]    ${sg-name}
1262     OpenStackOperations.Neutron Security Group Create    ${sg-name}
1263     OpenStackOperations.Neutron Security Group Rule Create
1264     ...    ${sg-name}
1265     ...    direction=ingress
1266     ...    port_range_max=65535
1267     ...    port_range_min=1
1268     ...    protocol=tcp
1269     ...    remote_ip_prefix=0.0.0.0/0
1270     OpenStackOperations.Neutron Security Group Rule Create
1271     ...    ${sg-name}
1272     ...    direction=egress
1273     ...    port_range_max=65535
1274     ...    port_range_min=1
1275     ...    protocol=tcp
1276     ...    remote_ip_prefix=0.0.0.0/0
1277     OpenStackOperations.Neutron Security Group Rule Create
1278     ...    ${sg-name}
1279     ...    direction=ingress
1280     ...    protocol=icmp
1281     ...    remote_ip_prefix=0.0.0.0/0
1282     OpenStackOperations.Neutron Security Group Rule Create
1283     ...    ${sg-name}
1284     ...    direction=egress
1285     ...    protocol=icmp
1286     ...    remote_ip_prefix=0.0.0.0/0
1287     OpenStackOperations.Neutron Security Group Rule Create
1288     ...    ${sg-name}
1289     ...    direction=ingress
1290     ...    port_range_max=65535
1291     ...    port_range_min=1
1292     ...    protocol=udp
1293     ...    remote_ip_prefix=0.0.0.0/0
1294     OpenStackOperations.Neutron Security Group Rule Create
1295     ...    ${sg-name}
1296     ...    direction=egress
1297     ...    port_range_max=65535
1298     ...    port_range_min=1
1299     ...    protocol=udp
1300     ...    remote_ip_prefix=0.0.0.0/0
1301
1302 Add Security Group To VM
1303     [Documentation]    Add the security group provided to the given VM.
1304     [Arguments]    ${vm}    ${sg}
1305     ${output} =    OpenStack CLI    openstack server add security group ${vm} ${sg}
1306
1307 Remove Security Group From VM
1308     [Documentation]    Remove the security group provided to the given VM.
1309     [Arguments]    ${vm}    ${sg}
1310     OpenStackOperations.Get ControlNode Connection
1311     ${output} =    OpenStack CLI    openstack server remove security group ${vm} ${sg}
1312
1313 Create SFC Flow Classifier
1314     [Documentation]    Create a flow classifier for SFC
1315     [Arguments]    ${name}    ${src_ip}    ${dest_ip}    ${protocol}    ${neutron_src_port}    ${args}=${EMPTY}
1316     ${output} =    OpenStack CLI
1317     ...    openstack sfc flow classifier create --ethertype IPv4 --source-ip-prefix ${src_ip}/32 --destination-ip-prefix ${dest_ip}/32 --protocol ${protocol} --logical-source-port ${neutron_src_port} ${args} ${name}
1318     BuiltIn.Should Contain    ${output}    ${name}
1319     RETURN    ${output}
1320
1321 Delete SFC Flow Classifier
1322     [Documentation]    Delete a SFC flow classifier
1323     [Arguments]    ${name}
1324     ${output} =    OpenStack CLI    openstack sfc flow classifier delete ${name}
1325     RETURN    ${output}
1326
1327 Create SFC Port Pair
1328     [Documentation]    Creates a neutron port pair for SFC
1329     [Arguments]    ${name}    ${port_in}    ${port_out}
1330     ${output} =    OpenStack CLI    openstack sfc port pair create --ingress=${port_in} --egress=${port_out} ${name}
1331     BuiltIn.Should Contain    ${output}    ${name}
1332     RETURN    ${output}
1333
1334 Delete SFC Port Pair
1335     [Documentation]    Delete a SFC port pair
1336     [Arguments]    ${name}
1337     ${output} =    OpenStack CLI    openstack sfc port pair delete ${name}
1338     RETURN    ${output}
1339
1340 Create SFC Port Pair Group
1341     [Documentation]    Creates a port pair group with a single port pair for SFC
1342     [Arguments]    ${name}    ${port_pair}
1343     ${output} =    OpenStack CLI    openstack sfc port pair group create --port-pair ${port_pair} ${name}
1344     BuiltIn.Should Contain    ${output}    ${name}
1345     RETURN    ${output}
1346
1347 Create SFC Port Pair Group With Two Pairs
1348     [Documentation]    Creates a port pair group with two port pairs for SFC
1349     [Arguments]    ${name}    ${port_pair1}    ${port_pair2}
1350     ${output} =    OpenStack CLI
1351     ...    openstack sfc port pair group create --port-pair ${port_pair1} --port-pair ${port_pair2} ${name}
1352     BuiltIn.Should Contain    ${output}    ${name}
1353     RETURN    ${output}
1354
1355 Delete SFC Port Pair Group
1356     [Documentation]    Delete a SFC port pair group
1357     [Arguments]    ${name}
1358     OpenStackOperations.Get ControlNode Connection
1359     ${output} =    OpenStack CLI    openstack sfc port pair group delete ${name}
1360     RETURN    ${output}
1361
1362 Create SFC Port Chain
1363     [Documentation]    Creates a port pair chain with two port groups and a singel classifier.
1364     [Arguments]    ${name}    ${args}=${EMPTY}
1365     ${output} =    OpenStack CLI    openstack sfc port chain create ${name} ${args}
1366     BuiltIn.Should Contain    ${output}    ${name}
1367     RETURN    ${output}
1368
1369 Update SFC Port Chain With A New Flow Classifier
1370     [Documentation]    Adds a Flow Classifier to a Port Chain
1371     [Arguments]    ${name}    ${fc}
1372     ${output} =    OpenStack CLI    openstack sfc port chain set ${name} --flow-classifier ${fc}
1373     RETURN    ${output}
1374
1375 Update SFC Port Chain Removing A Flow Classifier
1376     [Documentation]    Adds a Flow Classifier to a Port Chain
1377     [Arguments]    ${name}    ${fc}
1378     ${output} =    OpenStack CLI    openstack sfc port chain unset ${name} --flow-classifier ${fc}
1379     RETURN    ${output}
1380
1381 Delete SFC Port Chain
1382     [Documentation]    Delete a SFC port chain
1383     [Arguments]    ${name}
1384     ${output} =    OpenStack CLI    openstack sfc port chain delete ${name}
1385     RETURN    ${output}
1386
1387 Reboot Nova VM
1388     [Documentation]    Reboot NOVA VM
1389     [Arguments]    ${vm_name}
1390     ${output} =    OpenStack CLI    openstack server reboot --wait ${vm_name}
1391     BuiltIn.Wait Until Keyword Succeeds    35s    10s    OpenStackOperations.Verify VM Is ACTIVE    ${vm_name}
1392
1393 Remove RSA Key From KnownHosts
1394     [Documentation]    Remove RSA
1395     [Arguments]    ${vm_ip}
1396     OpenStackOperations.Get ControlNode Connection
1397     ${output} =    DevstackUtils.Write Commands Until Prompt And Log    sudo cat /root/.ssh/known_hosts    30s
1398     ${output} =    DevstackUtils.Write Commands Until Prompt And Log
1399     ...    sudo ssh-keygen -f "/root/.ssh/known_hosts" -R ${vm_ip}
1400     ...    30s
1401     ${output} =    DevstackUtils.Write Commands Until Prompt    sudo cat "/root/.ssh/known_hosts"    30s
1402
1403 Wait For Routes To Propogate
1404     [Documentation]    Check propagated routes
1405     [Arguments]    ${networks}    ${subnets}
1406     OpenStackOperations.Get ControlNode Connection
1407     FOR    ${INDEX}    IN RANGE    0    1
1408         ${net_id} =    OpenStackOperations.Get Net Id    ${networks}[${INDEX}]
1409         ${is_ipv6} =    String.Get Regexp Matches    ${subnets}[${INDEX}]    ${IP6_REGEX}
1410         ${length} =    BuiltIn.Get Length    ${is_ipv6}
1411         ${cmd} =    BuiltIn.Set Variable If    ${length} == 0    ip route    ip -6 route
1412         ${output} =    Utils.Write Commands Until Expected Prompt
1413         ...    sudo ip netns exec qdhcp-${net_id} ${cmd}
1414         ...    ${DEFAULT_LINUX_PROMPT_STRICT}
1415         BuiltIn.Should Contain    ${output}    ${subnets}[${INDEX}]
1416     END
1417
1418 Neutron Cleanup
1419     [Arguments]    ${vms}=@{EMPTY}    ${networks}=@{EMPTY}    ${subnets}=@{EMPTY}    ${ports}=@{EMPTY}    ${sgs}=@{EMPTY}
1420     FOR    ${vm}    IN    @{vms}
1421         BuiltIn.Run Keyword And Ignore Error    Delete Vm Instance    ${vm}
1422     END
1423     FOR    ${port}    IN    @{ports}
1424         BuiltIn.Run Keyword And Ignore Error    Delete Port    ${port}
1425     END
1426     FOR    ${subnet}    IN    @{subnets}
1427         BuiltIn.Run Keyword And Ignore Error    Delete SubNet    ${subnet}
1428     END
1429     FOR    ${network}    IN    @{networks}
1430         BuiltIn.Run Keyword And Ignore Error    Delete Network    ${network}
1431     END
1432     FOR    ${sg}    IN    @{sgs}
1433         BuiltIn.Run Keyword And Ignore Error    Delete SecurityGroup    ${sg}
1434     END
1435
1436 OpenStack List All
1437     [Documentation]    Get a list of different OpenStack resources that might be in use.
1438     @{modules} =    BuiltIn.Create List    server    port    network    subnet    security group
1439     ...    security group rule    floating ip    router
1440     FOR    ${module}    IN    @{modules}
1441         ${output} =    OpenStack CLI    openstack ${module} list
1442     END
1443
1444 OpenStack CLI Get List
1445     [Documentation]    Return a json list from the output of an OpenStack command.
1446     [Arguments]    ${cmd}
1447     @{list} =    BuiltIn.Create List
1448     ${json} =    OpenStack CLI    ${cmd}
1449     @{list} =    RequestsLibrary.To Json    ${json}
1450     BuiltIn.Log    ${list}
1451     RETURN    @{list}
1452
1453 OpenStack CLI
1454     [Documentation]    Run the given OpenStack ${cmd} and log the output.
1455     [Arguments]    ${cmd}
1456     ${result} =    Process.Run Process    ${cmd}    shell=True
1457     BuiltIn.Log    ${result.stdout}
1458     BuiltIn.Log    ${result.stderr}
1459     BuiltIn.Should Be True    '${result.rc}' == '0'
1460     RETURN    ${result.stdout}
1461
1462 OpenStack CLI With No Log
1463     [Documentation]    Run the given OpenStack ${cmd} and do not log the output.
1464     [Arguments]    ${cmd}
1465     ${result} =    Process.Run Process    ${cmd}    shell=True
1466     BuiltIn.Should Be True    '${result.rc}' == '0'
1467     RETURN    ${result.stdout}
1468
1469 OpenStack Cleanup All
1470     [Documentation]    Cleanup all Openstack resources with best effort. The keyword will query for all resources
1471     ...    in use and then attempt to delete them. Errors are ignored to allow the cleanup to continue.
1472     @{fips} =    OpenStack CLI Get List    openstack floating ip list -f json
1473     FOR    ${fip}    IN    @{fips}
1474         BuiltIn.Run Keyword And Ignore Error    Delete Floating IP    ${fip['ID']}
1475     END
1476     @{vms} =    OpenStack CLI Get List    openstack server list -f json
1477     FOR    ${vm}    IN    @{vms}
1478         OpenStack CLI    openstack server show ${vm['ID']}
1479         BuiltIn.Run Keyword And Ignore Error    Delete Vm Instance    ${vm['ID']}
1480     END
1481     @{routers} =    OpenStack CLI Get List    openstack router list -f json
1482     FOR    ${router}    IN    @{routers}
1483         BuiltIn.Run Keyword And Ignore Error    Cleanup Router    ${router['ID']}
1484     END
1485     @{ports} =    OpenStack CLI Get List    openstack port list -f json
1486     FOR    ${port}    IN    @{ports}
1487         BuiltIn.Run Keyword And Ignore Error    Delete Port    ${port['ID']}
1488     END
1489     @{networks} =    OpenStack CLI Get List    openstack network list -f json
1490     FOR    ${network}    IN    @{networks}
1491         BuiltIn.Run Keyword And Ignore Error    Delete Subnet    ${network['Subnets']}
1492         BuiltIn.Run Keyword And Ignore Error    Delete Network    ${network['ID']}
1493     END
1494     @{security_groups} =    OpenStack CLI Get List    openstack security group list -f json
1495     FOR    ${security_group}    IN    @{security_groups}
1496         IF    "${security_group['Name']}" != "default"
1497             BuiltIn.Run Keyword And Ignore Error    Delete SecurityGroup    ${security_group['ID']}
1498         END
1499     END
1500     OpenStack List All
1501
1502 Cleanup Router
1503     [Documentation]    Delete a router, but first remove any interfaces or gateways so that the delete will be successful.
1504     [Arguments]    ${id}
1505     @{ports} =    OpenStack CLI Get List    openstack port list --router ${id} -f json --long
1506     FOR    ${port}    IN    @{ports}
1507         ${subnet_id} =    OpenStackOperations.Get Match    ${port['Fixed IP Addresses']}    ${REGEX_UUID}    0
1508         IF    "${port['Device Owner']}" == "network:router_gateway"
1509             BuiltIn.Run Keyword And Ignore Error    Remove Gateway    ${id}
1510         END
1511         IF    "${port['Device Owner']}" == "network:router_interface"
1512             BuiltIn.Run Keyword And Ignore Error    Remove Interface    ${id}    ${subnet_id}
1513         END
1514     END
1515     BuiltIn.Run Keyword And Ignore Error    Delete Router    ${id}
1516
1517 OpenStack Suite Setup
1518     [Documentation]    Wrapper teardown keyword that can be used in any suite running in an openstack environement
1519     SetupUtils.Setup_Utils_For_Setup_And_Teardown
1520     @{loggers} =    BuiltIn.Create List
1521     ...    org.apache.karaf.shell.support.ShellUtil
1522     ...    org.apache.sshd.server.session.ServerSessionImpl
1523     Setuputils.Setup_Logging_For_Debug_Purposes_On_List_Or_All    OFF    ${loggers}
1524     DevstackUtils.Devstack Suite Setup
1525     @{tcpdump_port_6653_conn_ids} =    OpenStackOperations.Start Packet Capture On Nodes
1526     ...    tcpdump_port_6653
1527     ...    port 6653
1528     ...    @{OS_ALL_IPS}
1529     BuiltIn.Set Suite Variable    @{tcpdump_port_6653_conn_ids}
1530     IF    "${PRE_CLEAN_OPENSTACK_ALL}"=="True"    OpenStack Cleanup All
1531     OpenStackOperations.Add OVS Logging On All OpenStack Nodes
1532     Validate Deployment
1533
1534 OpenStack Suite Teardown
1535     [Documentation]    Wrapper teardown keyword that can be used in any suite running in an openstack environement
1536     ...    to clean up all openstack resources. For example, all instances, networks, ports, etc will be listed and
1537     ...    and deleted. As other global cleanup tasks are needed, they can be added here and the suites will all
1538     ...    benefit automatically.
1539     # TODO: followup patch will add the list of vms to pass to Show Debugs
1540     # OpenStackOperations.Show Debugs    @{NET_1_VMS}    @{NET_2_VMS}
1541     OpenStackOperations.Get Suite Debugs
1542     OpenStack Cleanup All
1543     OpenStackOperations.Stop Packet Capture On Nodes    ${tcpdump_port_6653_conn_ids}
1544     SSHLibrary.Close All Connections
1545     FOR    ${i}    IN RANGE    ${NUM_ODL_SYSTEM}
1546         KarafKeywords.Issue Command On Karaf Console    threads --list | wc -l    ${ODL_SYSTEM_${i+1}_IP}
1547     END
1548
1549 Validate Deployment
1550     [Documentation]    Validate the deployment. Examples to validate are verifying default table
1551     ...    flows are installed and that the tunnel mesh has been built correctly.
1552     Write To Validate File    ----------------------------------------\n${SUITE_NAME}\n
1553     FOR    ${keyword}    IN    @{VALIDATION_KEYWORDS}
1554         ${status} =    Builtin.Run Keyword And Return Status    ${keyword}
1555         IF    "${status}" == "FAIL" or "${status}" == "False"
1556             BuiltIn.Run Keywords    Write To Validate File    Failed: ${keyword}    AND    BuiltIn.Fail
1557         ELSE
1558             Write To Validate File    Passed: ${keyword}
1559         END
1560     END
1561
1562 Write To Validate File
1563     [Documentation]    Write the given ${msg} to ${VALIDATION_FILE}. Create the file if not present.
1564     [Arguments]    ${msg}
1565     ${status} =    BuiltIn.Run Keyword And Return Status    OperatingSystem.File Should Exist    ${VALIDATION_FILE}
1566     IF    "${status}" == "False"
1567         OperatingSystem.Create File    ${VALIDATION_FILE}
1568     END
1569     OperatingSystem.Append To File    ${VALIDATION_FILE}    ${msg}\n
1570
1571 Copy DHCP Files From Control Node
1572     [Documentation]    Copy the current DHCP files to the robot vm. The keyword must be called
1573     ...    after the subnet(s) are created and before the subnet(s) are deleted.
1574     ${suite_} =    BuiltIn.Evaluate    """${SUITE_NAME}""".replace(" ","_").replace("/","_").replace(".","_")
1575     ${dstdir} =    BuiltIn.Set Variable    /tmp/qdhcp/${suite_}
1576     OperatingSystem.Create Directory    ${dstdir}
1577     OpenStackOperations.Get ControlNode Connection
1578     BuiltIn.Run Keyword And Ignore Error
1579     ...    SSHLibrary.Get Directory
1580     ...    /opt/stack/data/neutron/dhcp
1581     ...    ${dstdir}
1582     ...    recursive=True
1583
1584 Is Feature Installed
1585     [Arguments]    ${features}=none
1586     FOR    ${feature}    IN    @{features}
1587         ${status}    ${output} =    BuiltIn.Run Keyword And Ignore Error
1588         ...    BuiltIn.Should Contain
1589         ...    ${CONTROLLERFEATURES}
1590         ...    ${feature}
1591         IF    "${status}" == "PASS"    RETURN    True
1592     END
1593     RETURN    False
1594
1595 Add OVS Logging On All OpenStack Nodes
1596     [Documentation]    Add higher levels of OVS logging to all the OpenStack nodes
1597     FOR    ${conn_id}    IN    @{OS_ALL_CONN_IDS}
1598         OVSDB.Add OVS Logging    ${conn_id}
1599     END
1600
1601 Reset OVS Logging On All OpenStack Nodes
1602     [Documentation]    Reset the OVS logging to all the OpenStack nodes
1603     FOR    ${conn_id}    IN    @{OS_ALL_CONN_IDS}
1604         OVSDB.Reset OVS Logging    ${conn_id}
1605     END
1606
1607 Start Packet Capture On Nodes
1608     [Documentation]    Wrapper keyword around the TcpDump packet capture that is catered to the Openstack setup.
1609     ...    The caller must pass the three arguments with a variable number of ips at the end,
1610     ...    but ${EMPTY} can be used for the tag and filter.
1611     [Arguments]    ${tag}    ${filter}    @{ips}
1612     ${suite_} =    BuiltIn.Evaluate    """${SUITE_NAME}""".replace(" ","_").replace("/","_").replace(".","_")
1613     ${tag_} =    BuiltIn.Catenate    SEPARATOR=__    ${tag}    ${suite_}
1614     @{conn_ids} =    Tcpdump.Start Packet Capture on Nodes    tag=${tag_}    filter=${filter}    ips=${ips}
1615     RETURN    @{conn_ids}
1616
1617 Stop Packet Capture On Nodes
1618     [Arguments]    ${conn_ids}=@{EMPTY}
1619     Tcpdump.Stop Packet Capture on Nodes    ${conn_ids}
1620
1621 Server Live Migrate
1622     [Documentation]    Keyword for live migration of VM instance
1623     ...    additional_agrs is to select particular migration(live/shared-migration/block-migration)
1624     ...    if the additional_agrs is not given default migration(shared-migration) will happen
1625     [Arguments]    ${vm_instance_name}
1626     ${output} =    OpenStackOperations.OpenStack CLI    nova live-migration ${vm_instance_name}
1627
1628 Get Hypervisor Host Of Vm
1629     [Documentation]    Show server with neutron request.
1630     [Arguments]    ${vm_name}
1631     ${output} =    OpenStackOperations.OpenStack CLI
1632     ...    openstack server show -f value -c OS-EXT-SRV-ATTR:host ${vm_name}
1633     RETURN    ${output}
1634
1635 Check If Migration Is Complete
1636     [Documentation]    Show server and verify if task_state is not migrating
1637     [Arguments]    ${vm_name}
1638     ${output} =    OpenStackOperations.OpenStack CLI    openstack server show ${vm_name} | grep "OS-EXT-STS:task_state"
1639     BuiltIn.Should Not Contain    ${output}    migrating
1640
1641 Modify OpenStack Configuration File
1642     [Documentation]    Use crudini to modify any parameter in any Openstack configuration File
1643     [Arguments]    ${conn_id}    ${file_name}    ${section}    ${key}    ${value}
1644     SSHLibrary.Switch Connection    ${conn_id}
1645     ${output}    ${rc} =    SSHLibrary.Execute Command
1646     ...    sudo crudini --verbose --set --inplace ${file_name} ${section} ${key} ${value}
1647     ...    return_rc=True
1648     ...    return_stdout=True
1649     BuiltIn.Log    ${output}
1650     BuiltIn.Should Be True    '${rc}' == '0'
1651
1652 Restart DevStack Service
1653     [Documentation]    Restart the Openstack Service
1654     [Arguments]    ${conn_id}    ${service_name}
1655     SSHLibrary.Switch Connection    ${conn_id}
1656     ${output}    ${rc} =    SSHLibrary.Execute Command
1657     ...    sudo systemctl restart devstack@${service_name}.service
1658     ...    return_rc=True
1659     ...    return_stdout=True
1660     BuiltIn.Log    ${output}
1661     BuiltIn.Should Be True    '${rc}' == '0'
1662
1663 Get Network Segmentation Id
1664     [Documentation]    Returns network segmentation id for the given network name.
1665     [Arguments]    ${network_name}
1666     ${output} =    OpenStack CLI    openstack network show ${network_name} | grep segmentation_id | awk '{print $4}'
1667     @{list} =    String.Split String    ${output}
1668     RETURN    ${list}[0]
1669
1670 Verify Services
1671     [Documentation]    Verify if the services are operational
1672     Wait Until Keyword Succeeds
1673     ...    60
1674     ...    2
1675     ...    ClusterManagement.Check Status Of Services Is OPERATIONAL
1676     ...    @{DIAG_SERVICES}
1677
1678 Verify Expected Default Tables On Nodes
1679     [Documentation]    Verify if Default Table Entries are programmed on all Nodes
1680     [Arguments]    ${node_ips}=@{OS_ALL_IPS}
1681     ${resp} =    RequestsLibrary.Get Request    session    ${RFC8040_CONFIG_NODES_API}
1682     Utils.Log Content    ${resp.text}
1683     ${failed_node_list} =    BuiltIn.Create List
1684     FOR    ${node_ip}    IN    @{node_ips}
1685         ${failed_table_list} =    Verify Expected Default Tables    ${node_ip}
1686         ${failed_table_list_size} =    BuiltIn.Get Length    ${failed_table_list}
1687         IF    ${failed_table_list_size} > 0
1688             Collections.Append To List    ${failed_node_list}    ${node_ip}
1689         END
1690     END
1691     Builtin.Should Be Empty    ${failed_node_list}
1692
1693 Verify Expected Default Tables
1694     [Documentation]    Verify if Default Table Entries are programmed on specific Node
1695     [Arguments]    ${ovs_ip}
1696     ${flow_dump} =    Utils.Run Command On Remote System
1697     ...    ${ovs_ip}
1698     ...    sudo ovs-ofctl dump-flows ${INTEGRATION_BRIDGE} -OOpenFlow13
1699     BuiltIn.Log    ${flow_dump}
1700     ${failed_table_list} =    BuiltIn.Create List
1701     FOR    ${table}    IN    @{DEFAULT_FLOW_TABLES}
1702         ${rc} =    Builtin.Run Keyword And Return Status
1703         ...    Builtin.Should Not Match Regexp
1704         ...    ${flow_dump}
1705         ...    .*table=${table}.*priority=0
1706         IF    ${rc}
1707             Collections.Append To List    ${failed_table_list}    ${table}
1708         END
1709     END
1710     RETURN    ${failed_table_list}
1711
1712 Get Project Id
1713     [Documentation]    Returns project ID for the given project name.
1714     [Arguments]    ${project_name}
1715     ${project_id} =    OpenStack CLI    openstack project show ${project_name} -f value -c id
1716     RETURN    ${project_id}
1717
1718 Set Instance Quota For Project
1719     [Documentation]    Set quota for the created instances using the specific project id.
1720     [Arguments]    ${num_instances}    ${project_id}
1721     ${output} =    OpenStack CLI    openstack quota set --instances ${num_instances} ${project_id}
1722     RETURN    ${output}
1723
1724 Create Bgpvpn
1725     [Documentation]    Create Bgpvpn with neutron request.
1726     [Arguments]    ${vpnname}    ${additional_args}=${EMPTY}
1727     ${output} =    OpenStack CLI    openstack bgpvpn create --name ${vpnname} ${additional_args}
1728
1729 Get BgpVpn Id
1730     [Documentation]    Retrieve the bgpvpn id for the given bgpvpn name
1731     [Arguments]    ${vpnName}
1732     ${output} =    OpenStack CLI    openstack bgpvpn show ${vpnName} | grep " ID" | awk '{print $4}'
1733     ${splitted_output} =    String.Split String    ${output}    ${EMPTY}
1734     ${vpn_id} =    Collections.Get from List    ${splitted_output}    0
1735     RETURN    ${vpn_id}
1736
1737 Configure_IP_On_Sub_Interface
1738     [Documentation]    Keyword for configuring specified IP on specified interface and the corresponding specified sub interface
1739     [Arguments]    ${network_name}    ${ip}    ${vm_ip}    ${mask}    ${sub_interface_state}=${EMPTY}    ${interface}=eth0
1740     ...    ${sub_interface_number}=1
1741     OpenStackOperations.Execute Command on VM Instance
1742     ...    ${network_name}
1743     ...    ${vm_ip}
1744     ...    sudo ifconfig ${interface}:${sub_interface_number} ${ip} netmask ${mask} ${sub_interface_state}
1745
1746 Verify_IP_Configured_On_Sub_Interface
1747     [Documentation]    Keyword for verifying specified IP on specified interface and the corresponding specified sub interface
1748     [Arguments]    ${network_name}    ${ip}    ${vm_ip}    ${interface}=eth0    ${sub_interface_number}=1
1749     ${resp} =    OpenStackOperations.Execute Command on VM Instance
1750     ...    ${network_name}
1751     ...    ${vm_ip}
1752     ...    sudo ifconfig ${interface}:${sub_interface_number}
1753     BuiltIn.Should Contain    ${resp}    ${ip}