+ ${macs} BuiltIn.Create List
+ : FOR ${port} IN @{ports}
+ \ ${mac} = OpenStackOperations.Get Port Mac ${port}
+ \ Collections.Append To List ${macs} ${mac}
+ [Return] ${macs}
+
+Get Port Ip
+ [Arguments] ${port_name}
+ [Documentation] Keyword would return the IP of the ${port_name} received.
+ ${output} = OpenStack CLI openstack port list | grep "${port_name}" | awk -F\\' '{print $2}'
+ ${splitted_output} = String.Split String ${output} ${EMPTY}
+ ${port_ip} = Collections.Get from List ${splitted_output} 0
+ [Return] ${port_ip}
+
+Get Port Mac
+ [Arguments] ${port_name}
+ [Documentation] Keyword would return the MAC ID of the ${port_name} received.
+ ${output} = OpenStack CLI openstack port show ${port_name} | grep mac_address | awk '{print $4}'
+ ${splitted_output} = String.Split String ${output} ${EMPTY}
+ ${port_mac} = Collections.Get from List ${splitted_output} 0
+ [Return] ${port_mac}
+
+Create L2Gateway
+ [Arguments] ${bridge_name} ${intf_name} ${gw_name}
+ [Documentation] Keyword to create an L2 Gateway ${gw_name} for bridge ${bridge_name} connected to interface ${intf_name} (Using Neutron CLI).
+ ${rc} ${l2gw_output} = OperatingSystem.Run And Return Rc And Output ${L2GW_CREATE} name=${bridge_name},interface_names=${intf_name} ${gw_name}
+ BuiltIn.Log ${l2gw_output}
+ [Return] ${l2gw_output}
+
+Update L2Gateway
+ [Arguments] ${bridge_name} ${gw_name} ${intf_name_1} ${intf_name_2}
+ [Documentation] Keyword to add {intf_name_list} to an existing L2 Gateway ${gw_name} (Using Neutron CLI).
+ ${rc} ${l2gw_output}= Run And Return Rc And Output ${L2GW_UPDATE} name=${bridge_name},interface_names="${intf_name_1};${intf_name_2}" ${gw_name}
+ Log ${l2gw_output}
+ [Return] ${l2gw_output}
+
+Create L2Gateway Connection
+ [Arguments] ${gw_name} ${net_name}
+ [Documentation] Keyword would create a new L2 Gateway Connection for ${gw_name} to ${net_name} (Using Neutron CLI).
+ ${rc} ${l2gw_output} = OperatingSystem.Run And Return Rc And Output ${L2GW_CONN_CREATE} ${gw_name} ${net_name}
+ BuiltIn.Log ${l2gw_output}
+ BuiltIn.Should Be True '${rc}' == '0'
+ [Return] ${l2gw_output}
+
+Get All L2Gateway
+ [Documentation] Keyword to return all the L2 Gateways available (Using Neutron CLI).
+ ${rc} ${output} = OperatingSystem.Run And Return Rc And Output ${L2GW_GET_YAML}
+ BuiltIn.Should Be True '${rc}' == '0'
+ [Return] ${output}
+
+Get All L2Gateway Connection
+ [Documentation] Keyword to return all the L2 Gateway connections available (Using Neutron CLI).
+ ${rc} ${output} = OperatingSystem.Run And Return Rc And Output ${L2GW_GET_CONN_YAML}
+ BuiltIn.Should Be True '${rc}' == '0'
+ [Return] ${output}
+
+Get L2Gateway
+ [Arguments] ${gw_id}
+ [Documentation] Keyword to check if the ${gw_id} is available in the L2 Gateway list (Using Neutron CLI).
+ ${rc} ${output} = OperatingSystem.Run And Return Rc And Output ${L2GW_SHOW} ${gw_id}
+ BuiltIn.Log ${output}
+ BuiltIn.Should Be True '${rc}' == '0'
+ [Return] ${output}
+
+Get L2gw Id
+ [Arguments] ${l2gw_name}
+ [Documentation] Keyword to retrieve the L2 Gateway ID for the ${l2gw_name} (Using Neutron CLI).
+ ${rc} ${output} = OperatingSystem.Run And Return Rc And Output ${L2GW_GET} | grep "${l2gw_name}" | awk '{print $2}'
+ BuiltIn.Log ${output}
+ BuiltIn.Should Be True '${rc}' == '0'
+ ${splitted_output} = String.Split String ${output} ${EMPTY}
+ ${l2gw_id} = Collections.Get from List ${splitted_output} 0
+ [Return] ${l2gw_id}
+
+Get L2gw Connection Id
+ [Arguments] ${l2gw_name}
+ [Documentation] Keyword to retrieve the L2 Gateway Connection ID for the ${l2gw_name} (Using Neutron CLI).
+ ${l2gw_id} = OpenStackOperations.Get L2gw Id ${l2gw_name}
+ ${rc} ${output} = OperatingSystem.Run And Return Rc And Output ${L2GW_GET_CONN} | grep "${l2gw_id}" | awk '{print $2}'
+ BuiltIn.Should Be True '${rc}' == '0'
+ ${splitted_output} = String.Split String ${output} ${EMPTY}
+ ${splitted_output} = String.Split String ${output} ${EMPTY}
+ ${l2gw_conn_id} = Collections.Get from List ${splitted_output} 0
+ [Return] ${l2gw_conn_id}
+
+Neutron Port List Rest
+ [Documentation] Keyword to get all ports details in Neutron (Using REST).
+ ${resp} = RequestsLibrary.Get Request session ${PORT_URL}
+ BuiltIn.Log ${resp.content}
+ BuiltIn.Should Be Equal As Strings ${resp.status_code} 200
+ [Return] ${resp.content}
+
+Get Neutron Port Rest
+ [Arguments] ${port_id}
+ [Documentation] Keyword to get the specific port details in Neutron (Using REST).
+ ${resp} = RequestsLibrary.Get Request session ${CONFIG_API}/${GET_PORT_URL}/${port_id}
+ BuiltIn.Log ${resp.content}
+ BuiltIn.Should Be Equal As Strings ${resp.status_code} 200
+ [Return] ${resp.content}
+
+Update Port Rest
+ [Arguments] ${port_id} ${json_data}
+ [Documentation] Keyword to update ${port_id} with json data received in ${json_data} (Using REST).
+ BuiltIn.Log ${json_data}
+ ${resp} = RequestsLibrary.Put Request session ${CONFIG_API}/${GET_PORT_URL}/${port_id} ${json_data}
+ BuiltIn.Log ${resp.content}
+ BuiltIn.Should Be Equal As Strings ${resp.status_code} 200
+ [Return] ${resp.content}
+
+Create And Configure Security Group
+ [Arguments] ${sg-name}
+ [Documentation] Create Security Group with given name, and default allow rules for TCP/UDP/ICMP protocols.
+ OpenStackOperations.Neutron Security Group Create ${sg-name}
+ OpenStackOperations.Neutron Security Group Rule Create ${sg-name} direction=ingress port_range_max=65535 port_range_min=1 protocol=tcp remote_ip_prefix=0.0.0.0/0
+ OpenStackOperations.Neutron Security Group Rule Create ${sg-name} direction=egress port_range_max=65535 port_range_min=1 protocol=tcp remote_ip_prefix=0.0.0.0/0
+ OpenStackOperations.Neutron Security Group Rule Create ${sg-name} direction=ingress protocol=icmp remote_ip_prefix=0.0.0.0/0
+ OpenStackOperations.Neutron Security Group Rule Create ${sg-name} direction=egress protocol=icmp remote_ip_prefix=0.0.0.0/0
+ OpenStackOperations.Neutron Security Group Rule Create ${sg-name} direction=ingress port_range_max=65535 port_range_min=1 protocol=udp remote_ip_prefix=0.0.0.0/0
+ OpenStackOperations.Neutron Security Group Rule Create ${sg-name} direction=egress port_range_max=65535 port_range_min=1 protocol=udp remote_ip_prefix=0.0.0.0/0
+
+Add Security Group To VM
+ [Arguments] ${vm} ${sg}
+ [Documentation] Add the security group provided to the given VM.
+ ${output} = OpenStack CLI openstack server add security group ${vm} ${sg}
+
+Remove Security Group From VM
+ [Arguments] ${vm} ${sg}
+ [Documentation] Remove the security group provided to the given VM.
+ OpenStackOperations.Get ControlNode Connection
+ ${output} = OpenStack CLI openstack server remove security group ${vm} ${sg}
+
+Create SFC Flow Classifier
+ [Arguments] ${name} ${src_ip} ${dest_ip} ${protocol} ${dest_port} ${neutron_src_port}
+ [Documentation] Create a flow classifier for SFC
+ ${output} = OpenStack CLI openstack sfc flow classifier create --ethertype IPv4 --source-ip-prefix ${src_ip}/32 --destination-ip-prefix ${dest_ip}/32 --protocol ${protocol} --destination-port ${dest_port}:${dest_port} --logical-source-port ${neutron_src_port} ${name}
+ BuiltIn.Should Contain ${output} ${name}
+ [Return] ${output}
+
+Delete SFC Flow Classifier
+ [Arguments] ${name}
+ [Documentation] Delete a SFC flow classifier
+ OpenStackOperations.Get ControlNode Connection
+ ${output} = OpenStack CLI openstack sfc flow classifier delete ${name}
+ [Return] ${output}
+
+Create SFC Port Pair
+ [Arguments] ${name} ${port_in} ${port_out}
+ [Documentation] Creates a neutron port pair for SFC
+ OpenStackOperations.Get ControlNode Connection
+ ${output} = OpenStack CLI openstack sfc port pair create --ingress=${port_in} --egress=${port_out} ${name}
+ BuiltIn.Should Contain ${output} ${name}
+ [Return] ${output}
+
+Delete SFC Port Pair
+ [Arguments] ${name}
+ [Documentation] Delete a SFC port pair
+ ${output} = OpenStack CLI openstack sfc port pair delete ${name}
+ [Return] ${output}
+
+Create SFC Port Pair Group
+ [Arguments] ${name} ${port_pair}
+ [Documentation] Creates a port pair group with a single port pair for SFC
+ ${output} = OpenStack CLI openstack sfc port pair group create --port-pair ${port_pair} ${name}
+ BuiltIn.Should Contain ${output} ${name}
+ [Return] ${output}
+
+Create SFC Port Pair Group With Two Pairs
+ [Arguments] ${name} ${port_pair1} ${port_pair2}
+ [Documentation] Creates a port pair group with two port pairs for SFC
+ ${output} = OpenStack CLI openstack sfc port pair group create --port-pair ${port_pair1} --port-pair ${port_pair2} ${name}
+ BuiltIn.Should Contain ${output} ${name}
+ [Return] ${output}
+
+Delete SFC Port Pair Group
+ [Arguments] ${name}
+ [Documentation] Delete a SFC port pair group
+ OpenStackOperations.Get ControlNode Connection
+ ${output} = OpenStack CLI openstack sfc port pair group delete ${name}
+ [Return] ${output}
+
+Create SFC Port Chain
+ [Arguments] ${name} ${pg1} ${pg2} ${fc}
+ [Documentation] Creates a port pair chain with two port groups and a singel classifier.
+ ${output} = OpenStack CLI openstack sfc port chain create --port-pair-group ${pg1} --port-pair-group ${pg2} --flow-classifier ${fc} ${name}
+ BuiltIn.Should Contain ${output} ${name}
+ [Return] ${output}
+
+Delete SFC Port Chain
+ [Arguments] ${name}
+ [Documentation] Delete a SFC port chain
+ ${output} = OpenStack CLI openstack sfc port chain delete ${name}
+ [Return] ${output}
+
+Reboot Nova VM
+ [Arguments] ${vm_name}
+ [Documentation] Reboot NOVA VM
+ ${output} = OpenStack CLI openstack server reboot --wait ${vm_name}
+ BuiltIn.Wait Until Keyword Succeeds 35s 10s OpenStackOperations.Verify VM Is ACTIVE ${vm_name}
+
+Remove RSA Key From KnownHosts
+ [Arguments] ${vm_ip}
+ [Documentation] Remove RSA
+ OpenStackOperations.Get ControlNode Connection
+ ${output} = DevstackUtils.Write Commands Until Prompt And Log sudo cat /root/.ssh/known_hosts 30s
+ ${output} = DevstackUtils.Write Commands Until Prompt And Log sudo ssh-keygen -f "/root/.ssh/known_hosts" -R ${vm_ip} 30s
+ ${output} = DevstackUtils.Write Commands Until Prompt sudo cat "/root/.ssh/known_hosts" 30s
+
+Wait For Routes To Propogate
+ [Arguments] ${networks} ${subnets}
+ [Documentation] Check propagated routes
+ OpenStackOperations.Get ControlNode Connection
+ : FOR ${INDEX} IN RANGE 0 1
+ \ ${net_id} = OpenStackOperations.Get Net Id @{networks}[${INDEX}]
+ \ ${is_ipv6} = String.Get Regexp Matches @{subnets}[${INDEX}] ${IP6_REGEX}
+ \ ${length} = BuiltIn.Get Length ${is_ipv6}
+ \ ${cmd} = BuiltIn.Set Variable If ${length} == 0 ip route ip -6 route
+ \ ${output} = Utils.Write Commands Until Expected Prompt sudo ip netns exec qdhcp-${net_id} ${cmd} ]>
+ \ BuiltIn.Should Contain ${output} @{subnets}[${INDEX}]
+
+Neutron Cleanup
+ [Arguments] ${vms}=@{EMPTY} ${networks}=@{EMPTY} ${subnets}=@{EMPTY} ${ports}=@{EMPTY} ${sgs}=@{EMPTY}
+ : FOR ${vm} IN @{vms}
+ \ BuiltIn.Run Keyword And Ignore Error Delete Vm Instance ${vm}
+ : FOR ${port} IN @{ports}
+ \ BuiltIn.Run Keyword And Ignore Error Delete Port ${port}
+ : FOR ${subnet} IN @{subnets}
+ \ BuiltIn.Run Keyword And Ignore Error Delete SubNet ${subnet}
+ : FOR ${network} IN @{networks}
+ \ BuiltIn.Run Keyword And Ignore Error Delete Network ${network}
+ : FOR ${sg} IN @{sgs}
+ \ BuiltIn.Run Keyword And Ignore Error Delete SecurityGroup ${sg}
+
+OpenStack List All
+ [Documentation] Get a list of different OpenStack resources that might be in use.
+ @{modules} = BuiltIn.Create List server port network subnet security group
+ ... security group rule
+ BuiltIn.Run Keyword If "${ODL_ENABLE_L3_FWD}"=="yes" Collections.Append To List ${modules} floating ip router
+ : FOR ${module} IN @{modules}
+ \ ${output} = OpenStack CLI openstack ${module} list
+
+OpenStack CLI Get List
+ [Arguments] ${cmd}
+ [Documentation] Return a json list from the output of an OpenStack command.
+ @{list} = BuiltIn.Create List
+ ${json} = OpenStack CLI ${cmd}
+ @{list} = RequestsLibrary.To Json ${json}
+ BuiltIn.Log ${list}
+ [Return] @{list}
+
+OpenStack CLI
+ [Arguments] ${cmd}
+ [Documentation] Run the given OpenStack ${cmd} and log the output.
+ ${rc} ${output} = OperatingSystem.Run And Return Rc And Output ${cmd}
+ BuiltIn.Log ${output}
+ BuiltIn.Should Be True '${rc}' == '0'
+ [Return] ${output}
+
+OpenStack CLI With No Log
+ [Arguments] ${cmd}
+ [Documentation] Run the given OpenStack ${cmd} and do not log the output.
+ ${rc} ${output} = OperatingSystem.Run And Return Rc And Output ${cmd}
+ BuiltIn.Should Be True '${rc}' == '0'
+ [Return] ${output}
+
+OpenStack Cleanup All
+ [Documentation] Cleanup all Openstack resources with best effort. The keyword will query for all resources
+ ... in use and then attempt to delete them. Errors are ignored to allow the cleanup to continue.
+ @{fips} = BuiltIn.Run Keyword If "${ODL_ENABLE_L3_FWD}"=="yes" OpenStack CLI Get List openstack floating ip list -f json
+ ... ELSE BuiltIn.Create List @{EMPTY}
+ : FOR ${fip} IN @{fips}
+ \ BuiltIn.Run Keyword And Ignore Error Delete Floating IP ${fip['ID']}
+ @{vms} = OpenStack CLI Get List openstack server list -f json
+ : FOR ${vm} IN @{vms}
+ \ BuiltIn.Run Keyword And Ignore Error Delete Vm Instance ${vm['ID']}
+ @{routers} = BuiltIn.Run Keyword If "${ODL_ENABLE_L3_FWD}"=="yes" OpenStack CLI Get List openstack router list -f json
+ ... ELSE BuiltIn.Create List @{EMPTY}
+ : FOR ${router} IN @{routers}
+ \ BuiltIn.Run Keyword And Ignore Error Cleanup Router ${router['ID']}
+ @{ports} = OpenStack CLI Get List openstack port list -f json
+ : FOR ${port} IN @{ports}
+ \ BuiltIn.Run Keyword And Ignore Error Delete Port ${port['ID']}
+ @{networks} = OpenStack CLI Get List openstack network list -f json
+ : FOR ${network} IN @{networks}
+ \ BuiltIn.Run Keyword And Ignore Error Delete Subnet ${network['Subnets']}
+ \ BuiltIn.Run Keyword And Ignore Error Delete Network ${network['ID']}
+ @{security_groups} = OpenStack CLI Get List openstack security group list -f json
+ : FOR ${security_group} IN @{security_groups}
+ \ BuiltIn.Run Keyword If "${security_group['Name']}" != "default" BuiltIn.Run Keyword And Ignore Error Delete SecurityGroup ${security_group['ID']}
+ OpenStack List All
+
+Cleanup Router
+ [Arguments] ${id}
+ [Documentation] Delete a router, but first remove any interfaces or gateways so that the delete will be successful.
+ @{ports} = OpenStack CLI Get List openstack port list --router ${id} -f json --long
+ : FOR ${port} IN @{ports}
+ \ ${subnet_id} = OpenStackOperations.Get Match ${port['Fixed IP Addresses']} ${REGEX_UUID} 0
+ \ BuiltIn.Run Keyword If "${port['Device Owner']}" == "network:router_gateway" BuiltIn.Run Keyword And Ignore Error Remove Gateway ${id}
+ \ BuiltIn.Run Keyword If "${port['Device Owner']}" == "network:router_interface" BuiltIn.Run Keyword And Ignore Error Remove Interface ${id} ${subnet_id}
+ BuiltIn.Run Keyword And Ignore Error Delete Router ${id}
+
+OpenStack Suite Setup
+ [Documentation] Wrapper teardown keyword that can be used in any suite running in an openstack environement
+ SetupUtils.Setup_Utils_For_Setup_And_Teardown
+ DevstackUtils.Devstack Suite Setup
+ @{tcpdump_port_6653_conn_ids} = OpenStackOperations.Start Packet Capture On Nodes tcpdump_port_6653 port 6653 @{OS_ALL_IPS}
+ BuiltIn.Set Suite Variable @{tcpdump_port_6653_conn_ids}
+ BuiltIn.Run Keyword If "${PRE_CLEAN_OPENSTACK_ALL}"=="True" OpenStack Cleanup All
+ OpenStackOperations.Add OVS Logging On All OpenStack Nodes
+
+OpenStack Suite Teardown
+ [Documentation] Wrapper teardown keyword that can be used in any suite running in an openstack environement
+ ... to clean up all openstack resources. For example, all instances, networks, ports, etc will be listed and
+ ... and deleted. As other global cleanup tasks are needed, they can be added here and the suites will all
+ ... benefit automatically.
+ OpenStack Cleanup All
+ OpenStackOperations.Stop Packet Capture On Nodes ${tcpdump_port_6653_conn_ids}
+ SSHLibrary.Close All Connections
+
+Copy DHCP Files From Control Node
+ [Documentation] Copy the current DHCP files to the robot vm. The keyword must be called
+ ... after the subnet(s) are created and before the subnet(s) are deleted.
+ ${suite_} = BuiltIn.Evaluate """${SUITE_NAME}""".replace(" ","_").replace("/","_").replace(".","_")
+ ${dstdir} = BuiltIn.Set Variable /tmp/qdhcp/${suite_}
+ OperatingSystem.Create Directory ${dstdir}
+ OpenStackOperations.Get ControlNode Connection
+ BuiltIn.Run Keyword And Ignore Error SSHLibrary.Get Directory /opt/stack/data/neutron/dhcp ${dstdir} recursive=True
+
+Is Feature Installed
+ [Arguments] ${features}=none
+ : FOR ${feature} IN @{features}
+ \ ${status} ${output} BuiltIn.Run Keyword And Ignore Error BuiltIn.Should Contain ${CONTROLLERFEATURES} ${feature}
+ \ Return From Keyword If "${status}" == "PASS" True
+ [Return] False
+
+Add OVS Logging On All OpenStack Nodes
+ [Documentation] Add higher levels of OVS logging to all the OpenStack nodes
+ BuiltIn.Run Keyword If 0 < ${NUM_OS_SYSTEM} OVSDB.Add OVS Logging ${OS_CNTL_CONN_ID}
+ BuiltIn.Run Keyword If 1 < ${NUM_OS_SYSTEM} OVSDB.Add OVS Logging ${OS_CMP1_CONN_ID}
+ BuiltIn.Run Keyword If 2 < ${NUM_OS_SYSTEM} OVSDB.Add OVS Logging ${OS_CMP2_CONN_ID}
+
+Reset OVS Logging On All OpenStack Nodes
+ [Documentation] Reset the OVS logging to all the OpenStack nodes
+ BuiltIn.Run Keyword If 0 < ${NUM_OS_SYSTEM} OVSDB.Reset OVS Logging ${OS_CNTL_CONN_ID}
+ BuiltIn.Run Keyword If 1 < ${NUM_OS_SYSTEM} OVSDB.Reset OVS Logging ${OS_CMP1_CONN_ID}
+ BuiltIn.Run Keyword If 2 < ${NUM_OS_SYSTEM} OVSDB.Reset OVS Logging ${OS_CMP2_CONN_ID}
+
+Start Packet Capture On Nodes
+ [Arguments] ${tag} ${filter} @{ips}
+ [Documentation] Wrapper keyword around the TcpDump packet capture that is catered to the Openstack setup.
+ ... The caller must pass the three arguments with a variable number of ips at the end,
+ ... but ${EMPTY} can be used for the tag and filter.
+ ${suite_} = BuiltIn.Evaluate """${SUITE_NAME}""".replace(" ","_").replace("/","_").replace(".","_")
+ ${tag_} = BuiltIn.Catenate SEPARATOR=__ ${tag} ${suite_}
+ @{conn_ids} = Tcpdump.Start Packet Capture on Nodes tag=${tag_} filter=${filter} ips=${ips}
+ [Return] @{conn_ids}
+
+Stop Packet Capture On Nodes
+ [Arguments] ${conn_ids}=@{EMPTY}
+ Tcpdump.Stop Packet Capture on Nodes ${conn_ids}