summaryrefslogtreecommitdiffstats
path: root/adapters/mso-openstack-adapters/src/test
diff options
context:
space:
mode:
authorSteve Smokowski <ss835w@att.com>2019-03-25 12:09:39 +0000
committerGerrit Code Review <gerrit@onap.org>2019-03-25 12:09:39 +0000
commit8e1de081db6c6c87d05687125c0316877ae1bec3 (patch)
treecb4f28f79eaf2437e74e0b904dcebe22614bb6b3 /adapters/mso-openstack-adapters/src/test
parent0d97f87b6381ea06350933b375c4e821b5e10568 (diff)
parent563a3579e907daa3952e10e25071b676430fd09d (diff)
Merge "heatbridge implementation for openstack-adapter"
Diffstat (limited to 'adapters/mso-openstack-adapters/src/test')
-rw-r--r--adapters/mso-openstack-adapters/src/test/java/org/onap/so/heatbridge/HeatBridgeImplTest.java375
-rw-r--r--adapters/mso-openstack-adapters/src/test/resources/stack-resources.json441
2 files changed, 816 insertions, 0 deletions
diff --git a/adapters/mso-openstack-adapters/src/test/java/org/onap/so/heatbridge/HeatBridgeImplTest.java b/adapters/mso-openstack-adapters/src/test/java/org/onap/so/heatbridge/HeatBridgeImplTest.java
new file mode 100644
index 0000000000..3c777e17cb
--- /dev/null
+++ b/adapters/mso-openstack-adapters/src/test/java/org/onap/so/heatbridge/HeatBridgeImplTest.java
@@ -0,0 +1,375 @@
+/*
+ * Copyright (C) 2018 Bell Canada. All rights reserved.
+ *
+ * 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.
+ */
+package org.onap.so.heatbridge;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+
+import org.apache.commons.io.FileUtils;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.onap.aai.domain.yang.LInterface;
+import org.onap.aai.domain.yang.PInterface;
+import org.onap.aai.domain.yang.SriovPf;
+import org.onap.aai.domain.yang.Vserver;
+import org.onap.so.client.aai.AAIObjectType;
+import org.onap.so.client.aai.AAIResourcesClient;
+import org.onap.so.client.aai.AAISingleTransactionClient;
+import org.onap.so.client.aai.entities.uri.AAIResourceUri;
+import org.onap.so.client.aai.entities.uri.AAIUriFactory;
+import org.onap.so.client.graphinventory.exceptions.BulkProcessFailed;
+import org.onap.so.db.catalog.beans.CloudIdentity;
+import org.onap.so.heatbridge.constants.HeatBridgeConstants;
+import org.onap.so.heatbridge.openstack.api.OpenstackClient;
+import org.onap.so.heatbridge.openstack.api.OpenstackClientException;
+import org.openstack4j.model.compute.Flavor;
+import org.openstack4j.model.compute.Image;
+import org.openstack4j.model.compute.Server;
+import org.openstack4j.model.compute.Server.Status;
+import org.openstack4j.model.heat.Resource;
+import org.openstack4j.model.network.Network;
+import org.openstack4j.model.network.NetworkType;
+import org.openstack4j.model.network.Port;
+import org.openstack4j.openstack.heat.domain.HeatResource;
+import org.openstack4j.openstack.heat.domain.HeatResource.Resources;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.google.common.collect.ImmutableMap;
+
+
+@RunWith(MockitoJUnitRunner.class)
+public class HeatBridgeImplTest {
+
+ private static final String CLOUD_OWNER = "CloudOwner";
+ private static final String REGION_ID = "RegionOne";
+ private static final String TENANT_ID = "7320ec4a5b9d4589ba7c4412ccfd290f";
+ private static final ObjectMapper MAPPER = new ObjectMapper();
+
+ @Mock
+ private OpenstackClient osClient;
+
+ private CloudIdentity cloudIdentity = new CloudIdentity();
+
+ @Mock
+ private AAIResourcesClient resourcesClient;
+ @Mock
+ private AAISingleTransactionClient transaction;
+
+ private HeatBridgeImpl heatbridge;
+
+ @Before
+ public void setUp() throws HeatBridgeException, OpenstackClientException, BulkProcessFailed {
+
+ when(resourcesClient.beginSingleTransaction()).thenReturn(transaction);
+ heatbridge = new HeatBridgeImpl(resourcesClient, cloudIdentity, CLOUD_OWNER, REGION_ID, TENANT_ID);
+ }
+
+ @Ignore
+ @Test
+ public void testQueryNestedHeatStackResources() throws HeatBridgeException {
+ // Arrange
+ String heatStackId = "1234567";
+ List<Resource> expectedResourceList = (List<Resource>) extractTestStackResources();
+ when(osClient.getStackBasedResources(heatStackId, HeatBridgeConstants.OS_DEFAULT_HEAT_NESTING))
+ .thenReturn(expectedResourceList);
+
+ // Act
+ List<Resource> resourceList = heatbridge.queryNestedHeatStackResources(heatStackId);
+
+ // Assert
+ verify(osClient).getStackBasedResources(heatStackId, HeatBridgeConstants.OS_DEFAULT_HEAT_NESTING);
+ assertEquals(resourceList, expectedResourceList);
+ }
+
+ @Test
+ public void testExtractStackResourceIdsByResourceType() throws HeatBridgeException {
+ // Arrange
+ List<Resource> expectedResourceList = (List<Resource>) extractTestStackResources();
+ List<String> expectedServerIds = Arrays.asList("43c2159b-2c04-46ac-bda5-594110cae2d3",
+ "7cff109a-b2b7-4933-97b4-ec44a8365568");
+
+ // Act
+ List<String> serverIds = heatbridge
+ .extractStackResourceIdsByResourceType(expectedResourceList, HeatBridgeConstants.OS_SERVER_RESOURCE_TYPE);
+
+ // Assert
+ assertEquals(expectedServerIds, serverIds);
+ }
+
+ @Ignore
+ @Test
+ public void testGetAllOpenstackServers() {
+ // Arrange
+ List<Resource> stackResources = (List<Resource>) extractTestStackResources();
+
+ Server server1 = mock(Server.class);
+ Server server2 = mock(Server.class);
+ List<Server> expectedServers = Arrays.asList(server1, server2);
+
+ when(osClient.getServerById("43c2159b-2c04-46ac-bda5-594110cae2d3")).thenReturn(server1);
+ when(osClient.getServerById("7cff109a-b2b7-4933-97b4-ec44a8365568")).thenReturn(server2);
+
+ // Act
+ List<Server> servers = heatbridge.getAllOpenstackServers(stackResources);
+
+ // Assert
+ assertEquals(expectedServers, servers);
+ }
+
+ @Ignore
+ @Test
+ public void testExtractOpenstackImagesFromServers() {
+ // Arrange
+ Server server1 = mock(Server.class);
+ Server server2 = mock(Server.class);
+ List<Server> servers = Arrays.asList(server1, server2);
+
+ Image image1 = mock(Image.class);
+ Image image2 = mock(Image.class);
+ when(image1.getId()).thenReturn("1");
+ when(image2.getId()).thenReturn("1");
+ List<Image> expectedDistinctImages = Collections.singletonList(image1);
+
+ when(server1.getImage()).thenReturn(image1);
+ when(server2.getImage()).thenReturn(image2);
+
+ // Act
+ List<Image> images = heatbridge.extractOpenstackImagesFromServers(servers);
+
+ // Assert
+ assertEquals(expectedDistinctImages, images);
+ }
+
+ @Ignore
+ @Test
+ public void testExtractOpenstackFlavorsFromServers() {
+ // Arrange
+ Server server1 = mock(Server.class);
+ Server server2 = mock(Server.class);
+ List<Server> servers = Arrays.asList(server1, server2);
+
+ Flavor flavor1 = mock(Flavor.class);
+ Flavor flavor2 = mock(Flavor.class);
+ when(flavor1.getId()).thenReturn("1");
+ when(flavor2.getId()).thenReturn("2");
+ List<Flavor> expectedFlavors = Arrays.asList(flavor1, flavor2);
+
+ when(server1.getFlavor()).thenReturn(flavor1);
+ when(server2.getFlavor()).thenReturn(flavor2);
+
+ // Act
+ List<Flavor> flavors = heatbridge.extractOpenstackFlavorsFromServers(servers);
+
+ // Assert
+ assertEquals(expectedFlavors, flavors);
+ }
+
+ @Test
+ public void testUpdateVserversToAai() throws HeatBridgeException {
+ // Arrange
+ Server server1 = mock(Server.class);
+
+ when(server1.getId()).thenReturn("test-server1-id");
+ when(server1.getHypervisorHostname()).thenReturn("test-hypervisor");
+ when(server1.getName()).thenReturn("test-server1-name");
+ when(server1.getStatus()).thenReturn(Status.ACTIVE);
+ when(server1.getLinks()).thenReturn(new ArrayList<>());
+
+ Server server2 = mock(Server.class);
+ when(server2.getId()).thenReturn("test-server2-id");
+ when(server2.getHypervisorHostname()).thenReturn("test-hypervisor");
+ when(server2.getName()).thenReturn("test-server2-name");
+ when(server2.getStatus()).thenReturn(Status.ACTIVE);
+ when(server2.getLinks()).thenReturn(new ArrayList<>());
+
+ List<Server> servers = Arrays.asList(server1, server2);
+
+ Image image = mock(Image.class);
+ when(server1.getImage()).thenReturn(image);
+ when(server2.getImage()).thenReturn(image);
+ when(image.getId()).thenReturn("test-image-id");
+
+ Flavor flavor = mock(Flavor.class);
+ when(server1.getFlavor()).thenReturn(flavor);
+ when(server2.getFlavor()).thenReturn(flavor);
+ when(flavor.getId()).thenReturn("test-flavor-id");
+
+
+ // Act
+ heatbridge.buildAddVserversToAaiAction("test-genericVnf-id", "test-vfModule-id", servers);
+
+ // Assert
+ ArgumentCaptor<AAIResourceUri> captor = ArgumentCaptor.forClass(AAIResourceUri.class);
+ verify(transaction, times(2)).create(captor.capture(), any(Vserver.class));
+
+ List<AAIResourceUri> uris = captor.getAllValues();
+ assertEquals(AAIUriFactory.createResourceUri(
+ AAIObjectType.VSERVER, CLOUD_OWNER, REGION_ID, TENANT_ID, server1.getId()), uris.get(0));
+ assertEquals(AAIUriFactory.createResourceUri(
+ AAIObjectType.VSERVER, CLOUD_OWNER, REGION_ID, TENANT_ID, server2.getId()), uris.get(1));
+
+ }
+
+ @Test
+ public void testUpdateImagesToAai() throws HeatBridgeException {
+ // Arrange
+ Image image1 = mock(Image.class);
+ when(image1.getId()).thenReturn("test-image1-id");
+ when(image1.getName()).thenReturn("test-image1-name");
+ when(image1.getLinks()).thenReturn(new ArrayList<>());
+
+ Image image2 = mock(Image.class);
+ when(image2.getId()).thenReturn("test-image2-id");
+ when(image2.getName()).thenReturn("test-image2-name");
+ when(image2.getLinks()).thenReturn(new ArrayList<>());
+
+ List<Image> images = Arrays.asList(image1, image2);
+
+ // Act #1
+ heatbridge.buildAddImagesToAaiAction(images);
+
+ // Assert #1
+ verify(transaction, times(2)).create(any(AAIResourceUri.class), any(org.onap.aai.domain.yang.Image.class));
+
+ // Act #2
+ heatbridge.buildAddImagesToAaiAction(images);
+
+ // Assert #2
+ verify(transaction, times(4)).create(any(AAIResourceUri.class), any(org.onap.aai.domain.yang.Image.class));
+ }
+
+ @Test
+ public void testUpdateFlavorsToAai() throws HeatBridgeException {
+ // Arrange
+ Flavor flavor1 = mock(Flavor.class);
+ when(flavor1.getId()).thenReturn("test-flavor1-id");
+ when(flavor1.getName()).thenReturn("test-flavor1-name");
+ when(flavor1.getLinks()).thenReturn(new ArrayList<>());
+
+ Flavor flavor2 = mock(Flavor.class);
+ when(flavor2.getId()).thenReturn("test-flavor2-id");
+ when(flavor2.getName()).thenReturn("test-flavor2-name");
+ when(flavor2.getLinks()).thenReturn(new ArrayList<>());
+
+ List<Flavor> flavors = Arrays.asList(flavor1, flavor2);
+
+ // Act #1
+ heatbridge.buildAddFlavorsToAaiAction(flavors);
+
+ // Assert #1
+ verify(transaction, times(2)).create(any(AAIResourceUri.class), any(org.onap.aai.domain.yang.Flavor.class));
+
+ // Act #2
+ heatbridge.buildAddFlavorsToAaiAction(flavors);
+
+ // Assert #2
+ verify(transaction, times(4)).create(any(AAIResourceUri.class), any(org.onap.aai.domain.yang.Flavor.class));
+ }
+
+ @Ignore
+ @Test
+ public void testUpdateVserverLInterfacesToAai() throws HeatBridgeException {
+ // Arrange
+ List<Resource> stackResources = (List<Resource>) extractTestStackResources();
+ Port port = mock(Port.class);
+ when(port.getId()).thenReturn("test-port-id");
+ when(port.getName()).thenReturn("test-port-name");
+ when(port.getvNicType()).thenReturn(HeatBridgeConstants.OS_SRIOV_PORT_TYPE);
+ when(port.getMacAddress()).thenReturn("78:4f:43:68:e2:78");
+ when(port.getNetworkId()).thenReturn("890a203a-23gg-56jh-df67-731656a8f13a");
+ when(port.getDeviceId()).thenReturn("test-device-id");
+ when(port.getVifDetails())
+ .thenReturn(ImmutableMap.of(HeatBridgeConstants.OS_VLAN_NETWORK_KEY, "2345"));
+ String pfPciId = "0000:08:00.0";
+ when(port.getProfile()).thenReturn(ImmutableMap.of(HeatBridgeConstants.OS_PCI_SLOT_KEY, pfPciId,
+ HeatBridgeConstants.OS_PHYSICAL_NETWORK_KEY, "physical_network_id"));
+
+ Network network = mock(Network.class);
+ when(network.getId()).thenReturn("test-network-id");
+ when(network.getNetworkType()).thenReturn(NetworkType.VLAN);
+ when(network.getProviderSegID()).thenReturn("2345");
+
+ when(osClient.getPortById("212a203a-9764-4f42-84ea-731536a8f13a")).thenReturn(port);
+ when(osClient.getPortById("387e3904-8948-43d1-8635-b6c2042b54da")).thenReturn(port);
+ when(osClient.getPortById("70a09dfd-f1c5-4bc8-bd8f-dc539b8d662a")).thenReturn(port);
+ when(osClient.getPortById("12f88b4d-c8a4-4fbd-bcb4-7e36af02430b")).thenReturn(port);
+ when(osClient.getPortById("c54b9f45-b413-4937-bbe4-3c8a5689cfc9")).thenReturn(port);
+ when(osClient.getNetworkById(anyString())).thenReturn(network);
+
+ SriovPf sriovPf = new SriovPf();
+ sriovPf.setPfPciId(pfPciId);
+ PInterface pIf = mock(PInterface.class);
+ when(pIf.getInterfaceName()).thenReturn("test-port-id");
+ when(resourcesClient.get(eq(PInterface.class), any(AAIResourceUri.class))).thenReturn(Optional.of(pIf));
+
+ // Act
+ heatbridge.buildAddVserverLInterfacesToAaiAction(stackResources, Arrays.asList("1", "2"));
+
+ // Assert
+ verify(transaction, times(5)).create(any(AAIResourceUri.class), any(LInterface.class));
+ verify(osClient, times(5)).getPortById(anyString());
+ verify(osClient, times(5)).getNetworkById(anyString());
+ }
+
+ private List<? extends Resource> extractTestStackResources() {
+ List<HeatResource> stackResources = null;
+ try {
+ stackResources = MAPPER.readValue(readTestResourceFile("stack-resources.json"), Resources.class)
+ .getList();
+ assertNotNull(stackResources);
+ assertFalse(stackResources.isEmpty());
+ } catch (IOException e) {
+ Assert.fail("Failed to extract test stack resources.");
+ }
+ return stackResources;
+ }
+
+ private String readTestResourceFile(String filePath) {
+ String content = null;
+ String pathname = Objects.requireNonNull(getClass().getClassLoader().getResource(filePath)).getFile();
+ File file = new File(pathname);
+ try {
+ content = Objects.requireNonNull(FileUtils.readFileToString(file, Charset.defaultCharset()));
+ } catch (IOException e) {
+ Assert.fail(String.format("Failed to read test resource file (%s)", filePath));
+ }
+ return content;
+ }
+}
diff --git a/adapters/mso-openstack-adapters/src/test/resources/stack-resources.json b/adapters/mso-openstack-adapters/src/test/resources/stack-resources.json
new file mode 100644
index 0000000000..6b63895a33
--- /dev/null
+++ b/adapters/mso-openstack-adapters/src/test/resources/stack-resources.json
@@ -0,0 +1,441 @@
+{
+ "resources": [
+ {
+ "resource_name": "ge_000",
+ "links": [
+ {
+ "href": "http://10.10.10.10:8004/v1/7320ec4a5b9d4589ba7c4412ccfd290f/stacks/ClosedLoop_vFW_VfModule/d1431cdc-9b29-44fc-98d0-9b3dc1ac246d/resources/ge_000",
+ "rel": "self"
+ },
+ {
+ "href": "http://10.10.10.10:8004/v1/7320ec4a5b9d4589ba7c4412ccfd290f/stacks/ClosedLoop_vFW_VfModule/d1431cdc-9b29-44fc-98d0-9b3dc1ac246d",
+ "rel": "stack"
+ },
+ {
+ "href": "http://10.10.10.10:8004/v1/7320ec4a5b9d4589ba7c4412ccfd290f/stacks/ClosedLoop_vFW_VfModule-ge_000-t66dxpwq6nb5/deee54a3-08ac-477b-9c09-c798edb40be1",
+ "rel": "nested"
+ }
+ ],
+ "logical_resource_id": "ge_000",
+ "resource_status_reason": "state changed",
+ "updated_time": "2018-04-09T21:09:52Z",
+ "required_by": [
+ "vfw_instance"
+ ],
+ "resource_status": "CREATE_COMPLETE",
+ "physical_resource_id": "deee54a3-08ac-477b-9c09-c798edb40be1",
+ "resource_type": "port.yaml"
+ },
+ {
+ "resource_name": "vfw_instance",
+ "links": [
+ {
+ "href": "http://10.10.10.10:8004/v1/7320ec4a5b9d4589ba7c4412ccfd290f/stacks/ClosedLoop_vFW_VfModule/d1431cdc-9b29-44fc-98d0-9b3dc1ac246d/resources/vfw_instance",
+ "rel": "self"
+ },
+ {
+ "href": "http://10.10.10.10:8004/v1/7320ec4a5b9d4589ba7c4412ccfd290f/stacks/ClosedLoop_vFW_VfModule/d1431cdc-9b29-44fc-98d0-9b3dc1ac246d",
+ "rel": "stack"
+ },
+ {
+ "href": "http://10.10.10.10:8004/v1/7320ec4a5b9d4589ba7c4412ccfd290f/stacks/ClosedLoop_vFW_VfModule-vfw_instance-tw3i5ile2nam/54f93b9e-5138-4f3f-bfe0-ee06e1f0877b",
+ "rel": "nested"
+ }
+ ],
+ "logical_resource_id": "vfw_instance",
+ "resource_status_reason": "state changed",
+ "updated_time": "2018-04-09T21:09:52Z",
+ "required_by": [],
+ "resource_status": "CREATE_COMPLETE",
+ "physical_resource_id": "54f93b9e-5138-4f3f-bfe0-ee06e1f0877b",
+ "resource_type": "vfw.yaml"
+ },
+ {
+ "resource_name": "port",
+ "links": [
+ {
+ "href": "http://10.10.10.10:8004/v1/7320ec4a5b9d4589ba7c4412ccfd290f/stacks/ClosedLoop_vFW_VfModule-ge_000-t66dxpwq6nb5/deee54a3-08ac-477b-9c09-c798edb40be1/resources/port",
+ "rel": "self"
+ },
+ {
+ "href": "http://10.10.10.10:8004/v1/7320ec4a5b9d4589ba7c4412ccfd290f/stacks/ClosedLoop_vFW_VfModule-ge_000-t66dxpwq6nb5/deee54a3-08ac-477b-9c09-c798edb40be1",
+ "rel": "stack"
+ }
+ ],
+ "logical_resource_id": "port",
+ "resource_status": "CREATE_COMPLETE",
+ "updated_time": "2018-04-09T21:09:52Z",
+ "required_by": [],
+ "resource_status_reason": "state changed",
+ "physical_resource_id": "212a203a-9764-4f42-84ea-731536a8f13a",
+ "resource_type": "OS::Neutron::Port"
+ },
+ {
+ "resource_name": "pfe0",
+ "links": [
+ {
+ "href": "http://10.10.10.10:8004/v1/7320ec4a5b9d4589ba7c4412ccfd290f/stacks/ClosedLoop_vFW_VfModule-vfw_instance-tw3i5ile2nam/54f93b9e-5138-4f3f-bfe0-ee06e1f0877b/resources/pfe0",
+ "rel": "self"
+ },
+ {
+ "href": "http://10.10.10.10:8004/v1/7320ec4a5b9d4589ba7c4412ccfd290f/stacks/ClosedLoop_vFW_VfModule-vfw_instance-tw3i5ile2nam/54f93b9e-5138-4f3f-bfe0-ee06e1f0877b",
+ "rel": "stack"
+ },
+ {
+ "href": "http://10.10.10.10:8004/v1/7320ec4a5b9d4589ba7c4412ccfd290f/stacks/ClosedLoop_vFW_VfModule-vfw_instance-tw3i5ile2nam-pfe0-kvqmgn7jmiti/1325e04b-e836-4a13-bb2e-f34923d97ad7",
+ "rel": "nested"
+ }
+ ],
+ "logical_resource_id": "pfe0",
+ "resource_status_reason": "state changed",
+ "updated_time": "2018-04-09T21:09:54Z",
+ "required_by": [
+ "re0"
+ ],
+ "resource_status": "CREATE_COMPLETE",
+ "physical_resource_id": "1325e04b-e836-4a13-bb2e-f34923d97ad7",
+ "resource_type": "fpc.yaml"
+ },
+ {
+ "resource_name": "fpc_internal_port",
+ "links": [
+ {
+ "href": "http://10.10.10.10:8004/v1/7320ec4a5b9d4589ba7c4412ccfd290f/stacks/ClosedLoop_vFW_VfModule-vfw_instance-tw3i5ile2nam/54f93b9e-5138-4f3f-bfe0-ee06e1f0877b/resources/fpc_internal_port",
+ "rel": "self"
+ },
+ {
+ "href": "http://10.10.10.10:8004/v1/7320ec4a5b9d4589ba7c4412ccfd290f/stacks/ClosedLoop_vFW_VfModule-vfw_instance-tw3i5ile2nam/54f93b9e-5138-4f3f-bfe0-ee06e1f0877b",
+ "rel": "stack"
+ },
+ {
+ "href": "http://10.10.10.10:8004/v1/7320ec4a5b9d4589ba7c4412ccfd290f/stacks/ClosedLoop_vFW_VfModule-vfw_instance-tw3i5ile2nam-fpc_internal_port-gbnyc4w7mb5b/4e920f39-9784-417e-9331-d75e2e37cc51",
+ "rel": "nested"
+ }
+ ],
+ "logical_resource_id": "fpc_internal_port",
+ "resource_status_reason": "state changed",
+ "updated_time": "2018-04-09T21:09:54Z",
+ "required_by": [
+ "pfe0"
+ ],
+ "resource_status": "CREATE_COMPLETE",
+ "physical_resource_id": "4e920f39-9784-417e-9331-d75e2e37cc51",
+ "resource_type": "re_pfe_port.yaml"
+ },
+ {
+ "resource_name": "re-fpc-affinity-grp",
+ "links": [
+ {
+ "href": "http://10.10.10.10:8004/v1/7320ec4a5b9d4589ba7c4412ccfd290f/stacks/ClosedLoop_vFW_VfModule-vfw_instance-tw3i5ile2nam/54f93b9e-5138-4f3f-bfe0-ee06e1f0877b/resources/re-fpc-affinity-grp",
+ "rel": "self"
+ },
+ {
+ "href": "http://10.10.10.10:8004/v1/7320ec4a5b9d4589ba7c4412ccfd290f/stacks/ClosedLoop_vFW_VfModule-vfw_instance-tw3i5ile2nam/54f93b9e-5138-4f3f-bfe0-ee06e1f0877b",
+ "rel": "stack"
+ }
+ ],
+ "logical_resource_id": "re-fpc-affinity-grp",
+ "resource_status": "CREATE_COMPLETE",
+ "updated_time": "2018-04-09T21:09:54Z",
+ "required_by": [
+ "pfe0",
+ "re0"
+ ],
+ "resource_status_reason": "state changed",
+ "physical_resource_id": "3aa37238-f8ff-4c96-b56a-8903bae28a60",
+ "resource_type": "OS::Nova::ServerGroup"
+ },
+ {
+ "resource_name": "re0",
+ "links": [
+ {
+ "href": "http://10.10.10.10:8004/v1/7320ec4a5b9d4589ba7c4412ccfd290f/stacks/ClosedLoop_vFW_VfModule-vfw_instance-tw3i5ile2nam/54f93b9e-5138-4f3f-bfe0-ee06e1f0877b/resources/re0",
+ "rel": "self"
+ },
+ {
+ "href": "http://10.10.10.10:8004/v1/7320ec4a5b9d4589ba7c4412ccfd290f/stacks/ClosedLoop_vFW_VfModule-vfw_instance-tw3i5ile2nam/54f93b9e-5138-4f3f-bfe0-ee06e1f0877b",
+ "rel": "stack"
+ },
+ {
+ "href": "http://10.10.10.10:8004/v1/7320ec4a5b9d4589ba7c4412ccfd290f/stacks/ClosedLoop_vFW_VfModule-vfw_instance-tw3i5ile2nam-re0-73oifso3xntc/0915e27e-428d-4d2c-a67b-abbce18081b2",
+ "rel": "nested"
+ }
+ ],
+ "logical_resource_id": "re0",
+ "resource_status_reason": "state changed",
+ "updated_time": "2018-04-09T21:09:54Z",
+ "required_by": [],
+ "resource_status": "CREATE_COMPLETE",
+ "physical_resource_id": "0915e27e-428d-4d2c-a67b-abbce18081b2",
+ "resource_type": "re.yaml"
+ },
+ {
+ "resource_name": "re_external_port",
+ "links": [
+ {
+ "href": "http://10.10.10.10:8004/v1/7320ec4a5b9d4589ba7c4412ccfd290f/stacks/ClosedLoop_vFW_VfModule-vfw_instance-tw3i5ile2nam/54f93b9e-5138-4f3f-bfe0-ee06e1f0877b/resources/re_external_port",
+ "rel": "self"
+ },
+ {
+ "href": "http://10.10.10.10:8004/v1/7320ec4a5b9d4589ba7c4412ccfd290f/stacks/ClosedLoop_vFW_VfModule-vfw_instance-tw3i5ile2nam/54f93b9e-5138-4f3f-bfe0-ee06e1f0877b",
+ "rel": "stack"
+ },
+ {
+ "href": "http://10.10.10.10:8004/v1/7320ec4a5b9d4589ba7c4412ccfd290f/stacks/ClosedLoop_vFW_VfModule-vfw_instance-tw3i5ile2nam-re_external_port-3okiee3zocr7/f58c65e3-a72e-4b2d-a295-cb40324d6b4c",
+ "rel": "nested"
+ }
+ ],
+ "logical_resource_id": "re_external_port",
+ "resource_status_reason": "state changed",
+ "updated_time": "2018-04-09T21:09:54Z",
+ "required_by": [
+ "re0"
+ ],
+ "resource_status": "CREATE_COMPLETE",
+ "physical_resource_id": "f58c65e3-a72e-4b2d-a295-cb40324d6b4c",
+ "resource_type": "port.yaml"
+ },
+ {
+ "resource_name": "fpc_external_port",
+ "links": [
+ {
+ "href": "http://10.10.10.10:8004/v1/7320ec4a5b9d4589ba7c4412ccfd290f/stacks/ClosedLoop_vFW_VfModule-vfw_instance-tw3i5ile2nam/54f93b9e-5138-4f3f-bfe0-ee06e1f0877b/resources/fpc_external_port",
+ "rel": "self"
+ },
+ {
+ "href": "http://10.10.10.10:8004/v1/7320ec4a5b9d4589ba7c4412ccfd290f/stacks/ClosedLoop_vFW_VfModule-vfw_instance-tw3i5ile2nam/54f93b9e-5138-4f3f-bfe0-ee06e1f0877b",
+ "rel": "stack"
+ },
+ {
+ "href": "http://10.10.10.10:8004/v1/7320ec4a5b9d4589ba7c4412ccfd290f/stacks/ClosedLoop_vFW_VfModule-vfw_instance-tw3i5ile2nam-fpc_external_port-5vumcqp7hkbn/979e47c9-c15a-428e-ad73-af922029ee37",
+ "rel": "nested"
+ }
+ ],
+ "logical_resource_id": "fpc_external_port",
+ "resource_status_reason": "state changed",
+ "updated_time": "2018-04-09T21:09:54Z",
+ "required_by": [
+ "pfe0",
+ "re0"
+ ],
+ "resource_status": "CREATE_COMPLETE",
+ "physical_resource_id": "979e47c9-c15a-428e-ad73-af922029ee37",
+ "resource_type": "port.yaml"
+ },
+ {
+ "resource_name": "re_internal_port",
+ "links": [
+ {
+ "href": "http://10.10.10.10:8004/v1/7320ec4a5b9d4589ba7c4412ccfd290f/stacks/ClosedLoop_vFW_VfModule-vfw_instance-tw3i5ile2nam/54f93b9e-5138-4f3f-bfe0-ee06e1f0877b/resources/re_internal_port",
+ "rel": "self"
+ },
+ {
+ "href": "http://10.10.10.10:8004/v1/7320ec4a5b9d4589ba7c4412ccfd290f/stacks/ClosedLoop_vFW_VfModule-vfw_instance-tw3i5ile2nam/54f93b9e-5138-4f3f-bfe0-ee06e1f0877b",
+ "rel": "stack"
+ },
+ {
+ "href": "http://10.10.10.10:8004/v1/7320ec4a5b9d4589ba7c4412ccfd290f/stacks/ClosedLoop_vFW_VfModule-vfw_instance-tw3i5ile2nam-re_internal_port-u4txbvemndci/0aebfd9d-ad97-43b1-a67b-b2b5340738d2",
+ "rel": "nested"
+ }
+ ],
+ "logical_resource_id": "re_internal_port",
+ "resource_status_reason": "state changed",
+ "updated_time": "2018-04-09T21:09:54Z",
+ "required_by": [
+ "re0"
+ ],
+ "resource_status": "CREATE_COMPLETE",
+ "physical_resource_id": "0aebfd9d-ad97-43b1-a67b-b2b5340738d2",
+ "resource_type": "re_pfe_port.yaml"
+ },
+ {
+ "resource_name": "re_pfe_network",
+ "links": [
+ {
+ "href": "http://10.10.10.10:8004/v1/7320ec4a5b9d4589ba7c4412ccfd290f/stacks/ClosedLoop_vFW_VfModule-vfw_instance-tw3i5ile2nam/54f93b9e-5138-4f3f-bfe0-ee06e1f0877b/resources/re_pfe_network",
+ "rel": "self"
+ },
+ {
+ "href": "http://10.10.10.10:8004/v1/7320ec4a5b9d4589ba7c4412ccfd290f/stacks/ClosedLoop_vFW_VfModule-vfw_instance-tw3i5ile2nam/54f93b9e-5138-4f3f-bfe0-ee06e1f0877b",
+ "rel": "stack"
+ },
+ {
+ "href": "http://10.10.10.10:8004/v1/7320ec4a5b9d4589ba7c4412ccfd290f/stacks/ClosedLoop_vFW_VfModule-vfw_instance-tw3i5ile2nam-re_pfe_network-2wmjvgzrhtvs/290fc2fd-cd1d-47d0-90eb-2ece7c009b29",
+ "rel": "nested"
+ }
+ ],
+ "logical_resource_id": "re_pfe_network",
+ "resource_status_reason": "state changed",
+ "updated_time": "2018-04-09T21:09:54Z",
+ "required_by": [
+ "fpc_internal_port",
+ "re_internal_port"
+ ],
+ "resource_status": "CREATE_COMPLETE",
+ "physical_resource_id": "290fc2fd-cd1d-47d0-90eb-2ece7c009b29",
+ "resource_type": "bridge_int.yaml"
+ },
+ {
+ "resource_name": "fpc",
+ "links": [
+ {
+ "href": "http://10.10.10.10:8004/v1/7320ec4a5b9d4589ba7c4412ccfd290f/stacks/ClosedLoop_vFW_VfModule-vfw_instance-tw3i5ile2nam-pfe0-kvqmgn7jmiti/1325e04b-e836-4a13-bb2e-f34923d97ad7/resources/fpc",
+ "rel": "self"
+ },
+ {
+ "href": "http://10.10.10.10:8004/v1/7320ec4a5b9d4589ba7c4412ccfd290f/stacks/ClosedLoop_vFW_VfModule-vfw_instance-tw3i5ile2nam-pfe0-kvqmgn7jmiti/1325e04b-e836-4a13-bb2e-f34923d97ad7",
+ "rel": "stack"
+ }
+ ],
+ "logical_resource_id": "fpc",
+ "resource_status": "CREATE_COMPLETE",
+ "updated_time": "2018-04-09T21:09:58Z",
+ "required_by": [],
+ "resource_status_reason": "state changed",
+ "physical_resource_id": "43c2159b-2c04-46ac-bda5-594110cae2d3",
+ "resource_type": "OS::Nova::Server"
+ },
+ {
+ "resource_name": "port",
+ "links": [
+ {
+ "href": "http://10.10.10.10:8004/v1/7320ec4a5b9d4589ba7c4412ccfd290f/stacks/ClosedLoop_vFW_VfModule-vfw_instance-tw3i5ile2nam-fpc_internal_port-gbnyc4w7mb5b/4e920f39-9784-417e-9331-d75e2e37cc51/resources/port",
+ "rel": "self"
+ },
+ {
+ "href": "http://10.10.10.10:8004/v1/7320ec4a5b9d4589ba7c4412ccfd290f/stacks/ClosedLoop_vFW_VfModule-vfw_instance-tw3i5ile2nam-fpc_internal_port-gbnyc4w7mb5b/4e920f39-9784-417e-9331-d75e2e37cc51",
+ "rel": "stack"
+ }
+ ],
+ "logical_resource_id": "port",
+ "resource_status": "CREATE_COMPLETE",
+ "updated_time": "2018-04-09T21:09:56Z",
+ "required_by": [],
+ "resource_status_reason": "state changed",
+ "physical_resource_id": "387e3904-8948-43d1-8635-b6c2042b54da",
+ "resource_type": "OS::Neutron::Port"
+ },
+ {
+ "resource_name": "re",
+ "links": [
+ {
+ "href": "http://10.10.10.10:8004/v1/7320ec4a5b9d4589ba7c4412ccfd290f/stacks/ClosedLoop_vFW_VfModule-vfw_instance-tw3i5ile2nam-re0-73oifso3xntc/0915e27e-428d-4d2c-a67b-abbce18081b2/resources/re",
+ "rel": "self"
+ },
+ {
+ "href": "http://10.10.10.10:8004/v1/7320ec4a5b9d4589ba7c4412ccfd290f/stacks/ClosedLoop_vFW_VfModule-vfw_instance-tw3i5ile2nam-re0-73oifso3xntc/0915e27e-428d-4d2c-a67b-abbce18081b2",
+ "rel": "stack"
+ }
+ ],
+ "logical_resource_id": "re",
+ "resource_status": "CREATE_COMPLETE",
+ "updated_time": "2018-04-09T21:10:36Z",
+ "required_by": [],
+ "resource_status_reason": "state changed",
+ "physical_resource_id": "7cff109a-b2b7-4933-97b4-ec44a8365568",
+ "resource_type": "OS::Nova::Server"
+ },
+ {
+ "resource_name": "port",
+ "links": [
+ {
+ "href": "http://10.10.10.10:8004/v1/7320ec4a5b9d4589ba7c4412ccfd290f/stacks/ClosedLoop_vFW_VfModule-vfw_instance-tw3i5ile2nam-re_external_port-3okiee3zocr7/f58c65e3-a72e-4b2d-a295-cb40324d6b4c/resources/port",
+ "rel": "self"
+ },
+ {
+ "href": "http://10.10.10.10:8004/v1/7320ec4a5b9d4589ba7c4412ccfd290f/stacks/ClosedLoop_vFW_VfModule-vfw_instance-tw3i5ile2nam-re_external_port-3okiee3zocr7/f58c65e3-a72e-4b2d-a295-cb40324d6b4c",
+ "rel": "stack"
+ }
+ ],
+ "logical_resource_id": "port",
+ "resource_status": "CREATE_COMPLETE",
+ "updated_time": "2018-04-09T21:09:55Z",
+ "required_by": [],
+ "resource_status_reason": "state changed",
+ "physical_resource_id": "70a09dfd-f1c5-4bc8-bd8f-dc539b8d662a",
+ "resource_type": "OS::Neutron::Port"
+ },
+ {
+ "resource_name": "port",
+ "links": [
+ {
+ "href": "http://10.10.10.10:8004/v1/7320ec4a5b9d4589ba7c4412ccfd290f/stacks/ClosedLoop_vFW_VfModule-vfw_instance-tw3i5ile2nam-fpc_external_port-5vumcqp7hkbn/979e47c9-c15a-428e-ad73-af922029ee37/resources/port",
+ "rel": "self"
+ },
+ {
+ "href": "http://10.10.10.10:8004/v1/7320ec4a5b9d4589ba7c4412ccfd290f/stacks/ClosedLoop_vFW_VfModule-vfw_instance-tw3i5ile2nam-fpc_external_port-5vumcqp7hkbn/979e47c9-c15a-428e-ad73-af922029ee37",
+ "rel": "stack"
+ }
+ ],
+ "logical_resource_id": "port",
+ "resource_status": "CREATE_COMPLETE",
+ "updated_time": "2018-04-09T21:09:55Z",
+ "required_by": [],
+ "resource_status_reason": "state changed",
+ "physical_resource_id": "12f88b4d-c8a4-4fbd-bcb4-7e36af02430b",
+ "resource_type": "OS::Neutron::Port"
+ },
+ {
+ "resource_name": "port",
+ "links": [
+ {
+ "href": "http://10.10.10.10:8004/v1/7320ec4a5b9d4589ba7c4412ccfd290f/stacks/ClosedLoop_vFW_VfModule-vfw_instance-tw3i5ile2nam-re_internal_port-u4txbvemndci/0aebfd9d-ad97-43b1-a67b-b2b5340738d2/resources/port",
+ "rel": "self"
+ },
+ {
+ "href": "http://10.10.10.10:8004/v1/7320ec4a5b9d4589ba7c4412ccfd290f/stacks/ClosedLoop_vFW_VfModule-vfw_instance-tw3i5ile2nam-re_internal_port-u4txbvemndci/0aebfd9d-ad97-43b1-a67b-b2b5340738d2",
+ "rel": "stack"
+ }
+ ],
+ "logical_resource_id": "port",
+ "resource_status": "CREATE_COMPLETE",
+ "updated_time": "2018-04-09T21:09:56Z",
+ "required_by": [],
+ "resource_status_reason": "state changed",
+ "physical_resource_id": "c54b9f45-b413-4937-bbe4-3c8a5689cfc9",
+ "resource_type": "OS::Neutron::Port"
+ },
+ {
+ "resource_name": "bridge_network_subnet",
+ "links": [
+ {
+ "href": "http://10.10.10.10:8004/v1/7320ec4a5b9d4589ba7c4412ccfd290f/stacks/ClosedLoop_vFW_VfModule-vfw_instance-tw3i5ile2nam-re_pfe_network-2wmjvgzrhtvs/290fc2fd-cd1d-47d0-90eb-2ece7c009b29/resources/bridge_network_subnet",
+ "rel": "self"
+ },
+ {
+ "href": "http://10.10.10.10:8004/v1/7320ec4a5b9d4589ba7c4412ccfd290f/stacks/ClosedLoop_vFW_VfModule-vfw_instance-tw3i5ile2nam-re_pfe_network-2wmjvgzrhtvs/290fc2fd-cd1d-47d0-90eb-2ece7c009b29",
+ "rel": "stack"
+ }
+ ],
+ "logical_resource_id": "bridge_network_subnet",
+ "resource_status": "CREATE_COMPLETE",
+ "updated_time": "2018-04-09T21:09:55Z",
+ "required_by": [],
+ "resource_status_reason": "state changed",
+ "physical_resource_id": "5ffd8c02-6913-4b67-adba-74e78c2bbe40",
+ "resource_type": "OS::Neutron::Subnet"
+ },
+ {
+ "resource_name": "bridge_network",
+ "links": [
+ {
+ "href": "http://10.10.10.10:8004/v1/7320ec4a5b9d4589ba7c4412ccfd290f/stacks/ClosedLoop_vFW_VfModule-vfw_instance-tw3i5ile2nam-re_pfe_network-2wmjvgzrhtvs/290fc2fd-cd1d-47d0-90eb-2ece7c009b29/resources/bridge_network",
+ "rel": "self"
+ },
+ {
+ "href": "http://10.10.10.10:8004/v1/7320ec4a5b9d4589ba7c4412ccfd290f/stacks/ClosedLoop_vFW_VfModule-vfw_instance-tw3i5ile2nam-re_pfe_network-2wmjvgzrhtvs/290fc2fd-cd1d-47d0-90eb-2ece7c009b29",
+ "rel": "stack"
+ }
+ ],
+ "logical_resource_id": "bridge_network",
+ "resource_status": "CREATE_COMPLETE",
+ "updated_time": "2018-04-09T21:09:55Z",
+ "required_by": [
+ "bridge_network_subnet"
+ ],
+ "resource_status_reason": "state changed",
+ "physical_resource_id": "5ad95036-8daf-4379-a59c-865f35976cd4",
+ "resource_type": "OS::Neutron::Net"
+ }
+ ]
+}