*** Settings ***
Documentation     Test suite for VTN Functionality
Suite Setup       Suite Setup
Suite Teardown    Suite Teardown
Variables         ../Framework/restApi.py
Library           Collections
Library           String
Library           OperatingSystem
Library           XML
Library           RequestsLibrary
Library           ../Framework/utils/utils.py
Library           ../Framework/restApi.py
Library           ../Framework/utils/openstackUtils.py
Variables         ../Properties/RestApiProperties.py
Resource           ../Framework/utils/utils.robot

*** Variables ***
${VM_USER}                         admin
${VM_PASS}                         admin
${head_node}                       head1
${SSH_KEY}                         id_rsa.pub
${ONOS_CORDVTN_API}                http://onos-cord:8182/onos/cordvtn
${CORE_SERVICE_PATHFILE}           ${CURDIR}/data/Service.json
${CORE_NETWORK_PATHFILE}           ${CURDIR}/data/CoreNetwork.json
${CORE_SLICE_PATHFILE}             ${CURDIR}/data/CoreSlice.json
${CORE_NETWORK_SLICE_PATHFILE}     ${CURDIR}/data/CoreNetworkSlice.json
${CORE_INSTANCE_PATHFILE}          ${CURDIR}/data/CoreInstance.json
${CORD_SUBSCRIBER_PATHFILE}        ${CURDIR}/data/CordSubscriber.json
${VOLT_TENANT_PATHFILE}            ${CURDIR}/data/CordVoltTenant.json
${ciab_local}                      True
${physical_pod}                    True
${default_flow_count}              42
${final_flow_count}                49
${expected_num_networks}           4
${expected_num_ports}              5

*** Test Cases ***
Validate Default OVS Flow Count
    [Documentation]    Logs into the compute-node where OVS is running and validates the default flow count
    [Tags]    ovsflows
    Wait Until Keyword Succeeds    30s    5s    Validate Flow Count    ${default_flow_count}

Validate Current VTN Service Networks and Ports
    [Documentation]    Makes rest calls to XOS to validate the default VTN Service Networks + Ports (public,management,exampleservice_network,mysite_vsg-access)
    [Tags]    vtn    pod
    Validate Default CIAB Service Networks and Ports via XOS

Validate Default Subscriber
    [Documentation]    Validates the default subscriber set up in CIAB (My House)
    [Tags]    vsg
    ${resp}=    CORD GET    ${SERVER_IP}    ${VOLT_SUBSCRIBER}/5
    Should Be Equal As Strings    ${resp.status_code}    200
    Log    ${resp.content}
    ${name}=    Get Json Value    ${resp.content}    /name
    ${service_specific_id}=    Get Json Value    ${resp.content}    /service_specific_id
    ${uplink_speed}=    Get Json Value    ${resp.content}    /uplink_speed
    Should Be Equal As Strings    ${name}    "My House"
    Should Be Equal As Strings    ${service_specific_id}    "123"
    Should Be Equal As Strings    ${uplink_speed}    1000000000

Create New Test Service
    [Documentation]    Creates a generic service that will be used for the new VTN Network
    [Tags]    vtn    pod
    ${updatedcservList}=    utils.setFieldValueInDict    ${cservlist[0]}    name    CordVTN-Test-Service
    ${updatedcservList}=    utils.setFieldValueInDict    ${updatedcservList}    description    Test Service for CordVTN Test Suite
    ${resp}=    Cord POST    ${SERVER_IP}    ${CH_CORE_SERVICES}    ${updatedcservList}
    Should Be Equal As Strings    ${resp.status_code}    200
    ${name}=    Get Json Value    ${resp.content}    /name
    ${generic_service_id}=    Get Json Value    ${resp.content}    /id
    ${description}=    Get Json Value    ${resp.content}    /description
    ${kind}=    Get Json Value    ${resp.content}    /kind
    Should Be Equal As Strings    ${name}    "CordVTN-Test-Service"
    Should Be Equal As Strings    ${description}    "Test Service for CordVTN Test Suite"
    Should Be Equal As Strings    ${kind}    "generic"
    Set Suite Variable    ${generic_service_id}

Create New VTN Service Network
    [Documentation]    Makes a POST Request to XOS to create a new core network
    [Tags]    vtn    pod
    ${updatedCnList}=    utils.setFieldValueInDict    ${cnlist[0]}    template_id    ${vsg_network_template_id}
    ${updatedCnList}=    utils.setFieldValueInDict    ${updatedCnList}    owner_id    ${vsg_slice_id}
    Log    ${updatedCnList}
    ${resp}=    Cord POST    ${SERVER_IP}    ${CH_CORE_NETWORKS}    ${cnlist[0]}
    Should Be Equal As Strings    ${resp.status_code}    200
    ${name}=    Get Json Value    ${resp.content}    /name
    ${network_id}=    Get Json Value    ${resp.content}    /id
    ${subnet}=    Get Json Value    ${resp.content}    /subnet
    ${start_ip}=    Get Json Value    ${resp.content}    /start_ip
    ${end_ip}=    Get Json Value    ${resp.content}    /end_ip
    Should Be Equal As Strings    ${name}    "test-network"
    Should Be Equal As Strings    ${subnet}    "2.2.2.0/24"
    Should Be Equal As Strings    ${start_ip}    "2.2.2.2"
    Should Be Equal As Strings    ${end_ip}    "2.2.2.254"
    Set Suite Variable    ${network_id}

Create New Slice with New Test Service
    [Documentation]    Makes a POST Request to XOS to create a new slice and adds new generic test service to that slice
    [Tags]    vtn    pod
    ${updatedCsList}=    utils.setFieldValueInDict    ${cslist[0]}    service_id    ${generic_service_id}
    #${updatedCsList}=    utils.setFieldValueInDict    ${cslist[0]}    service_id    12
    Log    ${updatedCsList}
    ${resp}=    Cord POST    ${SERVER_IP}    ${CH_CORE_SLICES}    ${updatedCsList}
    Should Be Equal As Strings    ${resp.status_code}    200
    ${name}=    Get Json Value    ${resp.content}    /name
    ${new_slice_id}=    Get Json Value    ${resp.content}    /id
    ${max_instances}=    Get Json Value    ${resp.content}    /max_instances
    ${ser_id}=    Get Json Value    ${resp.content}    /service_id
    ${default_isolation}=    Get Json Value    ${resp.content}    /default_isolation
    Should Be Equal As Strings    ${name}    "mysite_testservice"
    Should Be Equal As Strings    ${max_instances}    10
    Should Be Equal As Strings    ${ser_id}    ${generic_service_id}
    Should Be Equal As Strings    ${default_isolation}    "vm"
    Set Suite Variable    ${new_slice_id}

Add Networks to New Test Network Slice
    [Documentation]    Creates a new network slice for the new slice and adds mgmt and new network to it
    [Tags]    vsg    pod
    ${updatedCsList}=    utils.setFieldValueInDict    ${cnslist[0]}    network_id    ${network_id}
    #${updatedCsList}=    utils.setFieldValueInDict    ${cnslist[0]}    network_id    5
    ${updatedCsList}=    utils.setFieldValueInDict    ${updatedCsList}    slice_id    ${new_slice_id}
    #${updatedCsList}=    utils.setFieldValueInDict    ${updatedCsList}    slice_id    5
    Log    ${updatedCsList}
    ${resp}=    Cord POST    ${SERVER_IP}    ${CH_CORE_NETWORK_SLICES}    ${updatedCsList}
    Should Be Equal As Strings    ${resp.status_code}    200
    ${s_id}=    Get Json Value    ${resp.content}    /slice_id
    ${n_id}=    Get Json Value    ${resp.content}    /network_id
    #Should Be Equal As Strings    ${s_id}    5
    Should Be Equal As Strings    ${s_id}    ${new_slice_id}
    Should Be Equal As Strings    ${n_id}    ${network_id}
    ##Add mgmt network to this network slice
    ${updatedCsList}=    utils.setFieldValueInDict    ${cnslist[0]}    network_id    ${mgmt_network_id}
    ${updatedCsList}=    utils.setFieldValueInDict    ${updatedCsList}    slice_id    ${new_slice_id}
    #${updatedCsList}=    utils.setFieldValueInDict    ${updatedCsList}    slice_id    5
    Log    ${updatedCsList}
    ${resp}=    Cord POST    ${SERVER_IP}    ${CH_CORE_NETWORK_SLICES}    ${updatedCsList}
    Should Be Equal As Strings    ${resp.status_code}    200
    ${s_id}=    Get Json Value    ${resp.content}    /slice_id
    ${n_id}=    Get Json Value    ${resp.content}    /network_id
    Should Be Equal As Strings    ${s_id}    ${new_slice_id}
    #Should Be Equal As Strings    ${s_id}    5
    Should Be Equal As Strings    ${n_id}    ${mgmt_network_id}

Create New Test Instance
    [Documentation]    Creates a new instance for the test service
    [Tags]    vsg    pod
    ${updatedCiList}=    utils.setFieldValueInDict    ${cilist[0]}    slice_id    ${new_slice_id}
    #${updatedCiList}=    utils.setFieldValueInDict    ${cilist[0]}    slice_id    5
    ${updatedCiList}=    utils.setFieldValueInDict    ${updatedCiList}    image_id    ${image_id}
    Log    ${updatedCiList}
    ${resp}=    Cord POST    ${SERVER_IP}    ${CH_CORE_INSTANCES}    ${updatedCiList}
    #${resp}=    Cord POST    ${SERVER_IP}    ${CH_CORE_INSTANCES}    ${cilist[0]}
    Should Be Equal As Strings    ${resp.status_code}    200
    ${new_instance_id}=    Get Json Value    ${resp.content}    /id
    ${slice_id}=    Get Json Value    ${resp.content}    /slice_id
    ${i_id}=    Get Json Value    ${resp.content}    /image_id
    ${node_id}=    Get Json Value    ${resp.content}    /node_id
    ${name}=    Get Json Value    ${resp.content}    /name
    ${instance_name}=    Get Json Value    ${resp.content}    /instance_name
    Should Be Equal As Strings    ${slice_id}    ${new_slice_id}
    #Should Be Equal As Strings    ${slice_id}    5
    Should Be Equal As Strings    ${i_id}    ${image_id}
    Should Be Equal As Strings    ${node_id}    1
    Should Be Equal As Strings    ${name}    "mysite_testservice"
    Should Be Equal As Strings    ${instance_name}    "mysite_testservice-1"
    Set Suite Variable    ${new_instance_id}

Validate New OVS Flow Count
    [Documentation]    Logs into the compute-node where OVS is running and validates the new flow count (new flow rules for new volt tenant instance)
    [Tags]    ovsflows
    Wait Until Keyword Succeeds    300s    5s    Validate Flow Count    ${final_flow_count}

Validate Creation of Openstack Resources
    [Documentation]    Retrieves openstack compute node state and validates the new network and instance has been created properly
    [Tags]    openstack    pod
    Wait Until Keyword Succeeds    300s    5s    Validate Openstack Network    test-network    2.2.2.0/24
    Sleep    300
    ${test_instance_name}=    Get New Instance
    Wait Until Keyword Succeeds    300s    5s    Validate Openstack Nova Instance    ${test_instance_name}    test-network
    Set Suite Variable    ${test_instance_name}

Validate New Flows Pushed to OVS
    [Documentation]    Logs into the compute-node where OVS is running and validates the new flows added
    [Tags]    ovsflows
    ${ovs_flow_count}=    Run Keyword If    '${ciab_local}' == 'False'        Execute Command on Compute Node in CIAB    ${SERVER_IP}    ${head_node}    ${compute_node_hostname}    ovs-ofctl dump-flows br-int | grep 2.2.2.0 | wc -l    ELSE    Execute Command Locally    ssh -q root@${compute_node_hostname} "ovs-ofctl dump-flows br-int | grep 2.2.2.0 | wc -l"
    ${ovs_flow_count}=    Get Line    ${ovs_flow_count}    0
    Should Be Equal As Integers    ${ovs_flow_count}    2
    ${flows_added}=    Run Keyword If    '${ciab_local}' == 'False'        Execute Command on Compute Node in CIAB    ${SERVER_IP}    ${head_node}    ${compute_node_hostname}    ovs-ofctl dump-flows br-int    ELSE    Execute Command Locally    ssh -q root@${compute_node_hostname} "ovs-ofctl dump-flows br-int"
    ${flows_added}=    Get Lines Containing String    ${flows_added}    cookie=
    Log    ${flows_added}
    ## Match src/dst (bi-directional) rules on new flows added
    Should Contain    ${flows_added}    nw_src=2.2.2.0/24,nw_dst=2.2.2.0/24

Create New Cord Subscriber
    [Documentation]    Creates a new cord root subscriber
    [Tags]    vsg
    ${blacklist_sr_ids}=    Get Subscriber Root IDs in Use
    ${ss_id}=    Generate Random Number from Blacklist    ${blacklist_sr_ids}
    Set Suite Variable    ${ss_id}
    ${updatedcsList}=    utils.setFieldValueInDict    ${csubList[0]}    service_specific_id    ${ss_id}
    Log    ${updatedcsList}
    ${resp}=    Cord POST    ${SERVER_IP}    ${VOLT_SUBSCRIBER}    ${updatedcsList}
    Should Be Equal As Strings    ${resp.status_code}    200
    ${subscriber_root_id}=    Get Json Value    ${resp.content}    /id
    ${enable_uverse}=    Get Json Value    ${resp.content}    /enable_uverse
    ${uplink_speed}=    Get Json Value    ${resp.content}    /uplink_speed
    ${downlink_speed}=    Get Json Value    ${resp.content}    /downlink_speed
    ${status}=    Get Json Value    ${resp.content}    /status
    ${is_demo_user}=    Get Json Value    ${resp.content}    /is_demo_user
    ${service_specific_id}=    Get Json Value    ${resp.content}    /service_specific_id
    Should Be Equal As Strings    ${enable_uverse}    true
    Should Be Equal As Strings    ${uplink_speed}    1000000011
    Should Be Equal As Strings    ${downlink_speed}    1000000011
    Should Be Equal As Strings    ${status}    "enabled"
    Should Be Equal As Strings    ${is_demo_user}    false
    Should Be Equal As Strings    ${service_specific_id}    "${ss_id}"
    Set Suite Variable    ${service_specific_id}
    Set Suite Variable    ${subscriber_root_id}

Create New Volt Tenant for New Cord Subscriber
    [Documentation]    Creates a new volt tenant for the newly created cord root subscriber
    [Tags]    vsg
    ${blacklist_tags}=    Get Tags in Use
    Log    ${blacklist_tags}
    ${s_tag}=    Generate Random Number from Blacklist    ${blacklist_tags}    1    4096    True
    Append To List    ${blacklist_tags}    ${s_tag}
    ${c_tag}=    Generate Random Number from Blacklist    ${blacklist_tags}    1    4096    True
    Append To List    ${blacklist_tags}    ${c_tag}
    Log    ${blacklist_tags}
    ${updatedvtList}=    utils.setFieldValueInDict    ${vtList[0]}    service_specific_id    ${subscriber_root_id}
    #${updatedvtList}=    utils.setFieldValueInDict    ${vtList[0]}    subscriber_root_id    ${subscriber_root_id}
    ${updatedvtList}=    utils.setFieldValueInDict    ${updatedvtList}    s_tag    ${s_tag}
    ${updatedvtList}=    utils.setFieldValueInDict    ${updatedvtList}    c_tag    ${c_tag}
    Log    ${updatedvtList}
    ${resp}=    Cord POST    ${SERVER_IP}    ${VOLT_TENANT}    ${vtList[0]}
    Should Be Equal As Strings    ${resp.status_code}    200
    ${volt_tenant_id}=    Get Json Value    ${resp.content}    /id
    Set Suite Variable    ${volt_tenant_id}
    ${stag}=    Get Json Value    ${resp.content}    /s_tag
    ${ctag}=    Get Json Value    ${resp.content}    /c_tag
    ${ssid}=    Get Json Value    ${resp.content}    /service_specific_id
    Should Be Equal As Strings    ${stag}    ${s_tag}
    Should Be Equal As Strings    ${ctag}    ${c_tag}
    Should Be Equal As Strings   ${ssid}    "${subscriber_root_id}"

Validate Creation of New Subscriber Instance
    [Documentation]    Validates instance (vm) for new subscriber is created in the vsg slice
    [Tags]    openstack
    Sleep    300
    ${new_vsg_instance}=    Get New Instance
    Wait Until Keyword Succeeds    300s    5s    Validate Openstack Nova Instance    ${new_vsg_instance}    mysite_vsg-access
    Set Suite Variable    ${new_vsg_instance}

Delete Volt Tenant
    [Documentation]    Deletes new volt tenant
    [Tags]    delete
    ${resp}=    Cord DELETE    ${SERVER_IP}    ${VOLT_TENANT}    ${volt_tenant_id}
    Should Be Equal As Strings    ${resp.status_code}    200
    Wait Until Keyword Succeeds    300s    5s    Validate Openstack Nova Instance    ${new_vsg_instance}    mysite_vsg-access    destroyed=True

Delete Cord Subscriber
    [Documentation]    Deletes new cord subscriber
    [Tags]    delete
    ${resp}=    Cord DELETE    ${SERVER_IP}    ${VOLT_SUBSCRIBER}    ${subscriber_root_id}
    Should Be Equal As Strings    ${resp.status_code}    200

Delete Test Instance
    [Documentation]    Deletes the test instance created previously
    [Tags]    delete    pod
    ${resp}=    Cord DELETE    ${SERVER_IP}    ${CH_CORE_INSTANCES}    ${new_instance_id}
    Should Be Equal As Strings    ${resp.status_code}    200
    Wait Until Keyword Succeeds    300s    5s    Validate Openstack Nova Instance    ${test_instance_name}    test-network    destroyed=True

Delete Test Slice
    [Documentation]    Deletes the test slice created previously
    [Tags]    delete    pod
    ${resp}=    Cord DELETE    ${SERVER_IP}    ${CH_CORE_SLICES}    ${new_slice_id}
    Should Be Equal As Strings    ${resp.status_code}    200

Delete VTN Test Network
    [Documentation]    Deletes the test network created previously
    [Tags]    delete    pod
    ## Wait for test network to be destroyed via get neutron lists
    ##TODO: Find someting to poll on rather than wait 5 mins
    #Sleep    300
    ${resp}=    Cord DELETE    ${SERVER_IP}    ${CH_CORE_NETWORKS}    ${network_id}
    Should Be Equal As Strings    ${resp.status_code}    200

Delete Test Service
    [Documentation]    Deletes the test service created
    [Tags]    delete    pod
    ${resp}=    Cord DELETE    ${SERVER_IP}    ${CH_CORE_SERVICES}    ${generic_service_id}
    Should Be Equal As Strings    ${resp.status_code}    200

Validate OVS Flow Count Back to Default
    [Documentation]    Logs into the compute-node where OVS is running and validates the new flow count (new flow rules for new volt tenant instance)
    [Tags]    ovsflows
    Wait Until Keyword Succeeds    60s    5s    Validate Flow Count    ${default_flow_count}

Validate New Flows Removed From OVS
    [Documentation]    Validates that the flow rules added by ONOS from the network creation has been removed
    [Tags]    ovsflows
    ${ovs_flow_count}=    Run Keyword If    '${ciab_local}' == 'False'        Execute Command on Compute Node in CIAB    ${SERVER_IP}    ${head_node}    ${compute_node_hostname}    ovs-ofctl dump-flows br-int | grep 2.2.2.0 | wc -l    ELSE    Execute Command Locally    ssh -q root@${compute_node_hostname} "ovs-ofctl dump-flows br-int | grep 2.2.2.0 | wc -l"
    ${ovs_flow_count}=    Get Line    ${ovs_flow_count}    0
    Should Be Equal As Integers    ${ovs_flow_count}    0
    ${flows_added}=    Run Keyword If    '${ciab_local}' == 'False'        Execute Command on Compute Node in CIAB    ${SERVER_IP}    ${head_node}    ${compute_node_hostname}    ovs-ofctl dump-flows br-int    ELSE    Execute Command Locally    ssh -q root@${compute_node_hostname} "ovs-ofctl dump-flows br-int"
    ${flows_added}=    Get Lines Containing String    ${flows_added}    cookie=
    Log    ${flows_added}
    ## Validate flow rules arent in the flows table
    Should Not Contain    ${flows_added}    nw_src=2.2.2.0/24,nw_dst=2.2.2.0/24

*** Keywords ***
Suite Setup
    ${auth} =    Create List    ${USER}    ${PASSWD}
    ${HEADERS}    Create Dictionary    Content-Type=application/json
    Create Session    ${SERVER_IP}    http://${SERVER_IP}:${SERVER_PORT}    auth=${AUTH}    headers=${HEADERS}
    Read InputFile
    ${vsg_service_id}=    Get ID    ${CH_CORE_SERVICES}    name    vsg
    Set Suite Variable    ${vsg_service_id}
    ${vsg_network_template_id}=    Get ID    ${CH_CORE_NETWORK_TEMPLATES}    name    vsg
    Set Suite Variable    ${vsg_network_template_id}
    ${mgmt_network_id}=    Get ID    ${CH_CORE_NETWORKS}    name    management
    Set Suite Variable    ${mgmt_network_id}
    ${vsg_slice_id}=    Get ID    ${CH_CORE_SLICES}    name    mysite_vsg
    Set Suite Variable    ${vsg_slice_id}
    ${volt_service_id}=    Get ID    ${CH_CORE_SERVICES}    name    volt
    Set Suite Variable    ${volt_service_id}
    ${image_id}=    Get ID    ${CH_CORE_IMAGES}    name    trusty-server-multi-nic
    Set Suite Variable    ${image_id}
    ##Get compute node information
    ${compute_node_hostname}=    Run Keyword If    '${ciab_local}' == 'False'    Execute Command on CIAB Server in Specific VM    ${SERVER_IP}    ${head_node}    cord prov list | grep node | awk '{print $2}'    ELSE    Execute Command Locally    cord prov list | grep node | awk '{print $2}'
    ${compute_node_ip}=    Run Keyword If    '${ciab_local}' == 'False'        Execute Command on CIAB Server in Specific VM    ${SERVER_IP}    ${head_node}    cord prov list | grep node | awk '{print $4}'    ELSE    Execute Command Locally    cord prov list | grep node | awk '{print $4}'
    Set Suite Variable    ${compute_node_hostname}
    Set Suite Variable    ${compute_node_ip}
    Get List of Instances

Suite Teardown
    Delete All Sessions
    Close All Connections

Read InputFile
    ${coreServiceList} =    utils.jsonToList    ${CORE_SERVICE_PATHFILE}    ServiceInfo
    Set Suite Variable    ${cservlist}    ${coreServiceList}
    ${coreNetworkList} =    utils.jsonToList    ${CORE_NETWORK_PATHFILE}    NetworkInfo
    Set Suite Variable    ${cnlist}    ${coreNetworkList}
    ${coreSliceList} =    utils.jsonToList    ${CORE_SLICE_PATHFILE}    SliceInfo
    Set Suite Variable    ${cslist}    ${coreSliceList}
    ${coreNetworkSliceList} =    utils.jsonToList    ${CORE_NETWORK_SLICE_PATHFILE}    NetworkSliceInfo
    Set Suite Variable    ${cnslist}    ${coreNetworkSliceList}
    ${coreInstanceList} =    utils.jsonToList    ${CORE_INSTANCE_PATHFILE}    InstanceInfo
    Set Suite Variable    ${cilist}    ${coreInstanceList}
    ${cordSubscriberList} =    utils.jsonToList    ${CORD_SUBSCRIBER_PATHFILE}    CordSubscriberInfo
    Set Suite Variable    ${csubList}    ${cordSubscriberList}
    ${voltTenantList} =    utils.jsonToList    ${VOLT_TENANT_PATHFILE}    VoltTenantInfo
    Set Suite Variable    ${vtList}    ${voltTenantList}

CORD Get
    [Documentation]    Make a GET call to the CORD controller
    [Arguments]    ${session}    ${service}
    ${resp}=    Get Request    ${session}    ${service}
    Log    ${resp.content}
    [Return]    ${resp}

CORD Post
    [Documentation]    Make a POST call to the CORD controller
    [Arguments]    ${session}    ${service}    ${data}
    ${data}=    Evaluate    json.dumps(${data})    json
    ${resp}=    Post Request    ${session}    uri=${service}    data=${data}
    Log    ${resp.content}
    [Return]    ${resp}

CORD Delete
    [Documentation]    Make a DELETE call to the CORD controller
    [Arguments]    ${session}    ${service}    ${id}
    ${resp}=    Delete Request    ${session}    uri=${service}/${id}
    Log    ${resp.content}
    [Return]    ${resp}

Validate Default CIAB Service Networks and Ports via XOS
    [Documentation]    Using XOS API, this validates the default VTN Service Networks + Ports for a CIAB Environment
    @{expected_network_names}=    Create List    public    management    exampleservice_network    mysite_vsg-access
    Run Keyword If    '${physical_pod}' == 'True'    Remove Values From List    ${expected_network_names}    exampleservice_network
    @{names}=    Create List
    @{network_names}=    Create List
    ${resp}=    CORD GET    ${SERVER_IP}   ${CH_CORE_NETWORKS}
    Should Be Equal As Strings    ${resp.status_code}    200
    ${jsondata}=    To Json    ${resp.content}
    Log    ${jsondata}
    ${length}=    Get Length    ${jsondata['items']}
    Should Be Equal As Integers    ${length}    ${expected_num_networks}
    : FOR    ${INDEX}    IN RANGE    0    ${length}
    \    ${item}=    Get From List    ${jsondata['items']}    ${INDEX}
    \    ${name}=    Get From Dictionary    ${item}    name
    \    Append To List    ${names}    ${name}
    : FOR    ${value}    IN    @{expected_network_names}
    \    List Should Contain Value    ${names}    ${value}
    ${resp}=    CORD GET    ${SERVER_IP}    ${CH_CORE_PORTS}
    Should Be Equal As Strings    ${resp.status_code}    200
    ${jsondata}=    To Json    ${resp.content}
    ${length}=    Get Length    ${jsondata['items']}
    Should Be Equal As Integers    ${length}    ${expected_num_ports}

Validate Default CIAB Service Networks via ONOSCORD
    [Documentation]    Validates the default VTN Service Network via ONOSCORD for a CIAB Environment
    [Arguments]    ${jsondata}
    @{network_ids}=    Create List
    @{expected_types}=    Create List    PUBLIC    PRIVATE    MANAGEMENT_LOCAL    VSG
    @{expected_names}=    Create List    public    exampleservice_network    management    mysite_vsg-access
    Run Keyword If    '${physical_pod}' == 'True'    Remove From List    ${expected_types}    VSG
    Run Keyword If    '${physical_pod}' == 'True'    Remove From List    ${expected_names}    exampleservice_network
    @{types}=    Create List
    @{names}=    Create List
    ${jsondata}=    To Json    ${jsondata}
    ${length}=    Get Length    ${jsondata['ServiceNetworks']}
    Should Be Equal As Integers    ${length}    4
    : FOR    ${INDEX}    IN RANGE    0    ${length}
    \    ${item}=    Get From List    ${jsondata['ServiceNetworks']}    ${INDEX}
    \    ${network_id}=    Get From Dictionary    ${item}    id
    \    ${type}=    Get From Dictionary    ${item}    type
    \    ${name}=    Get From Dictionary    ${item}    name
    \    Append To List    ${network_ids}    ${network_id}
    \    Append To List    ${types}    ${type}
    \    Append To List    ${names}    ${name}
    \    Run Keyword If    "${name}" == "management"    Set Suite Variable    ${management_network_id}    ${network_id}
    \    Run Keyword If    "${name}" == "public"    Set Suite Variable    ${public_network_id}    ${network_id}
    : FOR    ${value}    IN    @{expected_types}
    \    List Should Contain Value    ${types}    ${value}
    : FOR    ${value}    IN    @{expected_names}
    \    List Should Contain Value    ${names}    ${value}
    Set Suite Variable    ${network_ids}

Validate Default CIAB Service Ports via ONOSCORD
    [Documentation]    Validates the default VTN Service Ports via ONOSCORD for a CIAB Environment
    [Arguments]    ${jsondata}
    ${net_ids}=    Create List
    ${jsondata}=    To Json    ${jsondata}
    ${length}=    Get Length    ${jsondata['ServicePorts']}
    Should Be Equal As Integers    ${length}    5
    : FOR    ${INDEX}    IN RANGE    0    ${length}
    \    ${item}=    Get From List    ${jsondata['ServicePorts']}    ${INDEX}
    \    ${net_id}=    Get From Dictionary    ${item}    network_id
    \    Append To List    ${net_ids}    ${net_id}
    : FOR    ${value}    IN    @{net_ids}
    \    List Should Contain Value    ${network_ids}    ${value}
    ${management_len}=    Count Values in List    ${net_ids}    ${management_network_id}
    Should Be Equal As Integers    ${management_len}    2

Get ID
    [Documentation]    Retreives the id of any specific component
    [Arguments]    ${endpoint}    ${item}    ${match}
    ${resp}=    CORD GET    ${SERVER_IP}   ${endpoint}
    Should Be Equal As Strings    ${resp.status_code}    200
    ${jsondata}=    To Json    ${resp.content}
    Log    ${jsondata}
    ${length}=    Get Length    ${jsondata['items']}
    : FOR    ${INDEX}    IN RANGE    0    ${length}
    \    ${value}=    Get From List    ${jsondata['items']}    ${INDEX}
    \    ${name}=    Get From Dictionary    ${value}    ${item}
    \    ${id}=    Get From Dictionary    ${value}    id
    \    Run Keyword If    '${name}' == '${match}'    Exit For Loop
    [Return]    ${id}

Validate Flow Count
    [Documentation]    Gets the count of the flows pushed to an ovs switch and validates that against expected count
    [Arguments]    ${count}
    ${ovs_flow_count}=    Run Keyword If    '${ciab_local}' == 'False'        Execute Command on Compute Node in CIAB    ${SERVER_IP}    ${head_node}    ${compute_node_hostname}    ovs-ofctl dump-flows br-int | wc -l    ELSE    Execute Command Locally    ssh -q root@${compute_node_hostname} "ovs-ofctl dump-flows br-int | wc -l"
    ${ovs_flow_count}=    Get Line    ${ovs_flow_count}    0
    Should Be Equal As Integers    ${ovs_flow_count}    ${count}

Get Subscriber Root IDs in Use
    [Documentation]    Retrieves information for current subscribers and "blacklists" their subscriber root ids
    @{sr_id_blacklist}=    Create List
    ${resp}=    CORD GET    ${SERVER_IP}    ${VOLT_SUBSCRIBER}
    ${jsondata}=    To Json    ${resp.content}
    ${length}=    Get Length    ${jsondata['items']}
    : FOR    ${INDEX}    IN RANGE    0    ${length}
    \    ${item}=    Get From List    ${jsondata['items']}    ${INDEX}
    \    ${id}=    Get From Dictionary    ${item}    service_specific_id
    \    Append To List    ${sr_id_blacklist}    ${id}
   [Return]    @{sr_id_blacklist}

Get Tags in Use
    [Documentation]    Retrieves information for current active volt tenants and "blacklists" their s/c tags
    @{tag_blacklist}=    Create List
    ${resp}=    CORD GET    ${SERVER_IP}    ${VOLT_TENANT}
    ${jsondata}=    To Json    ${resp.content}
    ${length}=    Get Length    ${jsondata['items']}
    : FOR    ${INDEX}    IN RANGE    0    ${length}
    \    ${item}=    Get From List    ${jsondata['items']}    ${INDEX}
    \    ${s_tag}=    Get From Dictionary    ${item}    s_tag
    \    ${c_tag}=    Get From Dictionary    ${item}    c_tag
    \    Append To List    ${tag_blacklist}    ${s_tag}
    \    Append To List    ${tag_blacklist}    ${c_tag}
   [Return]    @{tag_blacklist}

Get Openstack Info
    [Documentation]    Executes a command in the headnode vm in a CIAB environment where openstack is running
    [Arguments]    ${cmd}
    ${output}=    Run Keyword If    '${ciab_local}' == 'False'    Execute Command on CIAB Server in Specific VM    ${SERVER_IP}    ${head_node}    source /opt/cord_profile/admin-openrc.sh; ${cmd}    strip_line=False    ELSE    Execute Command Locally    . /opt/cord_profile/admin-openrc.sh; ${cmd}
    Log    ${output}
    [Return]    ${output}

Validate Openstack Network
    [Documentation]    Validates that a particular network/subnet exists
    [Arguments]    ${network_name}    ${subnet}    ${destroyed}=False
    ${netlist}=    Get Openstack Info    neutron net-list
    Log    ${netlist}
    ${NET_DICT}=    openstackUtils.Get Neutron Lists    ${netlist}
    Log    ${NET_DICT}
    ${test-net}=    Get From Dictionary    ${NET_DICT}    ${network_name}
    Should Contain    ${test-net}    ${subnet}


Validate Openstack Nova Instance
    [Documentation]    Validates that a particular nova instance/tenant exists
    [Arguments]    ${instance_name}    ${network}    ${destroyed}=False
    ${novalist}=    Get Openstack Info    nova list --all-tenants
    Log    ${novalist}
    Run Keyword If    '${destroyed}' == 'True'    Should Not Contain    ${novalist}    ${instance_name}
    ${INSTANCE_STATUS}=    openstackUtils.Get Instance Status    ${novalist}    ${instance_name}
    Run Keyword If    '${destroyed}' == 'False'    Should Contain    ${INSTANCE_STATUS}    ACTIVE
    ${NOVA_DICT}=    openstackUtils.Get Nova Lists    ${novalist}    ${instance_name}
    Run Keyword If    '${destroyed}' == 'False'    Should Contain    ${NOVA_DICT}    ${network}

Get List of Instances
    ${instances}=    Create List
    Set Suite Variable    ${instances}
    ${resp}=    Cord GET    ${SERVER_IP}    ${CH_CORE_INSTANCES}
    Should Be Equal As Strings    ${resp.status_code}    200
    ${jsondata}=    To Json    ${resp.content}
    Log    ${jsondata}
    ${instance_length}=    Get Length    ${jsondata['items']}
    : FOR    ${INDEX}    IN RANGE    0    ${instance_length}
    \    ${item}=    Get From List    ${jsondata['items']}    ${INDEX}
    \    ${name}=    Get From Dictionary    ${item}    instance_name
    \    Append To List    ${instances}    ${name}
    Log    ${instances}
    Set Suite Variable    ${instance_length}

Get New Instance
    ${new_instance}=    Set Variable    null
    ${resp}=    Cord GET    ${SERVER_IP}    ${CH_CORE_INSTANCES}
    Should Be Equal As Strings    ${resp.status_code}    200
    ${jsondata}=    To Json    ${resp.content}
    Log    ${jsondata}
    ${length}=    Get Length    ${jsondata['items']}
    : FOR    ${INDEX}    IN RANGE    0    ${length}
    \    ${item}=    Get From List    ${jsondata['items']}    ${INDEX}
    \    ${name}=    Get From Dictionary    ${item}    instance_name
    \    ${passed}=    Run Keyword And Return Status    List Should Contain Value    ${instances}    ${name}
    \    ${new_instance}=    Set Variable If    '${passed}' == 'False'    ${name}    ${new_instance}
    Log    ${new_instance}
    Append To List    ${instances}    ${new_instance}
    [Return]    ${new_instance}
