aboutsummaryrefslogtreecommitdiffstats
path: root/kubernetes/README.md
blob: dc49e5445bf37251651313b59962819988771f5f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
## **Quick Start Guide - ONAP on Kubernetes**


This is a quick start guide to help you get started on ONAP installation. Creating an ONAP deployment instance requires creating base configuration on the host node and then deploying the runtime containers.

Pre-requisites:

-  Your Kubernetes environment must be available. For more information see, [ONAP on Kubernetes](https://wiki.onap.org/display/DW/ONAP+on+Kubernetes).
-  Deployment artifacts are customized for your location.

Step 1

Review and optionally change configuration parameters:

Setup the [/oom/kubernetes/config/onap-parameters.yaml](https://gerrit.onap.org/r/gitweb?p=oom.git;a=blob;f=kubernetes/config/onap-parameters.yaml;h=7ddaf4d4c3dccf2fad515265f0da9c31ec0e64b1;hb=refs/heads/master) file with key-value pairs specific to your OpenStack environment.

OR

There is a [sample](https://gerrit.onap.org/r/gitweb?p=oom.git;a=blob;f=kubernetes/config/onap-parameters-sample.yaml;h=3a74beddbbf7f9f9ec8e5a6abaecb7cb238bd519;hb=refs/heads/master) that may help you out or even be usable directly if you don't intend to actually use OpenStack resources.


Step 2

In-order to be able to support multiple ONAP instances within a single kubernetes environment, a configuration set is required. To do this, execute the [createConfig.sh](https://gerrit.onap.org/r/gitweb?p=oom.git;a=blob;f=kubernetes/config/createConfig.sh;h=f226ccae47ca6de15c1da49be4b8b6de974895ed;hb=refs/heads/master) script:

> oom/kubernetes/config/createConfig.sh -n onap

Where:
'onap' refers to the name of the instance. This serves as the Namespace prefix for each deployed ONAP component (for example, onap-mso).

Step 3

The bash script [createAll.bash](https://gerrit.onap.org/r/gitweb?p=oom.git;a=blob;f=kubernetes/oneclick/createAll.bash;h=5e5f2dc76ea7739452e757282e750638b4e3e1de;hb=refs/heads/master) is used to create an ONAP deployment with kubernetes. It has two primary functions:

-  Creating the namespaces used to encapsulate the ONAP components, and
-  Creating the services, pods and containers within each of these namespaces that provide the core functionality of ONAP.

Before you execute the createAll.bash. script, pod config-init ([pod-config-init.yaml](https://gerrit.onap.org/r/gitweb?p=oom.git;a=blob;f=kubernetes/config/pod-config-init.yaml;h=b1285ce21d61815c082f6d6aa3c43d00561811c7;hb=refs/heads/master)) may need editing to match your environment and deployment into the default namespace.

To deploy the containers and create your ONAP system, execute the following command:

> oom/kubernetes/oneclick/createAll.bash -n onap

#### **Additional information on usage of createAll.bash**

Namespaces provide isolation between ONAP components as ONAP release 1.0 contains duplicate application (for example, mariadb) and port usage.

As such createAll.bash requires the user to enter a namespace prefix string that can be used to separate multiple deployments of onap. The result will be set of 10 namespaces (for example, onap-sdc, onap-aai, onap-mso, onap-message-router, onap-robot, onap-vid, onap-sdnc, onap-portal, onap-policy, onap-appc) being created within the kubernetes environment.


#### **Deploying multiple ONAP instances within the same Kubernetes cluster**

To deploy multiple ONAP instances, you must specify the number of Instances you would like to create in a Kubernetes cluster using createAllbash.

This is currently required due to the use of NodePort ranges. NodePorts allow external IP:Port access to containers that are running inside a Kubernetes cluster.

To create multiple instances of an ONAP deployment in the cluster, use the following commands:

> oom/kubernetes/config/createConfig.sh -n onap

> oom/kubernetes/oneclick/createAll.bash -n onap -i 2

Where:

-  'onap' refers to the name of the instance.

-  �i 2� refers to the number of instances of an ONAP deployment in the cluster.

#### **To delete a deployed instance**

To delete a deployed instance, use the following command:

> oom/kubernetes/oneclick/deleteAll.bash -n onap

**Note:** Deleting the runtime containers does not remove the configuration created in step 2.

For more information on OOM project documentation, refer to:

 -  [Quick Start Guide on Wiki](https://wiki.onap.org/display/DW/ONAP+Operations+Manager+Project#ONAPOperationsManagerProject-QuickStartGuide)
 -  [Quick Start Guide on readthedocs](http://onap.readthedocs.io/en/latest/submodules/oom.git/docs/OOM%20Project%20Description/oom_project_description.html#quick-start-guide)
/ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
*** Settings ***
Documentation   This test template encapsulates the VNF Orchestration use case.

Resource        ../vid/create_service_instance.robot
Resource        ../vid/vid_interface.robot
Resource        ../aai/service_instance.robot
Resource        ../vid/create_vid_vnf.robot
Resource        ../vid/teardown_vid.robot
Resource        ../sdnc_interface.robot
Resource        model_test_template.robot

Resource        ../aai/create_zone.robot
Resource        ../aai/create_customer.robot
Resource        ../aai/create_complex.robot
Resource        ../aai/create_tenant.robot
Resource        ../aai/create_service.robot
Resource        ../openstack/neutron_interface.robot
Resource        ../heatbridge.robot


Library         ONAPLibrary.Openstack
Library       SeleniumLibrary
Library         Collections
Library         ONAPLibrary.Utilities
Library         ONAPLibrary.JSON
Library         ONAPLibrary.ServiceMapping    WITH NAME    ServiceMapping


*** Keywords ***
Orchestrate VNF Template
    [Documentation]   Use ONAP to Orchestrate a service.
    [Arguments]    ${customer_name}    ${service}    ${product_family}    ${delete_flag}=DELETE
    ${uuid}=    Generate UUID4
    ${catalog_service_id}=    Set Variable    ${None}    # default to empty
    ${catalog_resource_ids}=    Set Variable    ${None}    # default to empty
    ${tenant_id}    ${tenant_name}=    Setup Orchestrate VNF    ${GLOBAL_AAI_CLOUD_OWNER}    SharedNode    OwnerType    v1    CloudZone
    ${vf_module_name_list}   ${generic_vnfs}    ${server_id}    ${service_instance_id}    ${catalog_resource_ids}   ${catalog_service_id}    ${uris_to_delete}=    Orchestrate VNF   ${customer_name}_${uuid}    ${service}    ${product_family}    ${tenant_id}    ${tenant_name}
    Run Keyword If   '${delete_flag}' == 'DELETE'   Delete VNF    ${tenant_name}    ${server_id}    ${customer_name}_${uuid}    ${service_instance_id}    ${vf_module_name_list}    ${uris_to_delete}
    [Teardown]         Teardown VNF    ${customer_name}_${uuid}    ${catalog_service_id}    ${catalog_resource_ids}

Orchestrate VNF
    [Documentation]   Use ONAP to Orchestrate a service.
    [Arguments]    ${customer_name}    ${service}    ${product_family}    ${tenant_id}    ${tenant_name}    ${project_name}=Project-Demonstration   ${owning_entity}=OE-Demonstration
    ${lcp_region}=   Get Openstack Region
    ${uuid}=    Generate UUID4
    ${service_name}=    Catenate    Service_Ete_Name${uuid}
    ${service_type}=    Set Variable    ${service}
    ${service_model_type}     ${vnf_type}    ${vf_modules}   ${catalog_resources}    ${catalog_resource_ids}   ${catalog_service_id}=    Model Distribution For Directory    ${service}
    ${server_id}=     Run Keyword If   '${service}' == 'vVG'    Create VVG Server    ${uuid}
    Create Customer For VNF    ${customer_name}    ${customer_name}    INFRA    ${service_type}    ${GLOBAL_AAI_CLOUD_OWNER}    ${tenant_id}
    Setup Browser
    Run Keyword If   "${API_TYPE}"=="GRA_API"    Login To VID GUI    gr_api
    ...   ELSE   Login To VID GUI
    #${service_instance_id}=   Wait Until Keyword Succeeds    300s   5s    Create VID Service Instance    ${customer_name}    ${service_model_type}    ${service}     ${service_name}   ${project_name}   ${owning_entity}
    ${service_instance_id}=   Create VID Service Instance    ${customer_name}    ${service_model_type}    ${service}     ${service_name}   ${project_name}   ${owning_entity}
    Wait Until Keyword Succeeds   60s   20s      Validate Service Instance    ${service_instance_id}    ${service}      ${customer_name}
    ServiceMapping.Set Directory    default    ${GLOBAL_SERVICE_MAPPING_DIRECTORY}
    ${vnflist}=    ServiceMapping.Get Service Vnf Mapping    default    ${service}
    ${generic_vnfs}=    Create Dictionary
    ${vnf_name_index}=   Set Variable  0
    ${vf_module_name_list}=    Create List
    ${uuid}=    Evaluate    str("${uuid}")[:8]
    :FOR   ${vnf}   IN   @{vnflist}
    # APPC max is 50 characters
    \   ${vnf_name}=    Catenate    Ete_${vnf}_${uuid}_${vnf_name_index}
    \   ${vf_module_name}=    Catenate    Vfmodule_Ete_${vnf}_${uuid}_${vnf_name_index}
    \   ${vnf_name_index}=   Evaluate   ${vnf_name_index} + 1
    \   ${vnf_type}=   Get VNF Type   ${catalog_resources}   ${vnf}    ${service}
    \   ${vf_module}=    Get VF Module    ${catalog_resources}   ${vnf}    ${service}
    \   Create VID VNF    ${service_instance_id}    ${vnf_name}    ${product_family}    ${lcp_region}    ${tenant_name}    ${vnf_type}   ${customer_name}

    \   ${vf_module_type}   ${closedloop_vf_module}=   Run Keyword If   "${API_TYPE}"=="GRA_API"     Preload Gra    ${service_instance_id}   ${vnf_name}   ${vnf_type}   ${vf_module_name}    ${vf_module}    ${vnf}    ${uuid}  ${service}    ${server_id}
    \                                                  ...   ELSE   Preload Vnf    ${service_instance_id}   ${vnf_name}   ${vnf_type}   ${vf_module_name}    ${vf_module}    ${vnf}    ${uuid}  ${service}   ${server_id}

    \   ${vf_module_id}=   Create VID VNF module    ${service_instance_id}    ${vf_module_name}    ${lcp_region}    ${tenant_name}     ${vf_module_type}   ${customer_name}   ${vnf_name}
    \   ${generic_vnf}=   Validate Generic VNF    ${vnf_name}    ${vnf_type}    ${service_instance_id}
    \   Set To Dictionary    ${generic_vnfs}    ${vf_module_type}    ${generic_vnf}
    #    TODO: Need to look at a better way to default ipv4_oam_interface  search for Heatbridge
    \   ${uris_to_delete}=    Execute Heatbridge    ${vf_module_name}    ${vnf}  ${service}    ipv4_oam_interface
    \   Validate VF Module      ${vf_module_name}    ${vnf}
    \   Append To List   ${vf_module_name_list}    ${vf_module_name}
    [Return]     ${vf_module_name_list}   ${generic_vnfs}    ${server_id}    ${service_instance_id}    ${catalog_resource_ids}   ${catalog_service_id}    ${uris_to_delete}


Orchestrate Demo VNF
    [Documentation]   Use ONAP to Orchestrate a service from Demonstration Models.
    [Arguments]    ${customer_name}    ${service}    ${product_family}    ${tenant_id}    ${tenant_name}  ${project_name}=Project-Demonstration   ${owning_entity}=OE-Demonstration
    ${service_model_type}=   Set Variable If
    ...                      '${service}'=='vFWCL'     demoVFWCL
    ...                      '${service}'=='vFW'       demoVFW
    ...                      '${service}'=='vLB'       demoVLB
    ${lcp_region}=   Get Openstack Region
    ${uuid}=    Generate UUID4
    ${full_customer_name}=    Catenate    ${customer_name}_${uuid}
    ${list}=    Create List
    ${vf_module_name_list}=    Create List
    ${service_name}=    Catenate    Service_Ete_Name${uuid}
    ${service_type}=    Set Variable    ${service}
    ${vnf_json_resources}=   Get SDC Demo Vnf Catalog Resource      ${service_model_type}
    ${server_id}=     Run Keyword If   '${service}' == 'vVG'    Create VVG Server    ${uuid}
    Create Customer For VNF    ${full_customer_name}    ${full_customer_name}    INFRA    ${service_type}    ${GLOBAL_AAI_CLOUD_OWNER}    ${tenant_id}
    Setup Browser
    Login To VID GUI
    ${service_instance_id}=   Wait Until Keyword Succeeds    300s   5s    Create VID Service Instance    ${full_customer_name}    ${service_model_type}    ${service}     ${service_name}   ${project_name}   ${owning_entity}
    Wait Until Keyword Succeeds    120s    15s    Validate Service Instance    ${service_instance_id}    ${service}      ${full_customer_name}
    ServiceMapping.Set Directory    default    ${GLOBAL_SERVICE_MAPPING_DIRECTORY}
    ${vnflist}=    ServiceMapping.Get Service Vnf Mapping    default    ${service}
    ${generic_vnfs}=    Create Dictionary
    :FOR   ${vnf}   IN   @{vnflist}
    \   ${vnf_name}=    Catenate    Ete_${vnf}_${uuid}
    \   ${vf_module_name}=    Catenate    Vfmodule_Demo_${vnf}_${uuid}
    \   ${vnf_type}=    Set Variable  ${vnf_json_resources['${vnf}']['vnf_type']}
    \   ${vf_module}=   Set Variable  ${vnf_json_resources['${vnf}']['vf_module']}
    \   Create VID VNF    ${service_instance_id}    ${vnf_name}    ${product_family}    ${lcp_region}    ${tenant_name}    ${vnf_type}   ${full_customer_name}
    \   ${vf_module_entry}=   Create Dictionary    name=${vf_module}
    \   ${vf_modules}=   Create List    ${vf_module_entry}
    #   in Demo VNF flow old logic since we did not create the resource so @{vf_modules} is passed to Preload Vnf / Preload Gra
    \   ${vf_module_type}   ${closedloop_vf_module}=   Run Keyword If   "${API_TYPE}"=="GRA_API"     Preload Gra    ${service_instance_id}   ${vnf_name}   ${vnf_type}   ${vf_module_name}    ${vf_modules}    ${vnf}    ${uuid}  ${service}    ${server_id}
    \                                                  ...   ELSE   Preload Vnf    ${service_instance_id}   ${vnf_name}   ${vnf_type}   ${vf_module_name}    ${vf_modules}    ${vnf}    ${uuid}  ${service}   ${server_id}


    \   ${vf_module_id}=   Create VID VNF module    ${service_instance_id}    ${vf_module_name}    ${lcp_region}    ${tenant_name}     ${vf_module_type}   ${full_customer_name}   ${vnf_name}
    \   ${generic_vnf}=   Validate Generic VNF    ${vnf_name}    ${vnf_type}    ${service_instance_id}
    \   Set To Dictionary    ${generic_vnfs}    ${vf_module_type}    ${generic_vnf}
    #    TODO: Need to look at a better way to default ipv4_oam_interface  search for Heatbridge
    \   Execute Heatbridge    ${vf_module_name}    ${vnf}  ${service}    ipv4_oam_interface
    \   Validate VF Module      ${vf_module_name}    ${vnf}
    \   Append To List   ${vf_module_name_list}   ${vf_module_name}
    [Return]     ${vf_module_name}    ${service}    ${generic_vnfs}


Get VNF Type
    [Documentation]    To support services with multiple VNFs, we need to dig the vnf type out of the SDC catalog resources to select in the VID UI
    [Arguments]   ${resources}   ${vnf}    ${service}
    ${cr}=   Get Catalog Resource    ${resources}    ${vnf}    ${service}
    ${vnf_type}=   Get From Dictionary   ${cr}   name
    [Return]   ${vnf_type}

Get VF Module
    [Documentation]    To support services with multiple VNFs, we need to dig the vnf type out of the SDC catalog resources to select in the VID UI
    [Arguments]   ${resources}   ${vnf}    ${service}
    ${cr}=   Get Catalog Resource    ${resources}    ${vnf}    ${service}
    ${vf_module}=    Find Element In Array    ${cr['groups']}    type    org.openecomp.groups.VfModule
    [Return]  ${vf_module}

Get Catalog Resource
    [Documentation]    To support services with multiple VNFs, we need to dig the vnf type out of the SDC catalog resources to select in the VID UI
    [Arguments]   ${resources}   ${vnf}    ${service}

    ${base_name}=  Get Name Pattern   ${vnf}    ${service}
    ${keys}=    Get Dictionary Keys    ${resources}

    :FOR   ${key}   IN    @{keys}
    \    ${cr}=   Get From Dictionary    ${resources}    ${key}
    \    Return From Keyword If   '${base_name}' in '${cr['allArtifacts']['heat1']['artifactDisplayName']}'    ${cr}
    \    Run Keyword If    'heat2' in ${cr['allArtifacts']}    Return From Keyword If   '${base_name}' in '${cr['allArtifacts']['heat2']['artifactDisplayName']}'    ${cr}
    Fail    Unable to find catalog resource for ${vnf} ${base_name}

Get Name Pattern
    [Documentation]    To support services with multiple VNFs, we need to dig the vnf type out of the SDC catalog resources to select in the VID UI
    [Arguments]   ${vnf}    ${service}
    ServiceMapping.Set Directory    default    ${GLOBAL_SERVICE_MAPPING_DIRECTORY}
    ${list}=    ServiceMapping.Get Service Template Mapping    default    ${service}    ${vnf}
    :FOR    ${dict}   IN   @{list}
    \   ${base_name}=   Get From Dictionary    ${dict}    name_pattern
    \   Return From Keyword If   '${dict['isBase']}' == 'true'   ${base_name}
    Fail  Unable to locate base name pattern

Create Customer For VNF
    [Documentation]    VNF Orchestration Test setup....
    ...                Create Tenant if not exists, Create Customer, Create Service and related relationships
    [Arguments]    ${customer_name}    ${customer_id}    ${customer_type}    ${service_type}    ${cloud_owner}    ${tenant_id}
    ${cloud_region_id}=   Get Openstack Region
    Create Service If Not Exists    ${service_type}
    ${resp}=    Create Customer    ${customer_name}    ${customer_id}    ${customer_type}    ${service_type}   ${cloud_owner}  ${cloud_region_id}    ${tenant_id}
  Should Be Equal As Strings  ${resp}   201

Setup Orchestrate VNF
    [Documentation]    Called before each test case to ensure tenant and region data
    ...                required by the Orchstrate VNF exists in A&AI
    [Arguments]        ${cloud_owner}  ${cloud_type}    ${owner_defined_type}    ${cloud_region_version}    ${cloud_zone}
    ${tenant_id}    ${tenant_name}=    Initialize Tenant From Openstack
    Run Openstack Auth Request    auth
    ${regs}=    Get Openstack Regions    auth
    :FOR    ${region}    IN    @{regs}
    \    Inventory Tenant If Not Exists    ${cloud_owner}  ${region}  ${cloud_type}    ${owner_defined_type}    ${cloud_region_version}    ${cloud_zone}    ${tenant_id}    ${tenant_name}
    Inventory Zone If Not Exists
    Inventory Complex If Not Exists    ${GLOBAL_AAI_COMPLEX_NAME}   ${GLOBAL_AAI_PHYSICAL_LOCATION_ID}   ${GLOBAL_AAI_CLOUD_OWNER}   ${GLOBAL_INJECTED_REGION}   ${GLOBAL_AAI_CLOUD_OWNER_DEFINED_TYPE}
    Log   Orchestrate VNF setup complete
    [Return]    ${tenant_id}    ${tenant_name}

Initialize Tenant From Openstack
    [Documentation]    Initialize the tenant test variables
    Run Openstack Auth Request    auth
    ${tenants}=    Get Current Openstack Tenant     auth
    ${tenant_name}=    Evaluate    $tenants.get("name")
    ${tenant_id}=     Evaluate    $tenants.get("id")
    [Return]    ${tenant_id}    ${tenant_name}

Create VVG Server
    [Documentation]    For the VolumeGroup test case, create a server to attach the volume group to be orchestrated.
    [Arguments]    ${uuid}
    Run Openstack Auth Request    auth
    ${vvg_server_name}=    Catenate   vVG_${uuid}
    ${server}=   Add Server For Image Name  auth    ${vvg_server_name}   ${GLOBAL_INJECTED_VM_IMAGE_NAME}   ${GLOBAL_INJECTED_VM_FLAVOR}   ${GLOBAL_INJECTED_PUBLIC_NET_ID}
    ${server}=       Get From Dictionary   ${server}   server
    ${server_id}=    Get From Dictionary   ${server}   id
    Wait for Server to Be Active    auth    ${server_id}
    [Return]    ${server_id}

Delete VNF
    [Documentation]    Called at the end of a test case to tear down the VNF created by Orchestrate VNF
    [Arguments]    ${tenant_name}    ${server_id}    ${customer_name}    ${service_instance_id}    ${vf_module_name_list}    ${uris_to_delete}
    ${lcp_region}=   Get Openstack Region
    ${list}=    Create List
    # remove duplicates, sort vFW-> vPKG , revers to get vPKG > vFWSNK
    ${sorted_stack_names}=    Create List
    ${sorted_stack_names}=  Remove Duplicates   ${vf_module_name_list}
    Sort List   ${sorted_stack_names}
    Reverse List   ${sorted_stack_names}
    :FOR   ${stack}   IN   @{sorted_stack_names}
    \     ${keypair_name}=    Get Stack Keypairs   ${stack}
    \     Append To List   ${list}   ${keypair_name}
    Teardown VVG Server    ${server_id}
    Run Keyword and Ignore Error   Teardown VID   ${service_instance_id}   ${lcp_region}   ${tenant_name}   ${customer_name}    ${uris_to_delete}
    #
    :FOR   ${stack}   IN   @{sorted_stack_names}
    \    Run Keyword and Ignore Error    Teardown Stack    ${stack}
    \    Log    Stack Deleted ${stack}
    # only needed if stack deleted but not keypair
    :FOR   ${key_pair}   IN   @{list}
    \    Run Keyword and Ignore Error    Delete Stack Keypair  ${key_pair}
    \    Log    Key pair Deleted ${key_pair}
    Log    VNF Deleted

Teardown VNF
    [Documentation]    Called at the end of a test case to tear down the VNF created by Orchestrate VNF
    [Arguments]    ${customer_name}     ${catalog_service_id}    ${catalog_resource_ids}
    Teardown Models     ${catalog_service_id}    ${catalog_resource_ids}
    Clean A&AI Inventory    ${customer_name}
    Close All Browsers

Teardown VVG Server
    [Documentation]   Teardown the server created as a place to mount the Volume Group.
    [Arguments]    ${server_id}
    Return From Keyword if   '${server_id}' == ''
    Return From Keyword if   '${server_id}' == 'None'
    Delete Server   auth   ${server_id}
    Wait for Server To Be Deleted    auth    ${server_id}
    Log    Teardown VVG Server Completed

Get Stack Keypairs
    [Documentation]  Get keypairs from openstack
    [Arguments]   ${stack}
    Run Openstack Auth Request    auth
    # Openstack can be delayed in making stack available to API
    ${stack_info}=    Wait Until Keyword Succeeds    300s    15s   Get Stack Details    auth    ${stack}
    Log    ${stack_info}
    ${stack_id}=    Get From Dictionary    ${stack_info}    id
    ${key_pair_status}   ${keypair_name}=   Run Keyword And Ignore Error   Get From Dictionary    ${stack_info}    key_name
    [Return]   ${keypair_name}

Delete Stack Keypair
    [Documentation]  Delete keypairs from openstack
    [Arguments]   ${keypair_name}
    Run Openstack Auth Request    auth
    Run Keyword   Delete Openstack Keypair    auth    ${keypair_name}

Teardown Stack
    [Documentation]    OBSOLETE - Called at the end of a test case to tear down the Stack created by Orchestrate VNF
    [Arguments]   ${stack}
    Run Openstack Auth Request    auth
    ${stack_info}=    Get Stack Details    auth    ${stack}
    Log    ${stack_info}
    ${stack_id}=    Get From Dictionary    ${stack_info}    id
    ${key_pair_status}   ${keypair_name}=   Run Keyword And Ignore Error   Get From Dictionary    ${stack_info}    key_name
    Delete Openstack Stack      auth    ${stack}    ${stack_id}
    Log    Deleted ${stack} ${stack_id}
    Run Keyword If   '${key_pair_status}' == 'PASS'   Delete Openstack Keypair    auth    ${keypair_name}

Clean A&AI Inventory
    [Documentation]    Clean up Tenant in A&AI, Create Customer, Create Service and related relationships
    [Arguments]   ${customer_name}
    Delete Customer    ${customer_name}