package org.onap.so.adapters.audit;
import java.net.URI;
+import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.onap.aai.domain.yang.LInterface;
import org.onap.aai.domain.yang.LInterfaces;
+import org.onap.aai.domain.yang.Vlan;
+import org.onap.aai.domain.yang.Vlans;
import org.onap.aai.domain.yang.Vserver;
import org.onap.so.openstack.utils.MsoHeatUtils;
+import org.onap.so.openstack.utils.MsoNeutronUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import com.woorea.openstack.heat.model.Resource;
import com.woorea.openstack.heat.model.Resources;
import com.woorea.openstack.heat.model.Stack;
+import com.woorea.openstack.quantum.model.Port;
@Component
public class HeatStackAudit {
@Autowired
protected MsoHeatUtils heat;
+
+ @Autowired
+ protected MsoNeutronUtils neutron;
@Autowired
protected AuditVServer auditVservers;
- public boolean auditHeatStack(String cloudRegion, String cloudOwner, String tenantId, String heatStackName) {
+ public Optional<AAIObjectAuditList> auditHeatStack(String cloudRegion, String cloudOwner, String tenantId, String heatStackName) {
try {
logger.debug("Fetching Top Level Stack Information");
Resources resources = heat.queryStackResources(cloudRegion, tenantId, heatStackName);
List<Resource> novaResources = resources.getList().stream()
.filter(p -> "OS::Nova::Server".equals(p.getType())).collect(Collectors.toList());
List<Resource> resourceGroups = resources.getList().stream()
- .filter(p -> "OS::Heat::ResourceGroup".equals(p.getType()) && p.getName().contains("subinterfaces")).collect(Collectors.toList());
- Set<Vserver> vserversToAudit = createVserverSet(resources, novaResources);
- Set<Vserver> vserversWithSubInterfaces = processSubInterfaces(cloudRegion, tenantId, resourceGroups,
- vserversToAudit);
- return auditVservers.auditVservers(vserversWithSubInterfaces, tenantId, cloudOwner, cloudRegion);
+ .filter(p -> "OS::Heat::ResourceGroup".equals(p.getType()) && p.getName().contains("subinterfaces"))
+ .collect(Collectors.toList());
+ List<Optional<Port>> neutronPortDetails = retrieveNeutronPortDetails(resources, cloudRegion, tenantId);
+ if (novaResources.isEmpty())
+ return Optional.of(new AAIObjectAuditList());
+ else {
+ Set<Vserver> vserversToAudit = createVserverSet(resources, novaResources, neutronPortDetails);
+ Set<Vserver> vserversWithSubInterfaces = processSubInterfaces(cloudRegion, tenantId, resourceGroups,
+ vserversToAudit);
+ return auditVservers.auditVservers(vserversWithSubInterfaces,
+ tenantId, cloudOwner, cloudRegion);
+ }
} catch (Exception e) {
logger.error("Error during auditing stack resources", e);
- return false;
+ return Optional.empty();
}
- }
+ }
protected Set<Vserver> processSubInterfaces(String cloudRegion, String tenantId, List<Resource> resourceGroups,
Set<Vserver> vServersToAudit) throws Exception {
logger.error("Error Parsing Link to obtain Path", e);
throw new Exception("Error finding Path from Self Link");
}
-
}
}
}
LInterface subInterface = new LInterface();
subInterface.setInterfaceId(contrailVm.getPhysicalResourceId());
+ subInterface.setIsPortMirrored(false);
+ subInterface.setInMaint(false);
+ subInterface.setIsIpUnnumbered(false);
+ String macAddr = (String) subinterfaceStack.getParameters().get("mac_address");
+ subInterface.setMacaddr(macAddr);
+ String namePrefix = (String) subinterfaceStack.getParameters().get("subinterface_name_prefix");
+ Integer vlanIndex = Integer.parseInt((String) subinterfaceStack.getParameters().get("counter"));
+ String vlanTagList = (String) subinterfaceStack.getParameters().get("vlan_tag");
+ List<String> subInterfaceVlanTagList = Arrays.asList(vlanTagList.split(","));
+ subInterface.setInterfaceName(namePrefix+"_"+subInterfaceVlanTagList.get(vlanIndex));
+ subInterface.setVlans(new Vlans());
+ Vlan vlan = new Vlan();
+ vlan.setInMaint(false);
+ vlan.setIsIpUnnumbered(false);
+ vlan.setVlanIdInner(Long.parseLong(subInterfaceVlanTagList.get(vlanIndex)));
+ vlan.setVlanInterface(namePrefix+"_"+subInterfaceVlanTagList.get(vlanIndex));
+ subInterface.getVlans().getVlan().add(vlan);
if(lInterface.getLInterfaces() == null)
lInterface.setLInterfaces(new LInterfaces());
lInterface.getInterfaceId(),subinterfaceStack.getId());
}
- protected Set<Vserver> createVserverSet(Resources resources, List<Resource> novaResources) {
+ protected Set<Vserver> createVserverSet(Resources resources, List<Resource> novaResources, List<Optional<Port>> neutronPortDetails) {
Set<Vserver> vserversToAudit = new HashSet<>();
for (Resource novaResource : novaResources) {
Vserver auditVserver = new Vserver();
auditVserver.setLInterfaces(new LInterfaces());
- auditVserver.setVserverId(novaResource.getPhysicalResourceId());
- Stream<Resource> filteredNeutronNetworks = resources.getList().stream()
- .filter(network -> network.getRequiredBy().contains(novaResource.getLogicalResourceId()));
- filteredNeutronNetworks.forEach(network -> {
+ auditVserver.setVserverId(novaResource.getPhysicalResourceId());
+ Stream<Port> filteredNeutronPorts = filterNeutronPorts(novaResource, neutronPortDetails);
+ filteredNeutronPorts.forEach(port -> {
LInterface lInterface = new LInterface();
- lInterface.setInterfaceId(network.getPhysicalResourceId());
+ lInterface.setInterfaceId(port.getId());
+ lInterface.setInterfaceName(port.getName());
auditVserver.getLInterfaces().getLInterface().add(lInterface);
});
vserversToAudit.add(auditVserver);
return vserversToAudit;
}
- protected Optional<String> extractResourcePathFromHref(String href) {
- URI uri;
+ /**
+ * @param novaResource Single openstack resource that is of type Nova
+ * @param neutronPorts List of Neutron ports created within the stack
+ * @return Filtered list of neutron ports taht relate to the nova server in openstack
+ */
+ protected Stream<Port> filterNeutronPorts(Resource novaResource, List<Optional<Port>> neutronPorts) {
+ List<Port> filteredNeutronPorts = neutronPorts.stream().filter(Optional::isPresent).map(Optional::get)
+ .collect(Collectors.toList());
+ return filteredNeutronPorts.stream()
+ .filter(port -> port.getDeviceId().equalsIgnoreCase(novaResource.getPhysicalResourceId()));
+ }
+
+ /**
+ * @param resources Resource stream created by the stack in openstack
+ * @param cloudSiteId Unique site id to identify which openstack we talk to
+ * @param tenantId The tenant within the cloud we are talking to where resouces exist
+ * @return List of optional neutron ports found within the cloud site and tenant
+ */
+ protected List<Optional<Port>> retrieveNeutronPortDetails(Resources resources,String cloudSiteId,String tenantId){
+ return resources.getList().parallelStream()
+ .filter(resource -> "OS::Neutron::Port".equals(resource.getType()))
+ .map(resource -> neutron.getNeutronPort(resource.getPhysicalResourceId(),tenantId,cloudSiteId)).collect(Collectors.toList());
+
+ }
+
+ protected Optional<String> extractResourcePathFromHref(String href) {
try {
- uri = new URI(href);
- return Optional.of(uri.getPath().replaceFirst("/v\\d+", "")+RESOURCES);
+ Optional<String> stackPath = extractStackPathFromHref(href);
+ if (stackPath.isPresent()){
+ return Optional.of(stackPath.get()+RESOURCES);
+ }else
+ return Optional.empty();
} catch (Exception e) {
logger.error("Error parsing URI", e);
}
}
protected Optional<String> extractStackPathFromHref(String href) {
- URI uri;
try {
- uri = new URI(href);
- return Optional.of(uri.getPath().replaceFirst("/v\\d+", ""));
+ URI uri = new URI(href);
+ Pattern p = Pattern.compile("/stacks.*");
+ Matcher m = p.matcher(uri.getPath());
+ if (m.find()){
+ return Optional.of(m.group());
+ }else
+ return Optional.empty();
} catch (Exception e) {
logger.error("Error parsing URI", e);
}
}
+