import org.openstack4j.model.compute.Image;
import org.openstack4j.model.compute.Server;
import org.openstack4j.model.heat.Resource;
+import org.openstack4j.model.network.Network;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
List<Resource> stackResources =
heatBridgeClient.queryNestedHeatStackResources(cloudInformation.getTemplateInstanceId());
+ List<Network> osNetworks = heatBridgeClient.getAllOpenstackProviderNetworks(stackResources);
+ heatBridgeClient.buildAddNetworksToAaiAction(cloudInformation.getVnfId(), cloudInformation.getVfModuleId(),
+ osNetworks);
+
List<Server> osServers = heatBridgeClient.getAllOpenstackServers(stackResources);
heatBridgeClient.createPserversAndPinterfacesIfNotPresentInAai(stackResources);
import org.openstack4j.model.compute.Image;
import org.openstack4j.model.compute.Server;
import org.openstack4j.model.heat.Resource;
+import org.openstack4j.model.network.Network;
/**
* Defines the contract to extract Heat Stack Resources from Openstack and inventory it to AAI. This API is used only to
*/
List<Server> getAllOpenstackServers(List<Resource> stackResources);
+ /**
+ * Query the Openstack provider network objects from the list of stack resources
+ *
+ * @param stackResources A list of stack based resources
+ * @return A list of Openstack Network objects
+ */
+ List<Network> getAllOpenstackProviderNetworks(final List<Resource> stackResources);
+
/**
* Extract Openstack Image objects from a a list of Server objects
*
*/
List<Flavor> extractOpenstackFlavorsFromServers(List<Server> servers);
+ /**
+ * Query and build AAI actions for Openstack Compute resources to AAI's l3-network objects with its subnets
+ *
+ * @param genericVnfId AAI generic-vnf-id
+ * @param vfModuleId AAI vf-module-id
+ * @param networks Openstack Network list
+ */
+ void buildAddNetworksToAaiAction(final String genericVnfId, final String vfModuleId, List<Network> networks);
+
/**
* Query and build AAI actions for Openstack Image resources to AAI's image objects
*
import org.onap.aai.domain.yang.Flavor;
import org.onap.aai.domain.yang.Image;
import org.onap.aai.domain.yang.L3InterfaceIpv4AddressList;
+import org.onap.aai.domain.yang.L3Network;
import org.onap.aai.domain.yang.LInterface;
import org.onap.aai.domain.yang.PInterface;
import org.onap.aai.domain.yang.Pserver;
+import org.onap.aai.domain.yang.Relationship;
+import org.onap.aai.domain.yang.RelationshipList;
import org.onap.aai.domain.yang.SriovPf;
import org.onap.aai.domain.yang.SriovPfs;
+import org.onap.aai.domain.yang.Subnets;
import org.onap.aai.domain.yang.SriovVf;
import org.onap.aai.domain.yang.SriovVfs;
import org.onap.aai.domain.yang.VfModule;
return serverIds.stream().map(serverId -> osClient.getServerById(serverId)).collect(Collectors.toList());
}
+ @Override
+ public List<Network> getAllOpenstackProviderNetworks(final List<Resource> stackResources) {
+ Objects.requireNonNull(osClient, ERR_MSG_NULL_OS_CLIENT);
+ // Filter Openstack Compute resources
+ List<String> providerNetworkIds =
+ extractStackResourceIdsByResourceType(stackResources, HeatBridgeConstants.OS_NEUTRON_PROVIDERNET);
+ return providerNetworkIds.stream().map(providerNetworkId -> osClient.getNetworkById(providerNetworkId))
+ .collect(Collectors.toList());
+ }
+
@Override
public List<org.openstack4j.model.compute.Image> extractOpenstackImagesFromServers(final List<Server> servers) {
Objects.requireNonNull(osClient, ERR_MSG_NULL_OS_CLIENT);
.filter(distinctByProperty(org.openstack4j.model.compute.Flavor::getId)).collect(Collectors.toList());
}
+ public void buildAddNetworksToAaiAction(final String genericVnfId, final String vfModuleId,
+ List<Network> networks) {
+ networks.forEach(network -> {
+ L3Network l3Network = aaiHelper.buildNetwork(network);
+ if (l3Network != null) {
+ l3Network.setSubnets(buildSunets(network));
+
+ RelationshipList relationshipList = new RelationshipList();
+ List<Relationship> relationships = relationshipList.getRelationship();
+
+ relationships.add(aaiHelper.getRelationshipToVfModule(genericVnfId, vfModuleId));
+ relationships.add(aaiHelper.getRelationshipToTenant(cloudOwner, cloudRegionId, tenantId));
+
+ l3Network.setRelationshipList(relationshipList);
+ transaction.createIfNotExists(
+ AAIUriFactory.createResourceUri(AAIObjectType.L3_NETWORK, l3Network.getNetworkId()),
+ Optional.of(l3Network));
+ }
+ });
+ }
+
@Override
public void buildAddImagesToAaiAction(final List<org.openstack4j.model.compute.Image> images)
throws HeatBridgeException {
return pserverMap;
}
+ private Subnets buildSunets(Network network) {
+ Subnets aaiSubnets = new Subnets();
+ List<String> subnetIds = network.getSubnets();
+
+ subnetIds.forEach(subnetId -> {
+ Subnet subnet = osClient.getSubnetById(subnetId);
+ org.onap.aai.domain.yang.Subnet aaiSubnet = aaiHelper.buildSubnet(subnet);
+ if (aaiSubnet != null) {
+ aaiSubnets.getSubnet().add(aaiSubnet);
+ }
+ });
+ return aaiSubnets;
+ }
+
private void createPServerIfNotExists(Map<String, Pserver> serverHostnames) {
for (Pserver pserver : serverHostnames.values()) {
AAIResourceUri uri = AAIUriFactory.createResourceUri(AAIObjectType.PSERVER, pserver.getHostname());
public static final Integer OS_DEFAULT_HEAT_NESTING = 5;
public static final String OS_SERVER_RESOURCE_TYPE = "OS::Nova::Server";
public static final String OS_PORT_RESOURCE_TYPE = "OS::Neutron::Port";
+ public static final String OS_NEUTRON_PROVIDERNET = "OS::Neutron::ProviderNet";
public static final String OS_SRIOV_PORT_TYPE = "direct";
public static final String OS_PCI_SLOT_KEY = "pci_slot";
public static final String OS_PHYSICAL_NETWORK_KEY = "physical_network";
public static final String AAI_VF_MODULE_ID = "vf-module.vf-module-id";
public static final String AAI_IMAGE = "image";
public static final String AAI_IMAGE_ID = "image.image-id";
+ public static final String AAI_TENANT = "tenant";
+ public static final String AAI_TENANT_ID = "tenant.tenant-id";
public static final String AAI_CLOUD_OWNER = "cloud-region.cloud-owner";
public static final String AAI_CLOUD_REGION_ID = "cloud-region.cloud-region-id";
public static final String AAI_FLAVOR = "flavor";
import org.apache.commons.lang3.StringUtils;
import org.onap.aai.domain.yang.Flavor;
import org.onap.aai.domain.yang.Image;
+import org.onap.aai.domain.yang.L3Network;
import org.onap.aai.domain.yang.PInterface;
import org.onap.aai.domain.yang.Pserver;
import org.onap.aai.domain.yang.Relationship;
import org.onap.aaiclient.client.aai.entities.uri.AAIUriFactory;
import org.onap.so.heatbridge.constants.HeatBridgeConstants;
import org.openstack4j.model.compute.Server;
+import org.openstack4j.model.network.Network;
import org.openstack4j.model.network.Port;
+import org.openstack4j.model.network.Subnet;
import com.google.common.base.Preconditions;
/**
return relationshipList;
}
+ public Relationship getRelationshipToVfModule(String vnfId, String vfModuleId) {
+ return buildRelationship(AAIUriFactory.createResourceUri(AAIObjectType.VF_MODULE, vnfId, vfModuleId));
+ }
+
+ public Relationship getRelationshipToTenant(String cloudOwner, String cloudRegionId, String tenantId) {
+ return buildRelationship(
+ AAIUriFactory.createResourceUri(AAIObjectType.TENANT, cloudOwner, cloudRegionId, tenantId));
+ }
+
+ public org.onap.aai.domain.yang.Subnet buildSubnet(Subnet subnet) {
+ org.onap.aai.domain.yang.Subnet aaiSubnet = new org.onap.aai.domain.yang.Subnet();
+ aaiSubnet.setSubnetId(subnet.getId());
+ aaiSubnet.setDhcpEnabled(subnet.isDHCPEnabled());
+
+ aaiSubnet.setSubnetName(subnet.getName());
+ aaiSubnet.setGatewayAddress(subnet.getGateway());
+ aaiSubnet.setCidrMask(subnet.getCidr());
+ aaiSubnet.setIpVersion(subnet.getIpVersion().name());
+ return aaiSubnet;
+ }
+
+ public L3Network buildNetwork(Network network) {
+ if (network.getId() == null) {
+ return null;
+ }
+ L3Network l3Network = new L3Network();
+ l3Network.setNetworkId(network.getId());
+ l3Network.setIsBoundToVpn(true);
+ l3Network.setIsProviderNetwork(true);
+
+ // optional fields
+ l3Network.setIsSharedNetwork(network.isShared());
+ l3Network.setIsExternalNetwork(network.isRouterExternal());
+ l3Network.setOperationalStatus(String.valueOf(network.isAdminStateUp()));
+ if (network.getName() != null) {
+ l3Network.setNetworkName(network.getName());
+ }
+ if (network.getProviderPhyNet() != null) {
+ l3Network.setPhysicalNetworkName(network.getProviderPhyNet());
+ }
+ return l3Network;
+ }
+
/**
* Transform Openstack Server object to AAI Vserver object
*
import org.openstack4j.model.compute.Server.Status;
import org.openstack4j.model.heat.Resource;
import org.openstack4j.model.network.IP;
+import org.openstack4j.model.network.IPVersionType;
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.openstack.heat.domain.HeatResource;
import org.openstack4j.openstack.heat.domain.HeatResource.Resources;
import org.springframework.core.env.Environment;
verify(osClient, times(10)).getNetworkById(anyString());
}
+ @Test
+ public void testUpdateNetworksToAai() throws HeatBridgeException {
+
+ Subnet subnet1 = mock(Subnet.class);
+ when(subnet1.getId()).thenReturn("test-subnet1-id");
+ when(subnet1.getName()).thenReturn("test-subnet1-name");
+ when(subnet1.isDHCPEnabled()).thenReturn(true);
+ when(subnet1.getGateway()).thenReturn("test-subnet1-gateway");
+ when(subnet1.getCidr()).thenReturn("test-subnet1-gateway");
+ when(subnet1.getIpVersion()).thenReturn(IPVersionType.V4);
+
+ Subnet subnet2 = mock(Subnet.class);
+ when(subnet2.getId()).thenReturn("test-subnet2-id");
+ when(subnet2.getName()).thenReturn("test-subnet2-name");
+ when(subnet2.isDHCPEnabled()).thenReturn(true);
+ when(subnet2.getGateway()).thenReturn("test-subnet1-gateway");
+ when(subnet2.getCidr()).thenReturn("test-subnet1-gateway");
+ when(subnet2.getIpVersion()).thenReturn(IPVersionType.V6);
+
+ when(osClient.getSubnetById(subnet1.getId())).thenReturn(subnet1);
+ when(osClient.getSubnetById(subnet2.getId())).thenReturn(subnet2);
+
+ List<String> subnetIds = Arrays.asList(subnet1.getId(), subnet2.getId());
+
+ // Arrange
+ Network network1 = mock(Network.class);
+ when(network1.getId()).thenReturn("test-network1-id");
+ when(network1.isShared()).thenReturn(true);
+ when(network1.isRouterExternal()).thenReturn(true);
+ when(network1.isAdminStateUp()).thenReturn(true);
+ when(network1.getProviderPhyNet()).thenReturn("sriov-network1");
+ when(network1.getName()).thenReturn("network1");
+ when(network1.getSubnets()).thenReturn(subnetIds);
+
+ Network network2 = mock(Network.class);
+ when(network2.getId()).thenReturn("test-network2-id");
+ when(network2.isShared()).thenReturn(true);
+ when(network2.isRouterExternal()).thenReturn(true);
+ when(network2.isAdminStateUp()).thenReturn(true);
+ when(network2.getProviderPhyNet()).thenReturn("sriov-network2");
+ when(network2.getName()).thenReturn("network2");
+ when(network2.getSubnets()).thenReturn(subnetIds);
+
+ String vnfId = "some-uuiid-of-the-vnf";
+ String vfModuleId = "some-uuiid-of-the-vf-module";
+
+ Subnet subnet = mock(Subnet.class);
+
+ List<Network> networks = Arrays.asList(network1, network2);
+
+ // Act #1
+ heatbridge.buildAddNetworksToAaiAction(vnfId, vfModuleId, networks);
+
+ // Assert #1
+ verify(transaction, times(2)).createIfNotExists(any(AAIResourceUri.class), any(Optional.class));
+
+ // Act #2
+ heatbridge.buildAddNetworksToAaiAction(vnfId, vfModuleId, networks);
+
+ // Assert #2
+ verify(transaction, times(4)).createIfNotExists(any(AAIResourceUri.class), any(Optional.class));
+
+ }
+
@Test
public void testUpdateVserverLInterfacesToAai_skipVlans() throws HeatBridgeException {
// Arrange