*** 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 to manage SDNCs.

Library   String
Library   Collections
Library   OperatingSystem

Resource   ../lib/prometheus_lib.resource


*** Variables ***
${SUCCESS_RETURN_CODE}   0
${SDNC_DELETE_MAX_WAIT_TIME}   1min
${SDNC_DELETE_POL_TIME}   15sec
${SDNC_STATUS_MAX_WAIT_TIME}   6min
${SDNC_STATUS_POL_TIME}   1min


*** Keywords ***
Create SDNC
    [Documentation]   Register an SDN Controller in OSM.
    ...                 The optional parameters (such as 'switch_dpid' or 'ip-address') are given to this function in name=value format. These parameters will be appended to the 'osm sdnc-create' command with the next syntax: --param_name=param_value
    ...                 Returns the ID of the created SDNC Target.
    ...                 Example of execution:
    ...                     \${sdnc_id}=   Create SDNC   \${sdnc_name}   \${sdnc_user}   \${sdnc_password}   \${sdnc_url}   \${sdnc_type}   switch_dpid='{...}'
    [Arguments]   ${sdnc_name}   ${sdnc_user}   ${sdnc_password}   ${sdnc_url}   ${sdnc_type}   @{optional_parameters}
    ${osm_sdnc_create_command}=   Set Variable   osm sdnc-create --name ${sdnc_name} --user ${sdnc_user} --password ${sdnc_password} --url ${sdnc_url} --type ${sdnc_type}
    FOR   ${param}   IN   @{optional_parameters}
        ${match}   ${param_name}   ${param_value}=   Should Match Regexp   ${param}   (.+)=(.+)   msg=Syntax error in optional parameters
        Log   ${match},${param_name},${param_value}
        ${osm_sdnc_create_command}=   Catenate   ${osm_sdnc_create_command}   --${param_name}=${param_value}
    END
    ${rc}   ${stdout}=   Run And Return Rc And Output   ${osm_sdnc_create_command}
    Log   ${stdout}
    Should Be Equal As Integers   ${rc}   ${SUCCESS_RETURN_CODE}
    RETURN   ${stdout}

Check For SDNC To Be Deleted
    [Documentation]   Check if an SDN controller identified by name is not present in OSM.
    [Arguments]   ${sdnc_name}
    ${rc}   ${stdout}=   Run And Return Rc And Output   osm sdnc-list | awk '{print $2}' | grep ${sdnc_name}
    Log   ${rc},${stdout}
    Should Not Be Equal As Strings   ${stdout}   ${sdnc_name}

Delete SDNC
    [Documentation]   Unregister/delete from OSM an SDN controller identified by name.
    [Arguments]   ${sdnc_name}
    ${rc}   ${stdout}=   Run Keyword And Continue On Failure   Run And Return Rc And Output   osm sdnc-delete ${sdnc_name}
    Log   ${stdout}
    Should Be Equal As Integers   ${rc}   ${SUCCESS_RETURN_CODE}   msg=${stdout}   values=False
    Wait Until Keyword Succeeds   ${SDNC_DELETE_MAX_WAIT_TIME}   ${SDNC_DELETE_POL_TIME}   Check For SDNC To Be Deleted   ${sdnc_name}

Get SDNC List
    [Documentation]   Get the list of SDN controllers from OSM and log it.
    ${rc}   ${stdout}=   Run And Return Rc And Output   osm sdnc-list
    Log   ${stdout}
    Should Be Equal As Integers   ${rc}   ${SUCCESS_RETURN_CODE}

Check For SDNC
    [Documentation]   Check if an SDN Controller identified by name or id exists in OSM and is enabled.
    [Arguments]   ${sdnc_id}
    ${rc}   ${stdout}=   Run And Return Rc And Output   osm sdnc-show ${sdnc_id} | grep -io ENABLED
    Log   ${stdout}
    Should Be Equal As Integers   ${rc}   ${SUCCESS_RETURN_CODE}

Check For SDNC Status
    [Documentation]   Check in a loop if the value of the metric osm_sdnc_status in Prometheus for the SDN controller is 1 (reachable).
    [Arguments]   ${sdnc_id}   ${prometheus_url}   ${prometheus_user}   ${prometheus_password}
    Wait Until Keyword Succeeds   ${SDNC_STATUS_MAX_WAIT_TIME}   ${SDNC_STATUS_POL_TIME}   Check If SDNC Is Available   ${sdnc_id}   ${prometheus_url}   ${prometheus_user}   ${prometheus_password}

Get SDNC ID
    [Documentation]   Check if an SDN controller identified by name exists in OSM, and return the id.
    [Arguments]   ${sdnc_name}
    ${rc}   ${stdout}=   Run And Return Rc And Output   osm sdnc-list | grep " ${sdnc_name} " | awk '{print $4}'
    Should Be Equal As Integers   ${rc}   ${SUCCESS_RETURN_CODE}
    Should Not Be Equal As Strings   ${stdout}   ${EMPTY}   msg=SDNC '${sdnc_name}' not found   values=false
    RETURN   ${stdout}

Check If SDNC Is Available
    [Documentation]   Check if the value of the metric osm_sdnc_status in Prometheus for the SDN controller is 1 (reachable).
    [Arguments]   ${sdnc_id}   ${prometheus_url}   ${prometheus_user}   ${prometheus_password}
    ${metric}=   Get Metric   ${prometheus_url}   ${prometheus_user}   ${prometheus_password}   osm_sdnc_status   sdnc_id=${sdnc_id}
    Should Be Equal As Integers   ${metric}   1   msg=SDNC '${sdnc_id}' is not active   values=false
