*** Comments ***
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#       http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.


*** Settings ***
Documentation   Library providing keywords to interact with Openstack with openstack client.

Library   OperatingSystem
Library   String

Resource   ns_lib.resource
Resource   vnf_lib.resource


*** Variables ***
${SUCCESS_RETURN_CODE}   0


*** Keywords ***
Get Server Flavor ID
    [Documentation]   Get from Openstack the flavor id of a server/VM passed as argument.
    [Arguments]   ${server_id}
    Should Not Be Empty   ${server_id}
    ${rc}   ${stdout}=   Run And Return Rc And Output   openstack server show ${server_id} -c flavor -f value |yq -r '.id'
    Log   ${stdout}
    Should Be Equal As Integers   ${rc}   ${SUCCESS_RETURN_CODE}
    RETURN   ${stdout}

Get Flavor Properties
    [Documentation]   Get from Openstack the properties of a flavor passed as argument.
    [Arguments]   ${flavor_id}
    Should Not Be Empty   ${flavor_id}
    ${rc}   ${stdout}=   Run And Return Rc And Output   openstack flavor show ${flavor_id} | grep properties | awk -F '|' '{print $3}'
    Log   ${stdout}
    Should Be Equal As Integers   ${rc}   ${SUCCESS_RETURN_CODE}
    RETURN   ${stdout}

Check NS Servers In VIM
    [Documentation]   Check if the number of servers in Openstack by filtering by NS name is as expected.
    [Arguments]   ${ns_name}   ${number}
    Should Not Be Empty   ${ns_name}
    ${rc}   ${stdout}=   Run And Return Rc And Output   openstack server list | grep ${ns_name} | awk '{print $4}'
    Log   ${stdout}
    Should Be Equal As Integers   ${rc}   ${SUCCESS_RETURN_CODE}
    @{servers}=   Split String   ${stdout}
    ${n_servers}=   Get Length   ${servers}
    Should Be Equal As Integers   ${number}   ${n_servers}

Check If Volume Bootable
    [Documentation]   Check the volume properties and return whether it is bootable or not.
    [Arguments]   ${volume_id}
    Should Not Be Empty   ${volume_id}
    ${rc}   ${stdout}=   Run And Return Rc And Output   openstack volume show ${volume_id} | grep bootable | awk '{print $4}'
    Log   ${stdout}
    Should Be Equal As Integers   ${rc}   ${SUCCESS_RETURN_CODE}
    RETURN   ${stdout}

Get Project Quota
    [Documentation]   Get a field (ram, cores, ports, etc.) from quota in current project.
    [Arguments]   ${field}
    Should Not Be Empty   ${field}
    ${rc}   ${stdout}=   Run And Return Rc And Output   openstack quota show -f yaml | yq '.[] | select(.Resource=="${field}") | .Limit'
    Log   ${stdout}
    Should Be Equal As Integers   ${rc}   ${SUCCESS_RETURN_CODE}
    RETURN   ${stdout}

Get Server Property
    [Documentation]   Get a field (flavor, image, volumes_attached, etc.) from a server.
    [Arguments]   ${server_id}   ${field}
    Should Not Be Empty   ${server_id}
    Should Not Be Empty   ${field}
    ${rc}   ${stdout}=   Run And Return Rc And Output   openstack server show ${server_id} -c ${field} -f value
    Log   ${stdout}
    Should Be Equal As Integers   ${rc}   ${SUCCESS_RETURN_CODE}
    RETURN   ${stdout}

Check VM In Server Group
    [Documentation]   Check if a given server is included in an Openstack server group
    [Arguments]   ${server_id}   ${server_group_name}
    Should Not Be Empty   ${server_group_name}
    Should Not Be Empty   ${server_id}
    ${rc}   ${stdout}=   Run And Return Rc And Output   openstack server group show ${server_group_name} -c members -f value
    Log   ${stdout}
    Should Be Equal As Integers   ${rc}   ${SUCCESS_RETURN_CODE}
    Should Contain   ${stdout}   ${server_id}

Set Volume Id
    [Documentation]   Sets the root volume ID and ordinary volume ID by checking bootable property of volumes
    [Arguments]   ${volume_match}   ${index}
    Should Not Be Empty   ${volume_match}   ${index}
    ${bootable}=   Check If Volume Bootable   ${volume_match}[${index}]
    IF   '${bootable}'=='true'
        Set Suite Variable   ${ROOT_VOL_ID}   ${volume_match}[${index}]
        IF   not ${index}
            Set Suite Variable   ${ORDINARY_VOL_ID}   ${volume_match}[1]
        ELSE
            Set Suite Variable   ${ORDINARY_VOL_ID}   ${volume_match}[0]
        END
    END

Get Persistent Volumes Attached To Vm
    [Documentation]   Sets the root volume ID and ordinary volume ID by checking bootable property of volumes
    [Arguments]   ${ns_id}
    Variable Should Exist   ${ns_id}   msg=NS is not available
    ${vnfs_list}=   Get Ns Vnf List   ${ns_id}
    ${vim_id}=   Get VNF VIM ID   ${vnfs_list}[0]
    ${volumes_attached}=   Get Server Property   ${vim_id}   volumes_attached
    Log   ${volumes_attached}
    ${stdout}=   Get Regexp Matches   ${volumes_attached}   '([0-9a-f\-]+)'   1
    Log   ${stdout}
    RETURN   ${stdout}

Check If Volume Exists
    [Documentation]   Checks if a volume id exists
    [Arguments]   ${volume_id}
    Should Not Be Empty   ${volume_id}
    ${rc}   ${stdout}=   Run And Return Rc And Output   openstack volume list | grep ${volume_id} | wc -l
    Log   ${stdout}
    Should Be Equal As Integers   ${rc}   ${SUCCESS_RETURN_CODE}
    RETURN   ${stdout}

Delete Volume
    [Documentation]   Delete a volume by its identifier
    [Arguments]   ${volume_id}
    Should Not Be Empty   ${volume_id}
    ${rc}   ${stdout}=   Run And Return Rc And Output   openstack volume delete ${volume_id}
    Log   ${stdout}
    Should Be Equal As Integers   ${rc}   ${SUCCESS_RETURN_CODE}
    RETURN   ${stdout}

Get Subnet
    [Documentation]   Get subnet information in JSON format
    [Arguments]   ${subnet_id}
    Should Not Be Empty   ${subnet_id}
    ${rc}   ${stdout}=   Run And Return Rc And Output   openstack subnet show ${subnet_id} -f json
    Log   ${stdout}
    Should Be Equal As Integers   ${rc}   ${SUCCESS_RETURN_CODE}
    RETURN   ${stdout}

Stop Server
    [Documentation]   Stop a server
    [Arguments]   ${server_id}
    Should Not Be Empty   ${server_id}
    ${rc}   ${stdout}=   Run And Return Rc And Output   openstack server stop ${server_id}
    Log   ${stdout}
    Should Be Equal As Integers   ${rc}   ${SUCCESS_RETURN_CODE}
    RETURN   ${stdout}

Halt Server
    [Documentation]   Reset a server
    [Arguments]   ${server_id}
    Should Not Be Empty   ${server_id}
    ${rc}   ${stdout}=   Run And Return Rc And Output   openstack server set --state error ${server_id}
    Log   ${stdout}
    Should Be Equal As Integers   ${rc}   ${SUCCESS_RETURN_CODE}
    RETURN   ${stdout}

Delete Server
    [Documentation]   Delete a server
    [Arguments]   ${server_id}
    Should Not Be Empty   ${server_id}
    ${rc}   ${stdout}=   Run And Return Rc And Output   openstack server delete ${server_id}
    Log   ${stdout}
    Should Be Equal As Integers   ${rc}   ${SUCCESS_RETURN_CODE}
    RETURN   ${stdout}

Create Flavor
    [Documentation]   Create a Flavor
    [Arguments]   ${flavor_name}   ${cpu}=1   ${ram}=1024   ${disk}=10
    Should Not Be Empty   ${flavor_name}
    ${rc}   ${flavor_id}=   Run And Return Rc And Output   openstack flavor create ${flavor_name} --ram ${ram} --disk ${disk} --vcpus ${cpu} -c id -f value
    Log   ${flavor_id}
    Should Be Equal As Integers   ${rc}   ${SUCCESS_RETURN_CODE}
    RETURN   ${flavor_id}

Delete Flavor
    [Documentation]   Delete a Flavor
    [Arguments]   ${flavor_id}
    Should Not Be Empty   ${flavor_id}
    ${rc}   ${stdout}=   Run And Return Rc And Output   openstack flavor delete ${flavor_id}
    Log   ${stdout}
    Should Be Equal As Integers   ${rc}   ${SUCCESS_RETURN_CODE}
    RETURN   ${stdout}

Openstack Server List
    [Documentation]   Get the openstack server list
    [Arguments]   ${ns_name}
    ${result}=   Run And Return Rc And Output   openstack server list | grep ${ns_name} | awk 'index($0, "ipv6=") {gsub(/,$/, ""); gsub("ipv6=", ""); print $8, $9}'
    ${rc}=   Get From List   ${result}   0
    ${Ip}=   Get From List   ${result}   1
    Log   ${Ip}
    Should Be Equal As Integers   ${rc}   ${success_return_code}
    RETURN   ${Ip}

Source Openrc Command
    [Documentation]   Keyword to source openstack tenant
    Write   source openrc
