Use OpenStack CLI for nova cli commands
[integration/test.git] / csit / libraries / OpenStackOperations.robot
index 98aa245473a58e00b10482c1c1b114da421691b3..1f6ae074fde7184a39e439a5c0f9fee66d2c7612 100644 (file)
@@ -7,8 +7,10 @@ Library           SSHLibrary
 Resource          DataModels.robot
 Resource          DevstackUtils.robot
 Resource          L2GatewayOperations.robot
+Resource          OVSDB.robot
 Resource          SetupUtils.robot
 Resource          SSHKeywords.robot
+Resource          Tcpdump.robot
 Resource          Utils.robot
 Resource          ../variables/Variables.robot
 Resource          ../variables/netvirt/Variables.robot
@@ -144,9 +146,7 @@ List Ports
 
 List Nova VMs
     [Documentation]    List VMs and return output with nova client.
-    ${rc}    ${output}=    Run And Return Rc And Output    openstack server list --all-projects
-    Log    ${output}
-    Should Be True    '${rc}' == '0'
+    ${output}=    OpenStack CLI    openstack server list --all-projects
     [Return]    ${output}
 
 Create And Associate Floating IPs
@@ -161,9 +161,7 @@ Create And Associate Floating IPs
     \    ${ip_length}    Get Length    ${ip}
     \    Run Keyword If    ${ip_length}>0    Append To List    ${ip_list}    @{ip}[0]
     \    ...    ELSE    Append To List    ${ip_list}    None
-    \    ${rc}    ${output}=    Run And Return Rc And Output    openstack server add floating ip ${vm} @{ip}[0]
-    \    Log    ${output}
-    \    Should Be True    '${rc}' == '0'
+    \    OpenStack CLI    openstack server add floating ip ${vm} @{ip}[0]
     [Return]    ${ip_list}
 
 Delete Floating IP
@@ -207,8 +205,7 @@ Verify No Gateway Ips
 Delete Vm Instance
     [Arguments]    ${vm_name}
     [Documentation]    Delete Vm instances using instance names.
-    ${rc}    ${output}=    Run And Return Rc And Output    openstack server delete ${vm_name}
-    Log    ${output}
+    OpenStack CLI    openstack server delete ${vm_name}
 
 Get Net Id
     [Arguments]    ${network_name}
@@ -253,17 +250,21 @@ Create Vm Instances
     ${image}    Set Variable If    "${image}"=="${EMPTY}"    ${CIRROS_${OPENSTACK_BRANCH}}    ${image}
     ${net_id}=    Get Net Id    ${net_name}
     : FOR    ${VmElement}    IN    @{vm_instance_names}
-    \    ${rc}    ${output}=    Run And Return Rc And Output    openstack server create --image ${image} --flavor ${flavor} --nic net-id=${net_id} ${VmElement} --security-group ${sg} --min ${min} --max ${max}
-    \    Should Be True    '${rc}' == '0'
-    \    Log    ${output}
+    \    OpenStack CLI    openstack server create --image ${image} --flavor ${flavor} --nic net-id=${net_id} ${VmElement} --security-group ${sg} --min ${min} --max ${max}
+
+Create Vm Instance On Compute Node
+    [Arguments]    ${net_name}    ${vm_name}    ${node_hostname}    ${image}=${EMPTY}    ${flavor}=m1.nano    ${sg}=default
+    [Documentation]    Create a VM instance on a specific compute node.
+    ${image} =    Set Variable If    "${image}"=="${EMPTY}"    ${CIRROS_${OPENSTACK_BRANCH}}    ${image}
+    ${net_id} =    Get Net Id    ${net_name}
+    OpenStack CLI    openstack server create ${vm_name} --image ${image} --flavor ${flavor} --nic net-id=${net_id} --security-group ${sg} --availability-zone nova:${node_hostname}
 
 Create Vm Instance With Port
     [Arguments]    ${port_name}    ${vm_instance_name}    ${image}=${EMPTY}    ${flavor}=m1.nano    ${sg}=default
     [Documentation]    Create One VM instance using given ${port_name} and for given ${compute_node}
     ${image}    Set Variable If    "${image}"=="${EMPTY}"    ${CIRROS_${OPENSTACK_BRANCH}}    ${image}
     ${port_id}=    Get Port Id    ${port_name}
-    ${rc}    ${output}=    Run And Return Rc And Output    openstack server create --image ${image} --flavor ${flavor} --nic port-id=${port_id} ${vm_instance_name} --security-group ${sg}
-    Log    ${output}
+    OpenStack CLI    openstack server create --image ${image} --flavor ${flavor} --nic port-id=${port_id} ${vm_instance_name} --security-group ${sg}
 
 Create Vm Instance With Ports
     [Arguments]    ${port_name}    ${port2_name}    ${vm_instance_name}    ${image}=${EMPTY}    ${flavor}=m1.nano    ${sg}=default
@@ -271,29 +272,21 @@ Create Vm Instance With Ports
     ${image}    Set Variable If    "${image}"=="${EMPTY}"    ${CIRROS_${OPENSTACK_BRANCH}}    ${image}
     ${port_id}=    Get Port Id    ${port_name}
     ${port2_id}=    Get Port Id    ${port2_name}
-    ${rc}    ${output}=    Run And Return Rc And Output    openstack server create --image ${image} --flavor ${flavor} --nic port-id=${port_id} --nic port-id=${port2_id} ${vm_instance_name} --security-group ${sg}
-    Log    ${output}
-    Should Be True    '${rc}' == '0'
+    OpenStack CLI    openstack server create --image ${image} --flavor ${flavor} --nic port-id=${port_id} --nic port-id=${port2_id} ${vm_instance_name} --security-group ${sg}
 
 Create Vm Instance With Port On Compute Node
-    [Arguments]    ${port_name}    ${vm_instance_name}    ${compute_node}    ${image}=${EMPTY}    ${flavor}=m1.nano    ${sg}=default
+    [Arguments]    ${port_name}    ${vm_instance_name}    ${node_hostname}    ${image}=${EMPTY}    ${flavor}=m1.nano    ${sg}=default
     [Documentation]    Create One VM instance using given ${port_name} and for given ${compute_node}
     ${image}    Set Variable If    "${image}"=="${EMPTY}"    ${CIRROS_${OPENSTACK_BRANCH}}    ${image}
     ${port_id}=    Get Port Id    ${port_name}
-    ${hostname_compute_node}=    Get Hypervisor Hostname From IP    ${compute_node}
-    ${rc}    ${output}=    Run And Return Rc And Output    openstack server create --image ${image} --flavor ${flavor} --nic port-id=${port_id} --security-group ${sg} --availability-zone nova:${hostname_compute_node} ${vm_instance_name}
-    Log    ${output}
-    Should Be True    '${rc}' == '0'
+    OpenStack CLI    openstack server create --image ${image} --flavor ${flavor} --nic port-id=${port_id} --security-group ${sg} --availability-zone nova:${node_hostname} ${vm_instance_name}
 
 Get Hypervisor Hostname From IP
     [Arguments]    ${hypervisor_ip}
     [Documentation]    Returns the hostname found for the given IP address if it's listed in hypervisor list. For debuggability
     ...    the full listing is logged first, then followed by a grep | cut to focus on the actual hostname to return
-    ${rc}    ${output}    Run And Return Rc And Output    openstack hypervisor list
-    Log    ${output}
-    ${rc}    ${hostname}=    Run And Return Rc And Output    openstack hypervisor list -f value | grep ${hypervisor_ip} | cut -d" " -f 2
-    Log    ${hostname}
-    Should Be True    '${rc}' == '0'
+    OpenStack CLI    openstack hypervisor list
+    ${hostname}=    OpenStack CLI    openstack hypervisor list -f value | grep "${hypervisor_ip} " | cut -d" " -f 2
     [Return]    ${hostname}
 
 Create Nano Flavor
@@ -305,8 +298,7 @@ Create Nano Flavor
 Verify VM Is ACTIVE
     [Arguments]    ${vm_name}
     [Documentation]    Run these commands to check whether the created vm instance is active or not.
-    ${rc}    ${output}=    Run And Return Rc And Output    openstack server show ${vm_name} | grep OS-EXT-STS:vm_state
-    Should Be True    '${rc}' == '0'
+    ${output}=    OpenStack CLI    openstack server show ${vm_name} | grep OS-EXT-STS:vm_state
     Should Contain    ${output}    active
 
 Poll VM Is ACTIVE
@@ -314,32 +306,6 @@ Poll VM Is ACTIVE
     [Documentation]    Run these commands to check whether the created vm instance is active or not.
     Wait Until Keyword Succeeds    ${retry}    ${retry_interval}    Verify VM Is ACTIVE    ${vm_name}
 
-Collect VM IP Addresses
-    [Arguments]    ${fail_on_none}    @{vm_list}
-    [Documentation]    Using the console-log on the provided ${vm_list} to search for the string "obtained" which
-    ...    correlates to the instance receiving it's IP address via DHCP. Also retrieved is the ip of the nameserver
-    ...    if available in the console-log output. The keyword will also return a list of the learned ips as it
-    ...    finds them in the console log output, and will have "None" for Vms that no ip was found.
-    ${ip_list}    Create List    @{EMPTY}
-    : FOR    ${vm}    IN    @{vm_list}
-    \    ${rc}    ${vm_ip_line}=    Run And Return Rc And Output    openstack console log show ${vm} | grep -i "obtained"
-    \    @{vm_ip}    Get Regexp Matches    ${vm_ip_line}    [0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}
-    \    ${vm_ip_length}    Get Length    ${vm_ip}
-    \    Run Keyword If    ${vm_ip_length}>0    Append To List    ${ip_list}    @{vm_ip}[0]
-    \    ...    ELSE    Append To List    ${ip_list}    None
-    \    ${rc}    ${dhcp_ip_line}=    Run And Return Rc And Output    openstack console log show ${vm} | grep "^nameserver"
-    \    ${dhcp_ip}    Get Regexp Matches    ${dhcp_ip_line}    [0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}
-    \    ${dhcp_ip_length}    Get Length    ${dhcp_ip}
-    \    Run Keyword If    ${dhcp_ip_length}<=0    Append To List    ${dhcp_ip}    None
-    \    ${vm_console_output}=    Run    openstack console log show ${vm}
-    \    Log    ${vm_console_output}
-    ${dhcp_length}    Get Length    ${dhcp_ip}
-    Run Keyword If    '${fail_on_none}' == 'true'    Should Not Contain    ${ip_list}    None
-    Run Keyword If    '${fail_on_none}' == 'true'    Should Not Contain    ${dhcp_ip}    None
-    Should Be True    ${dhcp_length} <= 1
-    Return From Keyword If    ${dhcp_length}==0    ${ip_list}    ${EMPTY}
-    [Return]    ${ip_list}    ${dhcp_ip}
-
 Get Match
     [Arguments]    ${text}    ${regexp}    ${index}=0
     [Documentation]    Wrapper around Get Regexp Matches to return None if not found or the first match if found.
@@ -353,7 +319,7 @@ Get VM IP
     [Arguments]    ${fail_on_none}    ${vm}
     [Documentation]    Get the vm ip address and nameserver by scraping the vm's console log.
     ...    Get VM IP returns three values: [0] the vm IP, [1] the DHCP IP and [2] the vm console log.
-    ${rc}    ${vm_console_output}=    Run And Return Rc And Output    openstack console log show ${vm}
+    ${vm_console_output}=    OpenStack CLI    openstack console log show ${vm}    log_output=False
     ${vm_ip} =    Set Variable    None
     ${dhcp_ip} =    Set Variable    None
     ${match} =    Get Match    ${vm_console_output}    ${REGEX_OBTAINED}
@@ -384,40 +350,38 @@ Get VM IPs
     \    Run Keyword If    "${status}" == "PASS"    BuiltIn.Log    ${ips_and_console_log[2]}
     \    BuiltIn.Run Keyword If    "${status}" == "PASS"    Collections.Append To List    ${vm_ips}    ${ips_and_console_log[0]}
     \    BuiltIn.Run Keyword If    "${status}" == "FAIL"    Collections.Append To List    ${vm_ips}    None
-    \    ${rc}    ${vm_console_output}=    BuiltIn.Run Keyword If    "${status}" == "FAIL"    Run And Return Rc And Output    openstack console log show ${vm}
+    \    ${vm_console_output}=    BuiltIn.Run Keyword If    "${status}" == "FAIL"    OpenStack CLI    openstack console log show ${vm}
     \    BuiltIn.Run Keyword If    "${status}" == "FAIL"    BuiltIn.Log    ${vm_console_output}
     Copy DHCP Files From Control Node
     [Return]    @{vm_ips}    ${ips_and_console_log[1]}
 
 Collect VM IPv6 SLAAC Addresses
-    [Arguments]    ${fail_on_none}    ${prefix}    @{vm_list}
-    [Documentation]    Using the console-log on the provided ${vm_list} to search for the string "inet6" which
-    ...    correlates to the instance generated IPv6 address, based on the ${prefix} received from ODL (SLAAC mode).
-    ${ip_list}    Create List    @{EMPTY}
+    [Arguments]    ${fail_on_none}    ${vm_list}    ${network}    ${subnet}
+    [Documentation]    For each VM parse output of "openstack server show" to get its IPv6 address from Neutron DB.
+    ...    Then try to connect to each VM by SSH and execute there "ip -6 a" command. This double-check allows to
+    ...    obtain and compare IP info (Neutron DB vs dnsmasque/ODL DHCP) and to test L2 connectivity as well.
+    ...    Returns an empty list if no IPv6 addresses found or if SSH connection fails.
+    ...    Otherwise, returns a list of IPv6 addresses.
+    ${ipv6_list}    Create List    @{EMPTY}
     : FOR    ${vm}    IN    @{vm_list}
-    \    Log    ${vm}
-    \    ${rc}    ${vm_ip_line}=    Run And Return Rc And Output    openstack console log show ${vm} | grep -i "inet6"
-    \    Log    ${vm_ip_line}
-    \    Log    ${rc}
-    \    @{vm_ip_list}    Get Regexp Matches    ${vm_ip_line}    ${prefix}
-    \    ${vm_ip_length}    Get Length    ${vm_ip_list}
-    \    Run Keyword If    ${vm_ip_length}>0    Append To List    ${ip_list}    @{vm_ip_list}[0]
-    \    ...    ELSE    Append To List    ${ip_list}    None
-    \    Log    ${ip_list}
-    Run Keyword If    '${fail_on_none}' == 'true'    Should Not Contain    ${ip_list}    None
-    Log    ${ip_list}
-    [Return]    ${ip_list}
+    \    ${output}=    OpenStack CLI    openstack server show ${vm} -f shell
+    \    ${pattern}=    Replace String    ${subnet}    ::/64    (:[a-f0-9]{,4}){,4}
+    \    @{vm_ipv6}=    Get Regexp Matches    ${output}    ${pattern}
+    \    ${vm_ip_length}    Get Length    ${vm_ipv6}[0]
+    \    ${ipv6_data_from_vm}=    Run Keyword If    ${vm_ip_length}>0    Execute Command on VM Instance    ${network}    ${vm_ipv6[0]}
+    \    ...    ip -6 a
+    \    @{ipv6}=    Get Regexp Matches    ${ipv6_data_from_vm}    ${pattern}
+    \    ${ipv6_addr_list_length}    Get Length    @{ipv6}
+    \    Run Keyword If    ${ipv6_addr_list_length}>0    Append To List    ${ipv6_list}    ${ipv6[0]}
+    \    ...    ELSE    Append To List    ${ipv6_list}    None
+    [Return]    ${ipv6_list}
 
 View Vm Console
     [Arguments]    ${vm_instance_names}
     [Documentation]    View Console log of the created vm instances using nova show.
     : FOR    ${VmElement}    IN    @{vm_instance_names}
-    \    ${rc}    ${output}=    Run And Return Rc And Output    openstack server show ${VmElement}
-    \    Log    ${output}
-    \    Should Be True    '${rc}' == '0'
-    \    ${rc}    ${output}=    Run And Return Rc And Output    openstack console log show ${VmElement}
-    \    Log    ${output}
-    \    Should Be True    '${rc}' == '0'
+    \    OpenStack CLI    openstack server show ${VmElement}
+    \    ${output}=    OpenStack CLI    openstack console log show ${VmElement}
 
 Ping Vm From DHCP Namespace
     [Arguments]    ${net_name}    ${vm_ip}
@@ -959,15 +923,13 @@ Create And Configure Security Group
 Add Security Group To VM
     [Arguments]    ${vm}    ${sg}
     [Documentation]    Add the security group provided to the given VM.
-    ${rc}    ${output}=    Run And Return Rc And Output    openstack server add security group ${vm} ${sg}
-    Log    ${output}
-    Should Be True    '${rc}' == '0'
+    ${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.
     Get ControlNode Connection
-    ${output}=    Write Commands Until Prompt And Log    openstack server remove security group ${vm} ${sg}
+    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}
@@ -1052,9 +1014,7 @@ Delete SFC Port Chain
 Reboot Nova VM
     [Arguments]    ${vm_name}
     [Documentation]    Reboot NOVA VM
-    ${rc}    ${output}=    Run And Return Rc And Output    openstack server reboot --wait ${vm_name}
-    Log    ${output}
-    Should Be True    '${rc}' == '0'
+    OpenStack CLI    openstack server reboot --wait ${vm_name}
     Wait Until Keyword Succeeds    35s    10s    Verify VM Is ACTIVE    ${vm_name}
 
 Remove RSA Key From KnownHosts
@@ -1106,10 +1066,10 @@ OpenStack CLI Get List
     [Return]    @{list}
 
 OpenStack CLI
-    [Arguments]    ${cmd}
+    [Arguments]    ${cmd}    ${log_output}=True
     [Documentation]    Run the given OpenStack ${cmd}.
     ${rc}    ${output} =    OperatingSystem.Run And Return Rc And Output    ${cmd}
-    BuiltIn.Log    ${output}
+    Run Keyword If    "${log_output}"=="True"    BuiltIn.Log    ${output}
     Should Be True    '${rc}' == '0'
     [Return]    ${output}
 
@@ -1150,7 +1110,9 @@ Cleanup Router
 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
+    Run Keyword If    "${PRE_CLEAN_OPENSTACK_ALL}"=="True"    OpenStack Cleanup All
     DevstackUtils.Devstack Suite Setup
+    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
@@ -1172,6 +1134,31 @@ Copy DHCP Files From Control Node
 Is Feature Installed
     [Arguments]    ${features}=none
     : FOR    ${feature}    IN    ${features}
-    \    ${status}    ${output}    Run Keyword And Ignore Error    Builtin.Should Contain    ${CFEATURES}    ${feature}
+    \    ${status}    ${output}    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
+    Run Keyword If    0 < ${NUM_OS_SYSTEM}    OVSDB.Add OVS Logging    ${OS_CNTL_CONN_ID}
+    Run Keyword If    1 < ${NUM_OS_SYSTEM}    OVSDB.Add OVS Logging    ${OS_CMP1_CONN_ID}
+    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
+    Run Keyword If    0 < ${NUM_OS_SYSTEM}    OVSDB.Reset OVS Logging    ${OS_CNTL_CONN_ID}
+    Run Keyword If    1 < ${NUM_OS_SYSTEM}    OVSDB.Reset OVS Logging    ${OS_CMP1_CONN_ID}
+    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_}
+    @{capture_conn_ids} =    Tcpdump.Start Packet Capture on Nodes    tag=${tag_}    filter=${filter}    ips=${ips}
+    BuiltIn.Set Suite Variable    @{capture_conn_ids}
+
+Stop Packet Capture On Nodes
+    Tcpdump.Stop Packet Capture on Nodes    ${capture_conn_ids}