/** * Abiquo community edition * cloud management application for hybrid clouds * Copyright (C) 2008-2010 - Abiquo Holdings S.L. * * This application is free software; you can redistribute it and/or * modify it under the terms of the GNU LESSER GENERAL PUBLIC * LICENSE as published by the Free Software Foundation under * version 3 of the License * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * LESSER GENERAL PUBLIC LICENSE v.3 for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ package com.abiquo.abiserver.model.ovf; import java.math.BigInteger; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import javax.xml.namespace.QName; import org.dmtf.schemas.ovf.envelope._1.AbicloudNetworkType; import org.dmtf.schemas.ovf.envelope._1.AnnotationSectionType; import org.dmtf.schemas.ovf.envelope._1.ContentType; import org.dmtf.schemas.ovf.envelope._1.DHCPOption; import org.dmtf.schemas.ovf.envelope._1.DHCPOptions; import org.dmtf.schemas.ovf.envelope._1.DHCPServiceType; import org.dmtf.schemas.ovf.envelope._1.EnvelopeType; import org.dmtf.schemas.ovf.envelope._1.FileType; import org.dmtf.schemas.ovf.envelope._1.IpPoolType; import org.dmtf.schemas.ovf.envelope._1.NetworkSectionType; import org.dmtf.schemas.ovf.envelope._1.NetworkSectionType.Network; import org.dmtf.schemas.ovf.envelope._1.OrgNetworkType; import org.dmtf.schemas.ovf.envelope._1.RASDType; import org.dmtf.schemas.ovf.envelope._1.ReferencesType; import org.dmtf.schemas.ovf.envelope._1.VSSDType; import org.dmtf.schemas.ovf.envelope._1.VirtualDiskDescType; import org.dmtf.schemas.ovf.envelope._1.VirtualHardwareSectionType; import org.dmtf.schemas.ovf.envelope._1.VirtualSystemCollectionType; import org.dmtf.schemas.ovf.envelope._1.VirtualSystemType; import org.dmtf.schemas.wbem.wscim._1.cim_schema._2.cim_resourceallocationsettingdata.CIMResourceAllocationSettingDataType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.abiquo.abiserver.abicloudws.AbiCloudConstants; import com.abiquo.abiserver.business.hibernate.pojohb.authorization.OneTimeTokenSessionHB; import com.abiquo.abiserver.business.hibernate.pojohb.infrastructure.HypervisorHB; import com.abiquo.abiserver.business.hibernate.pojohb.infrastructure.StateEnum; import com.abiquo.abiserver.business.hibernate.pojohb.networking.DhcpOptionHB; import com.abiquo.abiserver.business.hibernate.pojohb.networking.IpPoolManagementHB; import com.abiquo.abiserver.business.hibernate.pojohb.networking.VlanNetworkHB; import com.abiquo.abiserver.business.hibernate.pojohb.service.RemoteServiceHB; import com.abiquo.abiserver.business.hibernate.pojohb.service.RemoteServiceType; import com.abiquo.abiserver.business.hibernate.pojohb.virtualappliance.NodeHB; import com.abiquo.abiserver.business.hibernate.pojohb.virtualappliance.NodeVirtualImageHB; import com.abiquo.abiserver.business.hibernate.pojohb.virtualappliance.VirtualappHB; import com.abiquo.abiserver.business.hibernate.pojohb.virtualappliance.VirtualmachineHB; import com.abiquo.abiserver.business.hibernate.pojohb.virtualhardware.ResourceAllocationSettingData; import com.abiquo.abiserver.business.hibernate.pojohb.virtualhardware.ResourceManagementHB; import com.abiquo.abiserver.config.AbiConfigManager; import com.abiquo.abiserver.exception.PersistenceException; import com.abiquo.abiserver.networking.NetworkResolver; import com.abiquo.abiserver.persistence.DAOFactory; import com.abiquo.abiserver.persistence.dao.infrastructure.DataCenterDAO; import com.abiquo.abiserver.persistence.dao.infrastructure.RemoteServiceDAO; import com.abiquo.abiserver.persistence.dao.networking.VlanNetworkDAO; import com.abiquo.abiserver.persistence.dao.virtualappliance.VirtualApplianceDAO; import com.abiquo.abiserver.persistence.dao.virtualappliance.VirtualMachineDAO; import com.abiquo.abiserver.persistence.hibernate.HibernateDAOFactory; import com.abiquo.abiserver.pojo.infrastructure.Datastore; import com.abiquo.abiserver.pojo.infrastructure.HyperVisor; import com.abiquo.abiserver.pojo.infrastructure.PhysicalMachine; import com.abiquo.abiserver.pojo.infrastructure.Rack; import com.abiquo.abiserver.pojo.infrastructure.State; import com.abiquo.abiserver.pojo.infrastructure.VirtualMachine; import com.abiquo.abiserver.pojo.virtualappliance.Node; import com.abiquo.abiserver.pojo.virtualappliance.NodeVirtualImage; import com.abiquo.abiserver.pojo.virtualappliance.VirtualAppliance; import com.abiquo.abiserver.pojo.virtualimage.VirtualImage; import com.abiquo.abiserver.pojo.virtualimage.VirtualImageConversions; import com.abiquo.abiserver.pojo.virtualimage.VirtualImageDecorator; import com.abiquo.model.enumerator.HypervisorType; import com.abiquo.model.enumerator.NetworkType; import com.abiquo.ovfmanager.cim.CIMResourceAllocationSettingDataUtils; import com.abiquo.ovfmanager.cim.CIMTypesUtils.CIMResourceTypeEnum; import com.abiquo.ovfmanager.cim.CIMVirtualSystemSettingDataUtils; import com.abiquo.ovfmanager.ovf.OVFEnvelopeUtils; import com.abiquo.ovfmanager.ovf.OVFReferenceUtils; import com.abiquo.ovfmanager.ovf.exceptions.EmptyEnvelopeException; import com.abiquo.ovfmanager.ovf.exceptions.IdAlreadyExistsException; import com.abiquo.ovfmanager.ovf.exceptions.RequiredAttributeException; import com.abiquo.ovfmanager.ovf.exceptions.SectionException; import com.abiquo.ovfmanager.ovf.exceptions.SectionNotPresentException; import com.abiquo.ovfmanager.ovf.section.DiskFormat; import com.abiquo.ovfmanager.ovf.section.OVFDiskUtils; import com.abiquo.ovfmanager.ovf.section.OVFNetworkUtils; import com.abiquo.ovfmanager.ovf.section.OVFVirtualHadwareSectionUtils; public class OVFModelFromVirtualAppliance { private final static Logger logger = LoggerFactory .getLogger(OVFModelFromVirtualAppliance.class); // /////////// InfrastructureWS public EnvelopeType changeMachineState(final VirtualMachine virtualMachine, final String machineState, final List<ResourceAllocationSettingData> additionalRasds) throws Exception { EnvelopeType envelope = null; try { // Creates an OVF envelope from the virtual machine parameters envelope = constructEnvelopeType(virtualMachine, machineState, additionalRasds); } catch (RequiredAttributeException e) { // virtual system creation (require id) } catch (SectionException e) { // addSections into virtual system (just created) } catch (IdAlreadyExistsException e) { // addVirtual system (envelope just created) } return envelope; } /** * Private helper to construct an OVF envelope form the basic parameters on the virtual machine * * @param virtualMachine * @param machineState TODO * @return an OVFEnvelope with the information contained on the virtualMachine * @throws Exception, if the virtualMachine can not be represented as an OVF document. */ public EnvelopeType constructEnvelopeType(final VirtualMachine virtualMachine, final String machineState, final List<ResourceAllocationSettingData> additionalRasds) throws Exception { EnvelopeType envelope = new EnvelopeType(); ReferencesType references = new ReferencesType(); String instanceId = virtualMachine.getUUID(); String machineName = virtualMachine.getName(); VirtualImage virtualImage = virtualMachine.getVirtualImage(); try { // Create NetworkSection and Network and add to Envelope NetworkSectionType netSection = OVFEnvelopeUtils.createSection(NetworkSectionType.class, null); Network net = OVFNetworkUtils.createNetwork(virtualMachine.getName() + "_network", "Appliance Network identifier"); OVFNetworkUtils.addNetwork(netSection, net); // Set the network section on the envelope OVFEnvelopeUtils.addSection(envelope, netSection); // Add the custom network. Can be null if we are deleting the node from the VirtualApp // with an update nodes operation AbicloudNetworkType customNetwork = createCustomNetwork(virtualMachine.getId()); if (customNetwork != null) { OVFEnvelopeUtils.addSection(envelope, customNetwork); } // The Id of the virtualSystem is used for machine name VirtualSystemType virtualSystem = OVFEnvelopeUtils.createVirtualSystem(instanceId, machineName, null); // There is only one virtual base disk VirtualHardwareSectionType hardwareSection = createVirtualSystemSection(virtualMachine, virtualImage, null, 0, additionalRasds); // Configure AnnotationSection with the RD port AnnotationSectionType annotationSection = createVirtualSystemRDPortAnnotationSection(virtualMachine); if (machineState != null) { annotationSection.getOtherAttributes().put(AbiCloudConstants.machineStateQname, machineState); } // OVFEnvelopeUtils.addSection(virtualSystem, productSection); OVFEnvelopeUtils.addSection(virtualSystem, hardwareSection); OVFEnvelopeUtils.addSection(virtualSystem, annotationSection); // Setting the virtual Disk package level element to the envelope VirtualDiskDescType virtualDisk = createDiskFromVirtualImage(virtualMachine, virtualImage, "0"); OVFDiskUtils.addDisk(envelope, virtualDisk); OVFReferenceUtils.addFile(references, createFileFromVirtualImage(virtualImage, virtualMachine, false, false)); // Setting the virtual system as envelope content OVFEnvelopeUtils.addVirtualSystem(envelope, virtualSystem); envelope.setReferences(references); } catch (Exception e) // RequiredAttributeException(vs creation) and SectionException { String msg = String .format( "The envelope can not be created for the virtual machine [%s] (%s) : \n cause by : %s", instanceId, machineName, e.toString()); logger.error(msg); throw new Exception(msg, e); } return envelope; } /** * Gets the target datastore fully qualified path for deploying purposes * * @param datastore the datastore to deploy * @param hypervisorType the hypervisor type * @return */ public String getDatastoreForDeployedByHypervisorType(final Datastore datastore, final String hypervisorType) { if (HypervisorType.HYPERV_301.getValue().equalsIgnoreCase(hypervisorType) || HypervisorType.KVM.getValue().equalsIgnoreCase(hypervisorType) || HypervisorType.XEN_3.getValue().equalsIgnoreCase(hypervisorType)) { return datastore.getUUID() + datastore.getDirectory(); } else { return datastore.getUUID(); } } /** * Private helper to get the virtual machine state * * @param virtualMachine * @return */ public static String getActualState(final VirtualMachine virtualMachine) { String state = null; switch (virtualMachine.getState().toEnum()) { case ON: state = AbiCloudConstants.POWERUP_ACTION; break; case PAUSED: state = AbiCloudConstants.PAUSE_ACTION; break; case OFF: state = AbiCloudConstants.POWERDOWN_ACTION; break; // case REBOOTED: // state = AbiCloudConstants.RESUME_ACTION; // break; } return state; } private static String codifyRepositoryAndPath(final String imagePath, final String repository) { // TODO EBS when the path is formed by IP|IQN avoid using the repository and just the path String codify = null; if (imagePath.indexOf("|") != -1) { codify = imagePath; } else { // Not managed images don't have repository if (repository == null) { if (imagePath.indexOf("[") != -1) { codify = imagePath; } else { codify = "[null]" + imagePath; } } else { codify = '[' + repository + ']' + imagePath; } } /** * TODO replace protocol form the repository */ logger.info("Using repository [{}] and imagepath [{}]", repository, imagePath); logger.info("Codify ''{}''", codify); return codify; } /************************** * VirtualApplianceWS *********/ /** * Private helper to create a virtual appliance * * @param virtualAppliance * @return * @throws Exception */ public EnvelopeType createVirtualApplication(final VirtualAppliance virtualAppliance) throws Exception { return createVirtualApplication(virtualAppliance, false); } public EnvelopeType createVirtualApplication(final VirtualAppliance virtualAppliance, final boolean bundling) throws Exception { return createVirtualApplication(virtualAppliance, bundling, false); } public EnvelopeType createVirtualApplicationHA(final VirtualAppliance virtualAppliance) throws Exception { return createVirtualApplication(virtualAppliance, false, true); } private EnvelopeType createVirtualApplication(final VirtualAppliance virtualAppliance, final boolean bundling, final boolean isHa) throws Exception { // Create an OVF envelope EnvelopeType envelope = new EnvelopeType(); // Using the name as the virtual System Id String vscId = String.valueOf(virtualAppliance.getId()); VirtualSystemCollectionType virtualSystemCollection = OVFEnvelopeUtils.createVirtualSystemCollection(vscId, null, null); // TODO info and name // Creating the references element ReferencesType references = new ReferencesType(); // Creating the virtual Disk package level element // DiskSectionType diskSectionTypePackage = // OVFEnvelopeUtils.createSection(DiskSectionType.class, null); // Create NetworkSection and Network and add to Envelope NetworkSectionType netSection = OVFEnvelopeUtils.createSection(NetworkSectionType.class, null); Network net = OVFNetworkUtils.createNetwork(virtualAppliance.getName() + "_network", "Appliance Network identifier"); OVFNetworkUtils.addNetwork(netSection, net); // set the network section on the envelope OVFEnvelopeUtils.addSection(envelope, netSection); // Add the custom network AbicloudNetworkType customNetwork = createCustomNetwork(virtualAppliance); OVFEnvelopeUtils.addSection(envelope, customNetwork); // Getting the all the virtual Machines for (Node node : virtualAppliance.getNodes()) { if (node.isNodeTypeVirtualImage()) { NodeVirtualImage nodeVirtualImage = (NodeVirtualImage) node; StateEnum vmState = nodeVirtualImage.getVirtualMachine().getState().toEnum(); // Creates the virtual system inside the virtual system collection VirtualSystemType virtualSystem = createVirtualSystem(nodeVirtualImage, virtualAppliance); OVFEnvelopeUtils.addVirtualSystem(virtualSystemCollection, virtualSystem); // Setting the virtual Disk package level element to the envelope String diskId = String.valueOf(nodeVirtualImage.getId()); VirtualDiskDescType virtualDisk = createDiskFromVirtualImage(nodeVirtualImage.getVirtualMachine(), nodeVirtualImage.getVirtualImage(), diskId); OVFDiskUtils.addDisk(envelope, virtualDisk); // Adding the virtual disks to references try { OVFReferenceUtils.addFile( references, createFileFromVirtualImage(nodeVirtualImage.getVirtualImage(), nodeVirtualImage.getVirtualMachine(), bundling, isHa)); } catch (IdAlreadyExistsException e) { // If there is already a disk reference of a file, that means two machine are // pointing // at the same disk, which reference is already inserted in the OVF. So, in this // case, // an 'IdAlreadyExistsException' is not problematic logger.trace("File Reference already inserted"); } } else // not nodevirtualimage { // TODO warn or error } }// for each node on the appliance // Adding the virtual System collection to the envelope OVFEnvelopeUtils.addVirtualSystem(envelope, virtualSystemCollection); // Adding the references to the envelope envelope.setReferences(references); return envelope; } private static AbicloudNetworkType createCustomNetwork(final Integer idVirtualMachine) throws Exception { DAOFactory factory = HibernateDAOFactory.instance(); VirtualMachineDAO vmDAO = factory.getVirtualMachineDAO(); VlanNetworkDAO vlanDAO = factory.getVlanNetworkDAO(); DataCenterDAO dcDAO = factory.getDataCenterDAO(); factory.beginConnection(); VirtualmachineHB vmHB = vmDAO.findById(idVirtualMachine); // [ABICLOUDPREMIUM-1731] If we are removing the VM with an update nodes operation, the VM // will not exist in DB. We return null to ignore the network section (it is not needed to // delete the node). if (vmHB == null) { return null; } Map<Integer, List<IpPoolManagementHB>> vlansConfig = new HashMap<Integer, List<IpPoolManagementHB>>(); AbicloudNetworkType networkType = new AbicloudNetworkType(); // Build the Map of vlans with the IPs used by the VM for (ResourceManagementHB rasman : vmHB.getResman()) { if (rasman instanceof IpPoolManagementHB) { IpPoolManagementHB ipman = (IpPoolManagementHB) rasman; if (networkType.getUuid() == null) { networkType.setUuid(ipman.getVirtualDataCenter().getNetwork().getUuid()); } Integer vlanId = ipman.getVlanNetworkId(); List<IpPoolManagementHB> vlanIPs = vlansConfig.get(vlanId); if (vlanIPs == null) { vlanIPs = new LinkedList<IpPoolManagementHB>(); } vlanIPs.add(ipman); vlansConfig.put(vlanId, vlanIPs); } } for (Map.Entry<Integer, List<IpPoolManagementHB>> vlanConfig : vlansConfig.entrySet()) { Integer vlanId = vlanConfig.getKey(); List<IpPoolManagementHB> ips = vlanConfig.getValue(); Integer numberOfRules = 0; OrgNetworkType vlan = vlanDAO.findById(vlanId); VlanNetworkHB vlanHB = (VlanNetworkHB) vlan; DHCPOptions options = new DHCPOptions(); Set<DhcpOptionHB> optionsHB = vlanHB.getDhcpOptionsHB(); for (DhcpOptionHB opHB : optionsHB) { DHCPOption option = new DHCPOption(); option.setValue(NetworkResolver.getDhcpOption(opHB.getNetworkAddress(), opHB.getMask(), opHB.getGateway())); option.setOpt(opHB.getOption()); options.getOption().add(option); } vlan.setDhcpOptions(options); Integer idDataCenter = null; if (vlanHB.getNetworkType().equals(NetworkType.INTERNAL.name())) { idDataCenter = dcDAO.getDatacenterWhereThePrivateNetworkStays(vlanHB.getNetworkId()) .getIdDataCenter(); } else { idDataCenter = dcDAO.getDatacenterWhereThePublicNetworkStays(vlanHB.getNetworkId()) .getIdDataCenter(); } DHCPServiceType service = new DHCPServiceType(); if (idDataCenter != null) { RemoteServiceDAO rmDAO = factory.getRemoteServiceDAO(); List<RemoteServiceHB> remo = rmDAO.getRemoteServicesByType(idDataCenter, RemoteServiceType.DHCP_SERVICE); if (remo.size() != 0) { service.setDhcpAddress(remo.get(0).getURI().getHost()); service.setDhcpPort(remo.get(0).getURI().getPort()); vlan.getConfiguration().setDhcpService(service); } } // Pass all the IpPoolManagement to IpPoolType if the virtual machine is assigned. for (IpPoolManagementHB ip : ips) { IpPoolType rule = new IpPoolType(); rule.setConfigureGateway(ip.getConfigureGateway()); rule.setIp(ip.getIp()); rule.setMac(ip.getMac()); rule.setName(ip.getName()); // Configure bootstrap for the gateway-enabled NIC if (ip.getConfigureGateway()) { addBootstrapConfiguration(ip.getVirtualDataCenter().getIdVirtualDataCenter(), ip.getVirtualApp().getIdVirtualApp(), vmHB, rule); } service.getStaticRules().add(rule); numberOfRules++; } if (numberOfRules > 0 && !vlanHB.getNetworkType().equals(NetworkType.UNMANAGED.name())) { networkType.getNetworks().add(vlan); } } factory.endConnection(); return networkType; } /** * Helper method to createVirtualApplication - Adds the CustomNetwork to the EnvelopeType * * @param envelope a reference to an EnvelopeType object to which the CustomNetwork section will * be added * @param virtualAppliance a VirtualAppliance object which may or may not have a network * @throws Exception */ private static AbicloudNetworkType createCustomNetwork(final VirtualAppliance virtualAppliance) throws Exception { DAOFactory factory = HibernateDAOFactory.instance(); factory.beginConnection(); VirtualApplianceDAO vappDAO = factory.getVirtualApplianceDAO(); VirtualappHB persistedVapp = vappDAO.findByIdNamedExtended(virtualAppliance.getId()); factory.endConnection(); AbicloudNetworkType networkType = new AbicloudNetworkType(); for (NodeHB< ? > nodeHB : persistedVapp.getNodesHB()) { NodeVirtualImageHB nvi = (NodeVirtualImageHB) nodeHB; AbicloudNetworkType vmNetwork = createCustomNetwork(nvi.getVirtualMachineHB().getIdVm()); if (networkType.getUuid() == null) { networkType.setUuid(vmNetwork.getUuid()); } networkType.getNetworks().addAll(vmNetwork.getNetworks()); } return networkType; } private FileType createFileFromVirtualImage(final VirtualImage virtualImage, final VirtualMachine virtualMachine, final boolean bundling, final boolean isHa) throws RequiredAttributeException { String imagePath = null; String fileId = virtualImage.getName() + "." + virtualMachine.getId(); if (virtualImage instanceof VirtualImageDecorator) { VirtualImageDecorator virtualImageDecorated = (VirtualImageDecorator) virtualImage; imagePath = virtualImageDecorated.getBasePath(); fileId += "." + virtualImageDecorated.getPath(); } else { imagePath = virtualImage.getPath(); } // Combining the repository path + the virtual machine relative path (TODO AM) String imageRepository = null; if (virtualImage.getRepository() != null) { imageRepository = virtualImage.getRepository().getURL(); } // TODO bundle fail! if (!bundling) { VirtualImageConversions conversion = virtualMachine.getConversion(); if (conversion != null) { imagePath = conversion.getTargetPath(); } } imagePath = processImagePath(virtualMachine, virtualImage, imagePath); String absolutePath = codifyRepositoryAndPath(imagePath, imageRepository); /* * nodeVirtualImage.getVirtualImage().getRepository().getURL() + * nodeVirtualImage.getVirtualImage().getPath(); */ BigInteger fileSize = null; // TODO required fileSize FileType virtualDiskImageFile = OVFReferenceUtils.createFileType(fileId, absolutePath, fileSize, null, null); // TODO insertTargetDataStore(virtualDiskImageFile, virtualMachine.getDatastore().getUUID() + virtualMachine.getDatastore().getDirectory()); if (isHa) { setHA(virtualDiskImageFile); } // compression // chunk VirtualImageDecorator decorator = virtualImage instanceof VirtualImageDecorator ? (VirtualImageDecorator) virtualImage : VirtualImageDecorator.createDecorator(virtualImage); String path = null; String name = null; boolean isManaged = true; if (!virtualImage.isManaged()) { name = decorator.getNotManagedBundleName(); path = decorator.getNotManagedBundlePath() + "/" + name; virtualImage.setPath(path); virtualImage.setName(name); isManaged = false; } else { name = decorator.getName(); path = decorator.getPath(); isManaged = true; } virtualDiskImageFile.getOtherAttributes().put(new QName("destinationPath"), path); virtualDiskImageFile.getOtherAttributes().put(new QName("isManaged"), String.valueOf(isManaged)); insertRepositoryManager(virtualDiskImageFile, virtualMachine); return virtualDiskImageFile; } /** * In case of HA create/delete operation a new custom parameter is set on the Disk Element to * indicate do not execute any operation to copy/remove the disk from the target datastore. */ private static void setHA(final FileType virtualDiskImageFile) { virtualDiskImageFile.getOtherAttributes().put(AbiCloudConstants.HA_DISK, Boolean.TRUE.toString()); } /** * Override to perform custom image path processing. * * @param nodeVirtualImage The Virtual image being processed. * @param imagePath The computed path of the virtual image. * @throws RequiredAttributeException If an error occurs. */ protected String processImagePath(final VirtualMachine virtualMachine, final VirtualImage virtualImage, final String imagePath) throws RequiredAttributeException { return imagePath; } /** * Private helper to insert in the FileType the dataStore attribute * * @param virtualDiskImageFile the file type ovf section * @param dataStore the datastore attribute to insert */ private static void insertTargetDataStore(final FileType virtualDiskImageFile, final String dataStore) { virtualDiskImageFile.getOtherAttributes().put(AbiCloudConstants.DATASTORE_QNAME, dataStore); } private static VirtualDiskDescType createDiskFromVirtualImage( final VirtualMachine virtualMachine, final VirtualImage virtualImage, final String diskId) { String fileRef = virtualImage.getName() + "." + virtualMachine.getId(); if (virtualImage instanceof VirtualImageDecorator) { VirtualImageDecorator decorator = (VirtualImageDecorator) virtualImage; fileRef += "." + decorator.getPath(); } DiskFormat format; if (virtualMachine.getConversion() != null) { format = DiskFormat.fromValue(virtualMachine.getConversion().getDiskTargetFormatType() .getUri()); } else { format = DiskFormat.fromValue(virtualImage.getDiskFormatType().getUri()); } Long capacity = virtualImage.getHdRequired(); Long populate = virtualImage.getHdRequired(); // TODO required (using the fileSize + disk // format it can be computed) // // Adding the virtual Disks to the package level element VirtualDiskDescType virtualDescTypePackage = OVFDiskUtils.createDiskDescription("disk_" + diskId, fileRef, format, capacity, null, populate, null); // TODO unit, parent, return virtualDescTypePackage; } /** * Private helper to create a Virtual System * * @param virtualMachine the virtual machine to create the virtual system from * @param virtualImage ther virtual image to create the virtual system from * @return * @throws Exception */ public VirtualSystemType createVirtualSystem(final NodeVirtualImage nodeVirtualImage, final VirtualAppliance virtualAppliance) throws Exception { VirtualMachine virtualMachine = nodeVirtualImage.getVirtualMachine(); VirtualImage virtualImage = nodeVirtualImage.getVirtualImage(); // setting the network name the name of the virtualAppliance String networkName = virtualAppliance.getName() + "_network"; // The Id of the virtualSystem is used for machine name String vsId = virtualMachine.getUUID(); // TODO Using the machine instance UUID as ID VirtualSystemType virtualSystem = OVFEnvelopeUtils.createVirtualSystem(vsId, virtualMachine.getName(), nodeVirtualImage.getName()); // Create a productSection with the virtual system IP // ProductSectionType productSection = // createVirtualSystemMACOnProductSection(nodeVirtualImage); // Configure CPU, RAM and Network // NodeVirtualImage is a temporal attribute!!! VirtualHardwareSectionType hardwareSection = createVirtualSystemSection(virtualMachine, virtualImage, networkName, nodeVirtualImage.getId(), null); // Configure AnnotationSection with the RD port and password AnnotationSectionType annotationSection = createVirtualSystemRDPortAnnotationSection(virtualMachine); // OVFEnvelopeUtils.addSection(virtualSystem, productSection); OVFEnvelopeUtils.addSection(virtualSystem, hardwareSection); OVFEnvelopeUtils.addSection(virtualSystem, annotationSection); return virtualSystem; } private static AnnotationSectionType createVirtualSystemRDPortAnnotationSection( final VirtualMachine virtualMachine) { // TODO OVFEnvelopeUtils.createSection(AnnotationSectionType.class, null); AnnotationSectionType annotationSection = new AnnotationSectionType(); Map<QName, String> otherAttributes = annotationSection.getOtherAttributes(); String rdPort = String.valueOf(virtualMachine.getVdrpPort()); otherAttributes.put(AbiCloudConstants.remoteDesktopPortQname, String.valueOf(rdPort)); logger.debug("The remote desktop port included is: " + String.valueOf(rdPort)); if (virtualMachine.getPassword() != null && !virtualMachine.getPassword().equals("")) { String rdPassword = virtualMachine.getPassword(); otherAttributes.put(AbiCloudConstants.remoteDesktopPasswordQname, rdPassword); logger.debug("The remote desktop password is: " + rdPassword); } return annotationSection; } private static void addBootstrapConfiguration(final Integer idVirtualdatacenter, final Integer idVirtualAppliance, final VirtualmachineHB virtualMachine, final IpPoolType rule) throws Exception { // Captured VMs may have null virtual images if (virtualMachine.getImage() != null && virtualMachine.getImage().isChefEnabled()) { // Build the bootstrap configuration URI String bootstrapURITemplate = "%s/cloud/virtualdatacenters/%s/virtualappliances/%s/virtualmachines/%s/config/bootstrap"; String apiLocation = AbiConfigManager.getInstance().getAbiConfig().getApiLocation(); if (apiLocation.endsWith("/")) { apiLocation = apiLocation.substring(0, apiLocation.length() - 1); } String bootstrapURI = String.format(bootstrapURITemplate, apiLocation, idVirtualdatacenter, idVirtualAppliance, virtualMachine.getIdVm()); // Generate the one-time authentication token DAOFactory factory = HibernateDAOFactory.instance(); factory.beginConnection(); OneTimeTokenSessionHB oneTimeToken = factory.getOneTimeTokenSessionDAO().generateToken(); factory.endConnection(); rule.setBootstrapConfigURI(bootstrapURI); rule.setBootstrapConfigAuth(oneTimeToken.getToken()); } } /** * hypervisor info * * @throws RequiredAttributeException */ private VirtualHardwareSectionType createVirtualSystemSection( final VirtualMachine virtualMachine, final VirtualImage virtualImage, final String networkName, final Integer nodeId, final List<ResourceAllocationSettingData> additionalRasds) throws RequiredAttributeException { HyperVisor hypervisor = (HyperVisor) virtualMachine.getAssignedTo(); String hypervisorAddres = "http://" + hypervisor.getIp() + ":" + hypervisor.getPort() + "/"; String vsystemType = hypervisor.getType().getName(); String instanceID = virtualMachine.getUUID(); // VIRTUAL SYSTEM SETTING DATA VSSDType vssd = CIMVirtualSystemSettingDataUtils.createVirtualSystemSettingData("Hypervisor", instanceID, null, null, null, null); // TODO insertUserAndPassword(vssd, hypervisor); // Setting the hypervisor address as VirtualSystemIdentifier element String virtualSystemIdentifier = hypervisorAddres; // Setting the hypervisor type CIMVirtualSystemSettingDataUtils.setVirtualSystemToVSSettingData(vssd, virtualSystemIdentifier, vsystemType); // Creating the VirtualHardware element VirtualHardwareSectionType hardwareSection = OVFVirtualHadwareSectionUtils.createVirtualHardwareSection(vssd, null, "transport"); // TODO // info // and // transport // Setting RAM CIMResourceAllocationSettingDataType cimRam = CIMResourceAllocationSettingDataUtils.createResourceAllocationSettingData("RAM", "2", CIMResourceTypeEnum.Memory); CIMResourceAllocationSettingDataUtils.setAllocationToRASD(cimRam, new Long(virtualMachine.getRam())); // Setting CPU CIMResourceAllocationSettingDataType cimCpu = CIMResourceAllocationSettingDataUtils.createResourceAllocationSettingData("CPU", "1", CIMResourceTypeEnum.Processor); CIMResourceAllocationSettingDataUtils.setAllocationToRASD(cimCpu, new Long(virtualMachine.getCpu())); String virtualImageId = String.valueOf(nodeId); String diskId = "disk_" + virtualImageId; CIMResourceAllocationSettingDataType cimDisk = CIMResourceAllocationSettingDataUtils.createResourceAllocationSettingData("Harddisk" + virtualImageId + "'", virtualImageId, CIMResourceTypeEnum.Disk_Drive); CIMResourceAllocationSettingDataUtils.addHostResourceToRASD(cimDisk, OVFVirtualHadwareSectionUtils.OVF_DISK_URI + diskId); // All the above resource will be refactored to follow the CIM Resource Allocation model // So far we will receive iscsi resources - This information is now here // ResourceAllocationSettingData related to networking is taken care of in the for loop that // follows ... List<ResourceAllocationSettingData> rasdList = getResourceAllocationSettingDataList(virtualMachine, getPhysicalMachineIqn(virtualMachine), additionalRasds); for (ResourceAllocationSettingData rasd : rasdList) { RASDType rasdType = ResourceAllocationSettingData.toCIM_RASDType(rasd); OVFVirtualHadwareSectionUtils.addRASD(hardwareSection, rasdType); } RASDType raCpu = CIMResourceAllocationSettingDataUtils.createRASDTypeFromCIMRASD(cimCpu); RASDType raRam = CIMResourceAllocationSettingDataUtils.createRASDTypeFromCIMRASD(cimRam); RASDType raDisk = CIMResourceAllocationSettingDataUtils.createRASDTypeFromCIMRASD(cimDisk); OVFVirtualHadwareSectionUtils.addRASD(hardwareSection, raCpu); OVFVirtualHadwareSectionUtils.addRASD(hardwareSection, raRam); OVFVirtualHadwareSectionUtils.addRASD(hardwareSection, raDisk); return hardwareSection; }// vhs private String getPhysicalMachineIqn(final VirtualMachine virtualMachine) { // Get Virtual Datacenter HyperVisor hv = (HyperVisor) virtualMachine.getAssignedTo(); PhysicalMachine pm = (PhysicalMachine) hv.getAssignedTo(); return pm.getInitiatorIQN(); } /** * Adds user and password in the Virtual System Type * * @param vssd the virtual system type * @param hypervisor The hypervisor */ private static void insertUserAndPassword(final VSSDType vssd, final HyperVisor hypervisor) { DAOFactory factory = HibernateDAOFactory.instance(); factory.beginConnection(true); // Refresh credentials from database, since Flex Client does not provide them HypervisorHB hv = factory.getHyperVisorDAO().findById(hypervisor.getId()); vssd.getOtherAttributes().put(AbiCloudConstants.ADMIN_USER_QNAME, hv.getUser()); vssd.getOtherAttributes() .put(AbiCloudConstants.ADMIN_USER_PASSWORD_QNAME, hv.getPassword()); factory.endConnection(); } /** * Private helper to get the resources allocation setting data from the DB. This operation is * need since the virtual machine object got it doesn't store this information. When the pojos * for FLEX will be removed this operation won't be necessary * * @param virtualMachine the virtual machine to get the RASD from * @return the resource allocation setting data list */ protected List<ResourceAllocationSettingData> getResourceAllocationSettingDataList( final VirtualMachine virtualMachine, final String initiatorIqn, final List<ResourceAllocationSettingData> additionalRasds) throws RequiredAttributeException { List<ResourceAllocationSettingData> rads = new ArrayList<ResourceAllocationSettingData>(); DAOFactory factory = HibernateDAOFactory.instance(); try { VirtualMachineDAO vmDAO = factory.getVirtualMachineDAO(); factory.beginConnection(); VirtualmachineHB virtualMachineHB = vmDAO.findById(virtualMachine.getId()); // [ABICLOUDPREMIUM-1731] If we are removing the VM with an update nodes operation, the // VM will not exist in DB. We return the empty list to ignore the rasd section (it is // not needed to delete the node). if (virtualMachineHB != null) { rads = virtualMachineHB.getRasds(); } factory.endConnection(); } catch (Exception e) { factory.rollbackConnection(); logger.error( "An error was occurred when getting the rasds from the virtual machine: {}", e); } return rads; } /** * Private helper to assign the virtual system state with the present state of the virtual * machine * * @param enveloe * @param virtualAppliance the virtual appliance where to get the states of the virtual machine * @return * @throws EmptyEnvelopeException * @throws SectionException * @throws SectionNotPresentException */ public EnvelopeType changeVirtualMachineStates(final EnvelopeType envelope, final VirtualAppliance virtualAppliance) throws EmptyEnvelopeException, SectionException { ContentType entityInstance = OVFEnvelopeUtils.getTopLevelVirtualSystemContent(envelope); if (entityInstance instanceof VirtualSystemCollectionType) { VirtualSystemCollectionType virtualSystemCollectionType = (VirtualSystemCollectionType) entityInstance; for (ContentType subVirtualSystem : OVFEnvelopeUtils .getVirtualSystemsFromCollection(virtualSystemCollectionType)) { String virtualSystemState = null; Collection<Node> nodes = virtualAppliance.getNodes(); for (Node node : nodes) { NodeVirtualImage nodeVi = (NodeVirtualImage) node; VirtualMachine vm = nodeVi.getVirtualMachine(); String uuid = vm.getUUID(); if (uuid.equals(subVirtualSystem.getId())) { virtualSystemState = getStateToApply(vm.getState()); } } AnnotationSectionType annotationSection = OVFEnvelopeUtils.getSection(subVirtualSystem, AnnotationSectionType.class); Map<QName, String> attributes = annotationSection.getOtherAttributes(); attributes.put(AbiCloudConstants.machineStateQname, virtualSystemState); } } return envelope; } /** * Private helper to translate the Virtual machine state with the state to apply as parameter in * the Annotation Section of the Virtual System section * * @param state the virtual machien state * @return */ private static String getStateToApply(final State state) { String actionState = null; switch (state.toEnum()) { case ON: actionState = AbiCloudConstants.POWERUP_ACTION; break; case OFF: actionState = AbiCloudConstants.POWERDOWN_ACTION; break; case PAUSED: actionState = AbiCloudConstants.PAUSE_ACTION; break; default: break; } return actionState; } /** * Private helper to change the state * * @param enveloe * @return * @throws EmptyEnvelopeException * @throws SectionException * @throws SectionNotPresentException */ public EnvelopeType changeStateVirtualMachine(final EnvelopeType envelope, final String newState) throws EmptyEnvelopeException, SectionException { ContentType entityInstance = OVFEnvelopeUtils.getTopLevelVirtualSystemContent(envelope); if (entityInstance instanceof VirtualSystemType) { // Getting state property AnnotationSectionType annotationSection = OVFEnvelopeUtils.getSection(entityInstance, AnnotationSectionType.class); Map<QName, String> attributes = annotationSection.getOtherAttributes(); attributes.put(AbiCloudConstants.machineStateQname, newState); } else if (entityInstance instanceof VirtualSystemCollectionType) { VirtualSystemCollectionType virtualSystemCollectionType = (VirtualSystemCollectionType) entityInstance; for (ContentType subVirtualSystem : OVFEnvelopeUtils .getVirtualSystemsFromCollection(virtualSystemCollectionType)) { AnnotationSectionType annotationSection = OVFEnvelopeUtils.getSection(subVirtualSystem, AnnotationSectionType.class); Map<QName, String> attributes = annotationSection.getOtherAttributes(); attributes.put(AbiCloudConstants.machineStateQname, newState); } } return envelope; } /** * Adds the Repository Manager to the FileType. * <p> * The Repository Manager is used by the XenServer plugin in the copy operation. * * @param virtualDiskImageFile The FileType. * @param nvi The NodeVirtualImage. */ private static void insertRepositoryManager(final FileType virtualDiskImageFile, final VirtualMachine virtualMachine) { // XenServer virtual factory plugin needs to know the RepositoryManager address String repositoryManagerAddress = getRepositoryManagerAddress(virtualMachine); if (repositoryManagerAddress != null) { virtualDiskImageFile.getOtherAttributes().put(new QName("repositoryManager"), repositoryManagerAddress); } } private static String getRepositoryManagerAddress(final VirtualMachine virtualMachine) { // Get Virtual Datacenter HyperVisor hv = (HyperVisor) virtualMachine.getAssignedTo(); PhysicalMachine pm = (PhysicalMachine) hv.getAssignedTo(); Rack rack = (Rack) pm.getAssignedTo(); Integer idDatacenter = rack.getDataCenter().getId(); try { DAOFactory factory = HibernateDAOFactory.instance(); RemoteServiceDAO rsDAO = factory.getRemoteServiceDAO(); if (!factory.isTransactionActive()) { factory.beginConnection(); } List<RemoteServiceHB> remoteServices = rsDAO.getRemoteServicesByType(idDatacenter, RemoteServiceType.APPLIANCE_MANAGER); if (remoteServices == null || remoteServices.isEmpty()) { logger.error("Could find the Remote Repository Remote Service"); return null; } String repositoryManagerUri = remoteServices.iterator().next().getUri(); factory.endConnection(); return repositoryManagerUri; } catch (PersistenceException ex) { logger.error("Could not get Repository Manager Address", ex); } return null; } }