Complete teardown implementation.

Add demo.sh to support hands on demo

Change-Id: Idf235957bd992e6d7482c8241f6ba8b8944c2826
Signed-off-by: jf9860 <jf9860@att.com>
diff --git a/robot/resources/heatbridge.robot b/robot/resources/heatbridge.robot
index eb6a9ed..972c59d 100644
--- a/robot/resources/heatbridge.robot
+++ b/robot/resources/heatbridge.robot
@@ -8,15 +8,22 @@
 Resource    openstack/keystone_interface.robot
 Resource    openstack/heat_interface.robot
 Resource    openstack/nova_interface.robot
+Resource    openstack/neutron_interface.robot
 Resource    aai/aai_interface.robot
 
 *** Variables ***
-${VERSIONED_INDEX_PATH}     /aai/v8
 ${MULTIPART_PATH}  /bulkadd
 ${NAMED_QUERY_PATH}  /aai/search/named-query
 ${NAMED_QUERY_TEMPLATE}    robot/assets/templates/aai/named_query.template    
 ${REVERSE_HEATBRIDGE}
 
+${BASE_URI}   /cloud-infrastructure/cloud-regions/cloud-region/\${cloud}/\${region}
+${IMAGE_URI}   ${BASE_URI}/images/image/\${image_id}
+${FLAVOR_URI}   ${BASE_URI}/flavors/flavor/\${flavor}
+${VSERVER_URI}   ${BASE_URI}/tenants/tenant/\${tenant}/vservers/vserver/\${vserver_id}
+${L_INTERFACE_URI}   ${VSERVER_URI}/l-interfaces/l-interface/\${linterface_id}
+
+  
 
 *** Keywords ***
 Execute Heatbridge
@@ -34,11 +41,13 @@
     Init Bridge    ${openstack_identity_url}    ${GLOBAL_VM_PROPERTIES['openstack_username']}    ${GLOBAL_VM_PROPERTIES['openstack_password']}    ${tenant_id}    ${GLOBAL_OPENSTACK_SERVICE_REGION}    ${GLOBAL_AAI_CLOUD_OWNER}    
     ${request}=    Bridge Data    ${stack_id}
     Log    ${request}
-    ${resp}=    Run A&AI Put Request    ${VERSIONED_INDEX_PATH}${MULTIPART_PATH}    ${request}
+    ${resp}=    Run A&AI Put Request    ${VERSIONED_INDEX_PATH}${MULTIPART_PATH}    ${request} 
     Should Be Equal As Strings    ${resp.status_code}     200
-    Generate Reverse Heatbridge   ${request}
+    ${reverse_heatbridge}=   Generate Reverse Heatbridge From Stack Info   ${stack_info}
+    Set Test Variable   ${REVERSE_HEATBRIDGE}   ${reverse_heatbridge}
     Run Validation Query    ${stack_info}    ${service}
 
+
 Run Validation Query
     [Documentation]    Run A&AI query to validate the bulk add 
     [Arguments]    ${stack_info}    ${service}
@@ -56,93 +65,61 @@
     ${resp}=    Run A&AI Post Request    ${NAMED_QUERY_PATH}    ${request}
     Should Be Equal As Strings    ${resp.status_code}    200   
     
-Generate Reverse Heatbridge
-    [Documentation]    Turn all of the HB puts into deletes... 
-    [Arguments]    ${heatbridge_string}
-    ${heatbridge}=  To Json    ${heatbridge_string}
-    ${list}=    Get From Dictionary   ${heatbridge}   transactions
-    ${transactions}=    Create List
-    ${dupeDict}   Create Dictionary    
-    :for   ${t}   in   @{list}
-    \   ${entry}=    Get Deletes From Heatbridge   ${t}   ${dupeDict}
-    \   Run Keyword If   len(${entry}) > 0    Append To List    ${transactions}   ${entry}    
-    ${reverse}=    Create Dictionary    transactions=${transactions}
-    Set Test Variable   ${REVERSE_HEATBRIDGE}   ${reverse}
-    [Return]      ${REVERSE_HEATBRIDGE} 
-
-Get Deletes From Heatbridge
-    [Documentation]    Turn all of the HB puts into deletes... Should be one 'put' with one 
-    ...   Not sure why this is structured this way, dictionary with operation as the key
-    ...   So only one occurrance of an each operation, but with list of urls/bodies
-    ...   So multiple gets, puts, etc. but in which order??? 
-    [Arguments]    ${putDict}   ${dupeDict}
-    ${deleteDict}=    Create Dictionary
-    ${keys}=   Get Dictionary Keys    ${putDict} 
-    # We do not expect anyhting other than 'put'
-    :for   ${key}   in    @{keys}
-    \    Should be Equal   ${key}   put  
-    \    ${list}=   Get From Dictionary   ${putDict}   put
-    \    ${deleteList}=   Get List Of Deletes   ${list}   ${dupeDict}
-    \    Run Keyword If   len(${deleteList}) > 0   Set To Dictionary    ${deleteDict}   delete=${deleteList}
-    [Return]    ${deleteDict}           
-
-Get List Of Deletes
-    [Documentation]    Turn the list of puts into a list of deletes... 
-    ...   There is only on hash per 'put' but it looks like there can be more...
-    [Arguments]    ${putList}    ${dupeDict}
-    ${deleteList}=   Create List
-    :for   ${put}   in    @{putList}     
-    \   ${uri}=   Get From Dictionary   ${put}   uri
-    \   Continue For Loop If    '${uri}' in ${dupeDict}
-    \   ${delete}=    Create Dictionary   uri=${uri}
-    \   Append To List     ${deleteList}   ${delete}
-    \   Set To Dictionary   ${dupeDict}   ${uri}=${uri} 
-    [Return]   ${deleteList}  
-         
-Execute Bulk Transaction    
-    [Arguments]    ${transaction}
-    :for   ${put}    in    ${transaction}
-    \    Execute Put List    ${put}
-
-Execute Put List 
-    [Arguments]    ${put}
-    Log    ${put}
-    ${list}=   Get From Dictionary    ${put}    put 
-    :for   ${request}    in    @{list}
-    \    Execute Single Put    ${request}
-        
-Execute Single Put 
-    [Arguments]    ${request}
-    ${data}=    Get From Dictionary    ${request}    body
-    ${path}=    Get From Dictionary    ${request}    uri
-    ${resp}=    Run A&AI Put Request    ${VERSIONED_INDEX_PATH}${path}    ${data}
-    Should Be Equal As Strings        ${resp.status_code} 	201
     
-
 Execute Reverse Heatbridge
-    [Documentation]   VID has already torn down the stack, reverse HB 
-    [Arguments]    ${reverse_heatbridge}
-    ${resp}=    Run A&AI Put Request    ${VERSIONED_INDEX_PATH}${MULTIPART_PATH}    ${reverse_heatbridge}
-    Should Be Equal As Strings    ${resp.status_code}     200
-    
+    [Documentation]   VID has already torn down the stack, reverse HB
+    Return From Keyword If   len(${REVERSE_HEATBRIDGE}) == 0
+    :for   ${uri}    in   @{REVERSE_HEATBRIDGE}
+    \    Run Keyword And Ignore Error    Delete A&AI Entity   ${uri}
 
-Execute Heatbridge Teardown
-    [Documentation]   Run teardown against the stack to generate a bulkadd message that removes it
-    [Arguments]    ${stack_name}
+Generate Reverse Heatbridge From Stack Name  
+    [Arguments]   ${stack_name}
     Run Openstack Auth Request    auth
-    ${stack_info}=    Wait for Stack to Be Deployed    auth    ${stack_name}
+    ${stack_info}=    Wait for Stack to Be Deployed    auth    ${stack_name}   timeout=10s
+    ${reverse_heatbridge}=    Generate Reverse Heatbridge From Stack Info   ${stack_info}
+    [Return]    ${reverse_heatbridge}
+    
+Generate Reverse Heatbridge From Stack Info  
+    [Arguments]   ${stack_info}
+    ${reverse_heatbridge}=    Create List
+    ${stack_name}=    Get From Dictionary    ${stack_info}    name
     ${stack_id}=    Get From Dictionary    ${stack_info}    id
     ${tenant_id}=   Get From Dictionary    ${stack_info}    OS::project_id
+    ${keys}=    Create Dictionary   region=${GLOBAL_OPENSTACK_SERVICE_REGION}   cloud=${GLOBAL_AAI_CLOUD_OWNER}   tenant=${tenant_id}
     ${stack_resources}=    Get Stack Resources    auth    ${stack_name}    ${stack_id}
     ${resource_list}=    Get From Dictionary    ${stack_resources}    resources
-    Get Length    ${resource_list}
-    Log     ${resource_list}
     :FOR   ${resource}    in    @{resource_list}
     \    Log     ${resource}
-    \    Run Keyword If    '${resource['resource_type']}' == 'OS::Nova::Server'    Execute Server Teardown    auth    ${resource['physical_resource_id']}
-
-Execute Server Teardown
+    \    Run Keyword If    '${resource['resource_type']}' == 'OS::Neutron::Port'    Generate Linterface Uri    auth    ${resource['physical_resource_id']}   ${reverse_heatbridge}   ${keys}
+    :FOR   ${resource}    in    @{resource_list}
+    \    Log     ${resource}
+    \    Run Keyword If    '${resource['resource_type']}' == 'OS::Nova::Server'    Generate Vserver Uri    auth    ${resource['physical_resource_id']}  ${reverse_heatbridge}   ${keys}   ${resource_list}
+    [Return]    ${reverse_heatbridge}
+    
+Generate Vserver Uri
     [Documentation]   Run teardown against the server to generate a message that removes it
-    [Arguments]    ${alias}    ${server_id}
-    ${server}=    Get Openstack Server By Id   ${alias}	${server_id}
-    Log     ${server}
\ No newline at end of file
+    [Arguments]    ${alias}    ${port_id}   ${reverse_heatbridge}   ${keys}   ${resource_list}
+    ${resp}=    Get Openstack Server By Id   ${alias}	  ${port_id}
+    Return From Keyword If   '${resp.status_code}' != '200'
+    ${info}=   Set Variable   ${resp.json()} 
+    Set To Dictionary   ${keys}   vserver_id=${info['server']['id']}    
+    Set To Dictionary   ${keys}   flavor=${info['server']['flavor']['id']}    
+    Set To Dictionary   ${keys}   image_id=${info['server']['image']['id']}    
+    ${uri}=   Template String    ${VSERVER_URI}    ${keys}
+    Append To List  ${reverse_heatbridge}   ${uri}
+    ${uri}=   Template String    ${FLAVOR_URI}    ${keys}
+    Append To List  ${reverse_heatbridge}   ${uri}
+    ${uri}=   Template String    ${IMAGE_URI}    ${keys}
+    Append To List  ${reverse_heatbridge}   ${uri}
+
+Generate Linterface Uri
+    [Documentation]   Run teardown against the server to generate a message that removes it
+    [Arguments]    ${alias}    ${server_id}   ${reverse_heatbridge}   ${keys}
+    ${resp}=    Get Openstack Port By Id   ${alias}	${server_id}
+    Return From Keyword If   '${resp.status_code}' != '200'
+    ${info}=   Set Variable   ${resp.json()} 
+    Set To Dictionary   ${keys}   vserver_id=${info['port']['device_id']}
+    Set To Dictionary   ${keys}   linterface_id=${info['port']['name']}
+    ${uri}=   Template String    ${L_INTERFACE_URI}    ${keys}
+    Append To List  ${reverse_heatbridge}   ${uri}
+