From 9f6c9c74c5f10794cdbe6de2ed6d0539ce7d0d84 Mon Sep 17 00:00:00 2001 From: "BOSLET, CORY" Date: Mon, 8 Mar 2021 15:08:06 -0500 Subject: Added volume creation to heatbridge Added volume creation to heatbridge Issue-ID: SO-3577 Signed-off-by: AT&T Open Source Change-Id: I0f0844187efe880cccf4b663c8c4fadc346680c3 --- .../tasks/inventory/CreateAAIInventory.java | 2 ++ .../java/org/onap/so/heatbridge/HeatBridgeApi.java | 9 +++++ .../org/onap/so/heatbridge/HeatBridgeImpl.java | 42 ++++++++++++++++++++++ .../heatbridge/openstack/api/OpenstackClient.java | 8 +++++ .../openstack/api/OpenstackClientImpl.java | 7 ++++ .../org/onap/so/heatbridge/HeatBridgeImplTest.java | 26 +++++++++++++- .../src/test/resources/stack-resources.json | 22 ++++++++++++ 7 files changed, 115 insertions(+), 1 deletion(-) (limited to 'adapters/mso-openstack-adapters') diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/tasks/inventory/CreateAAIInventory.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/tasks/inventory/CreateAAIInventory.java index 0dd7635506..15cf4af62a 100644 --- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/tasks/inventory/CreateAAIInventory.java +++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/adapters/tasks/inventory/CreateAAIInventory.java @@ -121,6 +121,8 @@ public class CreateAAIInventory { cloudInformation.getOwner()); logger.debug("Successfully queried neutron resources and built AAI actions to add l-interfaces to vservers."); + heatBridgeClient.buildAddVolumes(stackResources); + // Update AAI logger.debug("Current Dry Run Value: {}", env.getProperty("heatBridgeDryrun", Boolean.class, false)); heatBridgeClient.submitToAai(env.getProperty("heatBridgeDryrun", Boolean.class, false)); diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/HeatBridgeApi.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/HeatBridgeApi.java index 1b2fdfedfa..1de7273909 100644 --- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/HeatBridgeApi.java +++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/HeatBridgeApi.java @@ -159,6 +159,13 @@ public interface HeatBridgeApi { void buildAddVserverLInterfacesToAaiAction(List stackResources, List oobMgtNetIds, String cloudOwner) throws HeatBridgeException; + /** + * Query and build AAI actions for Openstack volumes + * + * @throws HeatBridgeException when failing to remove heatbridge data from AAI for a given vf-module + */ + void buildAddVolumes(List stackResources) throws HeatBridgeException; + /** * Query and build AAI actions for Openstack Compute resources to AAI's pserver and pinterface objects * @@ -180,4 +187,6 @@ public interface HeatBridgeApi { * @throws HeatBridgeException when failing to remove heatbridge data from AAI for a given vf-module */ void deleteVfModuleData(String vnfId, String vfModuleId) throws HeatBridgeException; + + } diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/HeatBridgeImpl.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/HeatBridgeImpl.java index 04c6ea4ff7..1bf4aff8f6 100644 --- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/HeatBridgeImpl.java +++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/HeatBridgeImpl.java @@ -64,6 +64,7 @@ import org.onap.aai.domain.yang.SriovPf; import org.onap.aai.domain.yang.SriovVf; import org.onap.aai.domain.yang.Subnets; import org.onap.aai.domain.yang.Vlan; +import org.onap.aai.domain.yang.Volume; import org.onap.aai.domain.yang.Vserver; import org.onap.aaiclient.client.aai.AAIDSLQueryClient; import org.onap.aaiclient.client.aai.AAIResourcesClient; @@ -103,6 +104,7 @@ import org.openstack4j.model.network.Network; import org.openstack4j.model.network.NetworkType; import org.openstack4j.model.network.Port; import org.openstack4j.model.network.Subnet; +import org.openstack4j.model.storage.block.VolumeAttachment; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.core.env.Environment; @@ -421,6 +423,46 @@ public class HeatBridgeImpl implements HeatBridgeApi { } } + @Override + public void buildAddVolumes(List stackResources) throws HeatBridgeException { + try { + if (stackResources.stream().anyMatch(r -> r.getType().equals("OS::Cinder::Volume"))) { + stackResources.stream().filter(r -> r.getType().equalsIgnoreCase("OS::Cinder::Volume")) + .forEach(r -> createVolume(r)); + } else { + logger.debug("Heat stack contains no volumes"); + } + } catch (Exception e) { + logger.error("Failed to add volumes to AAI", e); + throw new HeatBridgeException("Failed to add volumes to AAI", e); + } + + } + + protected void createVolume(Resource r) { + org.openstack4j.model.storage.block.Volume osVolume = osClient.getVolumeById(r.getPhysicalResourceId()); + List attachments = osVolume.getAttachments(); + if (attachments != null) { + Optional vserver = attachments.stream().findFirst(); + if (vserver.isPresent()) { + Volume volume = new Volume(); + volume.setVolumeId(r.getPhysicalResourceId()); + AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.cloudInfrastructure() + .cloudRegion(cloudOwner, cloudRegionId).tenant(tenantId).vserver(vserver.get().getServerId()) + .volume(r.getPhysicalResourceId())); + transaction.createIfNotExists(uri, Optional.of(volume)); + } else { + logger.warn( + "Volume {} contains no attachments in openstack. Unable to determine which vserver volume belongs too.", + r.getPhysicalResourceId()); + } + } else { + logger.warn( + "Volume {} contains no attachments in openstack. Unable to determine which vserver volume belongs too.", + r.getPhysicalResourceId()); + } + } + protected String getInterfaceType(NodeType nodeType, String nicType) { logger.debug("nicType: " + nicType + "nodeType: " + nodeType); if (DIRECT.equalsIgnoreCase(nicType)) { diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/openstack/api/OpenstackClient.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/openstack/api/OpenstackClient.java index 8d47ff4ceb..a4aacfe0e2 100644 --- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/openstack/api/OpenstackClient.java +++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/openstack/api/OpenstackClient.java @@ -43,6 +43,7 @@ import org.openstack4j.model.heat.Resource; import org.openstack4j.model.network.Network; import org.openstack4j.model.network.Port; import org.openstack4j.model.network.Subnet; +import org.openstack4j.model.storage.block.Volume; public interface OpenstackClient { @@ -101,4 +102,11 @@ public interface OpenstackClient { * @return Subnet object. */ Subnet getSubnetById(String subnetId); + + /** + * Get a volume object by volume ID + * + * @return Volume object. + */ + Volume getVolumeById(String volumeId); } diff --git a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/openstack/api/OpenstackClientImpl.java b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/openstack/api/OpenstackClientImpl.java index 1505203d7c..81f09b8a3e 100644 --- a/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/openstack/api/OpenstackClientImpl.java +++ b/adapters/mso-openstack-adapters/src/main/java/org/onap/so/heatbridge/openstack/api/OpenstackClientImpl.java @@ -46,6 +46,8 @@ import org.openstack4j.model.heat.Resource; import org.openstack4j.model.network.Network; import org.openstack4j.model.network.Port; import org.openstack4j.model.network.Subnet; +import org.openstack4j.model.storage.block.Volume; +import org.openstack4j.model.storage.block.VolumeBackup; abstract class OpenstackClientImpl implements OpenstackClient { @Override @@ -84,6 +86,11 @@ abstract class OpenstackClientImpl implements OpenstackClient { return getClient().networking().subnet().get(subnetId); } + @Override + public Volume getVolumeById(String id) { + return getClient().blockStorage().volumes().get(id); + } + /** * Retrieves the specific client to utilize. * 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 index fab7df5345..cf3e1c5ee1 100644 --- 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 @@ -106,6 +106,8 @@ import org.openstack4j.model.network.Network; import org.openstack4j.model.network.NetworkType; import org.openstack4j.model.network.Port; import org.openstack4j.model.network.Subnet; +import org.openstack4j.model.storage.block.Volume; +import org.openstack4j.model.storage.block.VolumeAttachment; import org.openstack4j.openstack.heat.domain.HeatResource; import org.openstack4j.openstack.heat.domain.HeatResource.Resources; import org.slf4j.Logger; @@ -118,7 +120,6 @@ import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.collect.ImmutableMap; - @RunWith(MockitoJUnitRunner.Silent.class) public class HeatBridgeImplTest { @@ -808,6 +809,28 @@ public class HeatBridgeImplTest { assertEquals(1, images.size()); } + @Test + public void testBuildAddVolumes() throws HeatBridgeException { + List stackResources = (List) extractTestStackResources(); + Volume volume = mock(Volume.class); + List attachments = new ArrayList<>(); + VolumeAttachment server = mock(VolumeAttachment.class); + attachments.add(server); + when(volume.getAttachments()).thenAnswer(x -> attachments); + when(server.getServerId()).thenReturn("vserverIdTest"); + + when(osClient.getVolumeById("5ad95036-8daf-4379-a59c-865f35976ca3")).thenReturn(volume); + + heatbridge.buildAddVolumes(stackResources); + + verify(transaction, times(1)).createIfNotExists( + eq(AAIUriFactory.createResourceUri(AAIFluentTypeBuilder.cloudInfrastructure() + .cloudRegion("CloudOwner", "RegionOne").tenant("7320ec4a5b9d4589ba7c4412ccfd290f") + .vserver("vserverIdTest").volume("5ad95036-8daf-4379-a59c-865f35976ca3"))), + any(Optional.class)); + verify(osClient, times(1)).getVolumeById(eq("5ad95036-8daf-4379-a59c-865f35976ca3")); + } + private List extractTestStackResources() { List stackResources = null; try { @@ -838,4 +861,5 @@ public class HeatBridgeImplTest { } + } diff --git a/adapters/mso-openstack-adapters/src/test/resources/stack-resources.json b/adapters/mso-openstack-adapters/src/test/resources/stack-resources.json index 6b63895a33..159c6665f2 100644 --- a/adapters/mso-openstack-adapters/src/test/resources/stack-resources.json +++ b/adapters/mso-openstack-adapters/src/test/resources/stack-resources.json @@ -436,6 +436,28 @@ "resource_status_reason": "state changed", "physical_resource_id": "5ad95036-8daf-4379-a59c-865f35976cd4", "resource_type": "OS::Neutron::Net" + }, + { + "resource_name": "volume", + "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": "some_id", + "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-865f35976ca3", + "resource_type": "OS::Cinder::Volume" } ] } -- cgit 1.2.3-korg