diff --git a/api/src/main/java/com/cloud/agent/api/storage/OVFHelper.java b/api/src/main/java/com/cloud/agent/api/storage/OVFHelper.java index bd58a189f76..45eff89b0c9 100644 --- a/api/src/main/java/com/cloud/agent/api/storage/OVFHelper.java +++ b/api/src/main/java/com/cloud/agent/api/storage/OVFHelper.java @@ -39,10 +39,15 @@ import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; +import com.cloud.agent.api.to.deployasis.OVFConfigurationTO; +import com.cloud.agent.api.to.deployasis.OVFEulaSectionTO; +import com.cloud.agent.api.to.deployasis.OVFPropertyTO; +import com.cloud.agent.api.to.deployasis.OVFVirtualHardwareItemTO; +import com.cloud.agent.api.to.deployasis.OVFVirtualHardwareSectionTO; import com.cloud.configuration.Resource.ResourceType; import com.cloud.exception.InternalErrorException; import com.cloud.utils.compression.CompressionUtil; -import org.apache.cloudstack.api.net.NetworkPrerequisiteTO; +import com.cloud.agent.api.to.deployasis.OVFNetworkTO; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.math.NumberUtils; @@ -573,7 +578,7 @@ public class OVFHelper { return null; } - public List getNetPrerequisitesFromDocument(Document doc) throws InternalErrorException { + public List getNetPrerequisitesFromDocument(Document doc) throws InternalErrorException { if (doc == null) { if (s_logger.isTraceEnabled()) { s_logger.trace("no document to parse; returning no prerequiste networks"); @@ -581,7 +586,7 @@ public class OVFHelper { return Collections.emptyList(); } - Map nets = getNetworksFromDocumentTree(doc); + Map nets = getNetworksFromDocumentTree(doc); checkForOnlyOneSystemNode(doc); @@ -590,7 +595,7 @@ public class OVFHelper { return new ArrayList<>(nets.values()); } - private void matchNicsToNets(Map nets, Node systemElement) { + private void matchNicsToNets(Map nets, Node systemElement) { final DocumentTraversal traversal = (DocumentTraversal) systemElement; final NodeIterator iterator = traversal.createNodeIterator(systemElement, NodeFilter.SHOW_ELEMENT, null, true); if (s_logger.isTraceEnabled()) { @@ -606,9 +611,9 @@ public class OVFHelper { if(s_logger.isInfoEnabled()) { s_logger.info(String.format("found a nic definition without a network definition byname %s, adding it to the list.", name)); } - nets.put(name, new NetworkPrerequisiteTO()); + nets.put(name, new OVFNetworkTO()); } - NetworkPrerequisiteTO thisNet = nets.get(name); + OVFNetworkTO thisNet = nets.get(name); if (e.getParentNode() != null) { fillNicPrerequisites(thisNet,e.getParentNode()); } @@ -625,7 +630,7 @@ public class OVFHelper { * @param nic the object to carry through the system * @param parentNode the xml container node for nic data */ - private void fillNicPrerequisites(NetworkPrerequisiteTO nic, Node parentNode) { + private void fillNicPrerequisites(OVFNetworkTO nic, Node parentNode) { String addressOnParentStr = getChildNodeValue(parentNode, "AddressOnParent"); String automaticAllocationStr = getChildNodeValue(parentNode, "AutomaticAllocation"); String description = getChildNodeValue(parentNode, "Description"); @@ -667,9 +672,9 @@ public class OVFHelper { } } - private Map getNetworksFromDocumentTree(Document doc) { + private Map getNetworksFromDocumentTree(Document doc) { NodeList networkElements = doc.getElementsByTagName("Network"); - Map nets = new HashMap<>(); + Map nets = new HashMap<>(); for (int i = 0; i < networkElements.getLength(); i++) { Element networkElement = (Element)networkElements.item(i); @@ -677,7 +682,7 @@ public class OVFHelper { String description = getChildNodeValue(networkElement, "Description"); - NetworkPrerequisiteTO network = new NetworkPrerequisiteTO(); + OVFNetworkTO network = new OVFNetworkTO(); network.setName(networkName); network.setNetworkDescription(description); diff --git a/api/src/main/java/com/cloud/agent/api/to/DeployAsIsInfoTO.java b/api/src/main/java/com/cloud/agent/api/to/DeployAsIsInfoTO.java index c51c2632137..cc0e1d01d03 100644 --- a/api/src/main/java/com/cloud/agent/api/to/DeployAsIsInfoTO.java +++ b/api/src/main/java/com/cloud/agent/api/to/DeployAsIsInfoTO.java @@ -16,36 +16,37 @@ // under the License. package com.cloud.agent.api.to; +import com.cloud.agent.api.LogLevel; + +import java.util.HashMap; +import java.util.Map; + public class DeployAsIsInfoTO { - private boolean deployAsIs; private String templatePath; - private String deploymentConfiguration; + private String destStoragePool; + @LogLevel(LogLevel.Log4jLevel.Off) + private Map properties = new HashMap<>(); public DeployAsIsInfoTO() { } - public boolean isDeployAsIs() { - return deployAsIs; - } - - public void setDeployAsIs(boolean deployAsIs) { - this.deployAsIs = deployAsIs; + public DeployAsIsInfoTO(String templatePath, String destStoragePool, Map properties) { + this.templatePath = templatePath; + this.destStoragePool = destStoragePool; + this.properties = properties; } public String getTemplatePath() { return templatePath; } - public void setTemplatePath(String templateInSecondaryPath) { - this.templatePath = templateInSecondaryPath; + public Map getProperties() { + return properties; } - public String getDeploymentConfiguration() { - return deploymentConfiguration; + public String getDestStoragePool() { + return destStoragePool; } - public void setDeploymentConfiguration(String deploymentConfiguration) { - this.deploymentConfiguration = deploymentConfiguration; - } } diff --git a/api/src/main/java/com/cloud/agent/api/to/VirtualMachineTO.java b/api/src/main/java/com/cloud/agent/api/to/VirtualMachineTO.java index 7dbc70d6629..efc735ccecf 100644 --- a/api/src/main/java/com/cloud/agent/api/to/VirtualMachineTO.java +++ b/api/src/main/java/com/cloud/agent/api/to/VirtualMachineTO.java @@ -20,8 +20,6 @@ import java.util.List; import java.util.Map; import java.util.HashMap; -import com.cloud.agent.api.LogLevel; -import com.cloud.agent.api.storage.OVFPropertyTO; import com.cloud.template.VirtualMachineTemplate.BootloaderType; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachine.Type; @@ -80,8 +78,6 @@ public class VirtualMachineTO { Map guestOsDetails = new HashMap(); Map extraConfig = new HashMap<>(); - @LogLevel(LogLevel.Log4jLevel.Off) - List ovfProperties; DeployAsIsInfoTO deployAsIsInfo; public VirtualMachineTO(long id, String instanceName, VirtualMachine.Type type, int cpus, Integer speed, long minRam, long maxRam, BootloaderType bootloader, @@ -376,13 +372,6 @@ public class VirtualMachineTO { return extraConfig; } - public List getOvfProperties() { - return ovfProperties; - } - - public void setOvfProperties(List ovfProperties) { - this.ovfProperties = ovfProperties; - } public String getBootType() { return bootType; } diff --git a/api/src/main/java/com/cloud/agent/api/storage/OVFConfigurationTO.java b/api/src/main/java/com/cloud/agent/api/to/deployasis/OVFConfigurationTO.java similarity index 93% rename from api/src/main/java/com/cloud/agent/api/storage/OVFConfigurationTO.java rename to api/src/main/java/com/cloud/agent/api/to/deployasis/OVFConfigurationTO.java index 983a8b808f4..f3cb75089ab 100644 --- a/api/src/main/java/com/cloud/agent/api/storage/OVFConfigurationTO.java +++ b/api/src/main/java/com/cloud/agent/api/to/deployasis/OVFConfigurationTO.java @@ -16,11 +16,11 @@ // specific language governing permissions and limitations // under the License. // -package com.cloud.agent.api.storage; +package com.cloud.agent.api.to.deployasis; import java.util.List; -public class OVFConfigurationTO { +public class OVFConfigurationTO implements TemplateDeployAsIsInformationTO { private final String id; private final String label; diff --git a/api/src/main/java/com/cloud/agent/api/storage/OVFEulaSectionTO.java b/api/src/main/java/com/cloud/agent/api/to/deployasis/OVFEulaSectionTO.java similarity index 91% rename from api/src/main/java/com/cloud/agent/api/storage/OVFEulaSectionTO.java rename to api/src/main/java/com/cloud/agent/api/to/deployasis/OVFEulaSectionTO.java index eff478c88b3..893661782f4 100644 --- a/api/src/main/java/com/cloud/agent/api/storage/OVFEulaSectionTO.java +++ b/api/src/main/java/com/cloud/agent/api/to/deployasis/OVFEulaSectionTO.java @@ -16,16 +16,14 @@ // specific language governing permissions and limitations // under the License. // -package com.cloud.agent.api.storage; +package com.cloud.agent.api.to.deployasis; import com.cloud.agent.api.LogLevel; -import java.io.Serializable; - /** * End-user licence agreement */ -public class OVFEulaSectionTO implements Serializable { +public class OVFEulaSectionTO implements TemplateDeployAsIsInformationTO { private String info; @LogLevel(LogLevel.Log4jLevel.Off) private byte[] compressedLicense; diff --git a/api/src/main/java/org/apache/cloudstack/api/net/NetworkPrerequisiteTO.java b/api/src/main/java/com/cloud/agent/api/to/deployasis/OVFNetworkTO.java similarity index 96% rename from api/src/main/java/org/apache/cloudstack/api/net/NetworkPrerequisiteTO.java rename to api/src/main/java/com/cloud/agent/api/to/deployasis/OVFNetworkTO.java index e39849685de..9b05dbc1863 100644 --- a/api/src/main/java/org/apache/cloudstack/api/net/NetworkPrerequisiteTO.java +++ b/api/src/main/java/com/cloud/agent/api/to/deployasis/OVFNetworkTO.java @@ -14,7 +14,7 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package org.apache.cloudstack.api.net; +package com.cloud.agent.api.to.deployasis; /** * container for the network prerequisites as found in the appliance template @@ -38,7 +38,7 @@ package org.apache.cloudstack.api.net; * * {code} */ -public class NetworkPrerequisiteTO { +public class OVFNetworkTO implements TemplateDeployAsIsInformationTO { String name; String networkDescription; diff --git a/api/src/main/java/com/cloud/agent/api/storage/OVFPropertyTO.java b/api/src/main/java/com/cloud/agent/api/to/deployasis/OVFPropertyTO.java similarity index 97% rename from api/src/main/java/com/cloud/agent/api/storage/OVFPropertyTO.java rename to api/src/main/java/com/cloud/agent/api/to/deployasis/OVFPropertyTO.java index 24207e92821..32c62559262 100644 --- a/api/src/main/java/com/cloud/agent/api/storage/OVFPropertyTO.java +++ b/api/src/main/java/com/cloud/agent/api/to/deployasis/OVFPropertyTO.java @@ -17,7 +17,7 @@ // under the License. // -package com.cloud.agent.api.storage; +package com.cloud.agent.api.to.deployasis; import com.cloud.agent.api.LogLevel; @@ -30,7 +30,7 @@ import com.cloud.agent.api.LogLevel; * Choose "Remote HTTP and SSH Client Routes" to route only traffic destined for the management client(s), when they are on remote networks. * */ -public class OVFPropertyTO { +public class OVFPropertyTO implements TemplateDeployAsIsInformationTO { private String key; private String type; diff --git a/api/src/main/java/com/cloud/agent/api/storage/OVFVirtualHardwareItemTO.java b/api/src/main/java/com/cloud/agent/api/to/deployasis/OVFVirtualHardwareItemTO.java similarity index 98% rename from api/src/main/java/com/cloud/agent/api/storage/OVFVirtualHardwareItemTO.java rename to api/src/main/java/com/cloud/agent/api/to/deployasis/OVFVirtualHardwareItemTO.java index 365ef7d37b5..52577506653 100644 --- a/api/src/main/java/com/cloud/agent/api/storage/OVFVirtualHardwareItemTO.java +++ b/api/src/main/java/com/cloud/agent/api/to/deployasis/OVFVirtualHardwareItemTO.java @@ -14,10 +14,10 @@ // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. -package com.cloud.agent.api.storage; +package com.cloud.agent.api.to.deployasis; // From: https://schemas.dmtf.org/wbem/wscim/1/cim-schema/2/CIM_ResourceAllocationSettingData.xsd -public class OVFVirtualHardwareItemTO { +public class OVFVirtualHardwareItemTO implements TemplateDeployAsIsInformationTO{ //From: https://schemas.dmtf.org/wbem/cim-html/2/CIM_ResourceAllocationSettingData.html public enum HardwareResourceType { diff --git a/api/src/main/java/com/cloud/agent/api/storage/OVFVirtualHardwareSectionTO.java b/api/src/main/java/com/cloud/agent/api/to/deployasis/OVFVirtualHardwareSectionTO.java similarity index 91% rename from api/src/main/java/com/cloud/agent/api/storage/OVFVirtualHardwareSectionTO.java rename to api/src/main/java/com/cloud/agent/api/to/deployasis/OVFVirtualHardwareSectionTO.java index 9a3ae1244eb..2698f8c5e18 100644 --- a/api/src/main/java/com/cloud/agent/api/storage/OVFVirtualHardwareSectionTO.java +++ b/api/src/main/java/com/cloud/agent/api/to/deployasis/OVFVirtualHardwareSectionTO.java @@ -16,11 +16,11 @@ // specific language governing permissions and limitations // under the License. // -package com.cloud.agent.api.storage; +package com.cloud.agent.api.to.deployasis; import java.util.List; -public class OVFVirtualHardwareSectionTO { +public class OVFVirtualHardwareSectionTO implements TemplateDeployAsIsInformationTO { public OVFVirtualHardwareSectionTO() { } diff --git a/api/src/main/java/com/cloud/agent/api/to/deployasis/TemplateDeployAsIsInformationTO.java b/api/src/main/java/com/cloud/agent/api/to/deployasis/TemplateDeployAsIsInformationTO.java new file mode 100644 index 00000000000..9080b92f594 --- /dev/null +++ b/api/src/main/java/com/cloud/agent/api/to/deployasis/TemplateDeployAsIsInformationTO.java @@ -0,0 +1,24 @@ +// +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 com.cloud.agent.api.to.deployasis; + +import java.io.Serializable; + +public interface TemplateDeployAsIsInformationTO extends Serializable { +} diff --git a/api/src/main/java/com/cloud/deployasis/DeployAsIsConstants.java b/api/src/main/java/com/cloud/deployasis/DeployAsIsConstants.java new file mode 100644 index 00000000000..8c50a3ff401 --- /dev/null +++ b/api/src/main/java/com/cloud/deployasis/DeployAsIsConstants.java @@ -0,0 +1,27 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 com.cloud.deployasis; + +public interface DeployAsIsConstants { + + String ACS_PROPERTY_PREFIX = "ACS-property-"; + String REQUIRED_NETWORK_PREFIX = "ACS-network-"; + String OVF_HARDWARE_CONFIGURATION_PREFIX = "ACS-configuration-"; + String OVF_HARDWARE_ITEM_PREFIX = "ACS-hardware-item-"; + String OVF_EULA_SECTION_PREFIX = "ACS-eula-"; + +} diff --git a/api/src/main/java/com/cloud/storage/ImageStore.java b/api/src/main/java/com/cloud/storage/ImageStore.java index 017f367c13e..c019b17421d 100644 --- a/api/src/main/java/com/cloud/storage/ImageStore.java +++ b/api/src/main/java/com/cloud/storage/ImageStore.java @@ -21,13 +21,6 @@ import org.apache.cloudstack.api.InternalIdentity; public interface ImageStore extends Identity, InternalIdentity { - String ACS_PROPERTY_PREFIX = "ACS-property-"; - String REQUIRED_NETWORK_PREFIX = "ACS-network-"; - String DISK_DEFINITION_PREFIX = "ACS-disk-"; - String OVF_HARDWARE_CONFIGURATION_PREFIX = "ACS-configuration-"; - String OVF_HARDWARE_ITEM_PREFIX = "ACS-hardware-item-"; - String OVF_EULA_SECTION_PREFIX = "ACS-eula-"; - /** * @return name of the object store. */ diff --git a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java index 4751e312f92..ba1f1768395 100644 --- a/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/main/java/org/apache/cloudstack/api/ApiConstants.java @@ -826,6 +826,7 @@ public class ApiConstants { public static final String BOOT_MODE = "bootmode"; public static final String BOOT_INTO_SETUP = "bootintosetup"; public static final String DEPLOY_AS_IS = "deployasis"; + public static final String DEPLOY_AS_IS_DETAILS = "deployasisdetails"; public static final String CROSS_ZONES = "crossZones"; public static final String TEMPLATETYPE = "templatetype"; public static final String SOURCETEMPLATEID = "sourcetemplateid"; diff --git a/api/src/main/java/org/apache/cloudstack/api/response/TemplateResponse.java b/api/src/main/java/org/apache/cloudstack/api/response/TemplateResponse.java index 457d29c7ab1..c733f37a9fb 100644 --- a/api/src/main/java/org/apache/cloudstack/api/response/TemplateResponse.java +++ b/api/src/main/java/org/apache/cloudstack/api/response/TemplateResponse.java @@ -199,6 +199,10 @@ public class TemplateResponse extends BaseResponseWithTagInformation implements @Param(description = "VMware only: true if template is deployed without orchestrating disks and networks but \"as-is\" defined in the template.") private Boolean deployAsIs; + @SerializedName(ApiConstants.DEPLOY_AS_IS_DETAILS) + @Param(description = "VMware only: additional key/value details tied with deploy-as-is template") + private Map deployAsIsDetails; + @SerializedName("parenttemplateid") @Param(description = "if Datadisk template, then id of the root disk template this template belongs to") @Deprecated(since = "4.15") @@ -429,4 +433,19 @@ public class TemplateResponse extends BaseResponseWithTagInformation implements public void setRequiresHvm(Boolean requiresHvm) { this.requiresHvm = requiresHvm; } + + public Map getDeployAsIsDetails() { + return this.deployAsIsDetails; + } + + public void setDeployAsIsDetails(Map details) { + this.deployAsIsDetails = details; + } + + public void addDeployAsIsDetail(String key, String value) { + if (this.deployAsIsDetails == null) { + setDeployAsIsDetails(new HashMap<>()); + } + this.deployAsIsDetails.put(key,value); + } } diff --git a/api/src/test/java/com/cloud/agent/api/storage/OVFHelperTest.java b/api/src/test/java/com/cloud/agent/api/storage/OVFHelperTest.java index c4f71052496..e28680784d7 100644 --- a/api/src/test/java/com/cloud/agent/api/storage/OVFHelperTest.java +++ b/api/src/test/java/com/cloud/agent/api/storage/OVFHelperTest.java @@ -16,6 +16,10 @@ // under the License. package com.cloud.agent.api.storage; +import com.cloud.agent.api.to.deployasis.OVFConfigurationTO; +import com.cloud.agent.api.to.deployasis.OVFEulaSectionTO; +import com.cloud.agent.api.to.deployasis.OVFPropertyTO; +import com.cloud.agent.api.to.deployasis.OVFVirtualHardwareItemTO; import org.junit.Assert; import org.junit.Test; import org.xml.sax.SAXException; diff --git a/core/src/main/java/com/cloud/agent/api/storage/DownloadAnswer.java b/core/src/main/java/com/cloud/agent/api/storage/DownloadAnswer.java index a7b9179e200..9ae1d6dcca5 100644 --- a/core/src/main/java/com/cloud/agent/api/storage/DownloadAnswer.java +++ b/core/src/main/java/com/cloud/agent/api/storage/DownloadAnswer.java @@ -26,9 +26,12 @@ import com.cloud.agent.api.Answer; import com.cloud.agent.api.Command; import com.cloud.agent.api.LogLevel; import com.cloud.agent.api.to.DatadiskTO; +import com.cloud.agent.api.to.deployasis.OVFEulaSectionTO; +import com.cloud.agent.api.to.deployasis.OVFPropertyTO; +import com.cloud.agent.api.to.deployasis.OVFVirtualHardwareSectionTO; import com.cloud.storage.VMTemplateStorageResourceAssoc; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; -import org.apache.cloudstack.api.net.NetworkPrerequisiteTO; +import com.cloud.agent.api.to.deployasis.OVFNetworkTO; public class DownloadAnswer extends Answer { private String jobId; @@ -44,7 +47,7 @@ public class DownloadAnswer extends Answer { @LogLevel(LogLevel.Log4jLevel.Off) private List ovfProperties; @LogLevel(LogLevel.Log4jLevel.Off) - private List networkRequirements; + private List networkRequirements; @LogLevel(LogLevel.Log4jLevel.Off) private List disks; @LogLevel(LogLevel.Log4jLevel.Off) @@ -169,11 +172,11 @@ public class DownloadAnswer extends Answer { this.ovfProperties = ovfProperties; } - public List getNetworkRequirements() { + public List getNetworkRequirements() { return networkRequirements; } - public void setNetworkRequirements(List networkRequirements) { + public void setNetworkRequirements(List networkRequirements) { this.networkRequirements = networkRequirements; } diff --git a/core/src/main/java/com/cloud/storage/template/OVAProcessor.java b/core/src/main/java/com/cloud/storage/template/OVAProcessor.java index 794ac48c904..e980293b750 100644 --- a/core/src/main/java/com/cloud/storage/template/OVAProcessor.java +++ b/core/src/main/java/com/cloud/storage/template/OVAProcessor.java @@ -28,12 +28,12 @@ import javax.naming.ConfigurationException; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; -import com.cloud.agent.api.storage.OVFConfigurationTO; -import com.cloud.agent.api.storage.OVFEulaSectionTO; -import com.cloud.agent.api.storage.OVFPropertyTO; -import com.cloud.agent.api.storage.OVFVirtualHardwareItemTO; -import com.cloud.agent.api.storage.OVFVirtualHardwareSectionTO; -import org.apache.cloudstack.api.net.NetworkPrerequisiteTO; +import com.cloud.agent.api.to.deployasis.OVFConfigurationTO; +import com.cloud.agent.api.to.deployasis.OVFEulaSectionTO; +import com.cloud.agent.api.to.deployasis.OVFPropertyTO; +import com.cloud.agent.api.to.deployasis.OVFVirtualHardwareItemTO; +import com.cloud.agent.api.to.deployasis.OVFVirtualHardwareSectionTO; +import com.cloud.agent.api.to.deployasis.OVFNetworkTO; import org.apache.commons.collections.CollectionUtils; import org.apache.log4j.Logger; import org.w3c.dom.Document; @@ -115,7 +115,7 @@ public class OVAProcessor extends AdapterBase implements Processor { info.disks = disks; } - List nets = ovfHelper.getNetPrerequisitesFromDocument(doc); + List nets = ovfHelper.getNetPrerequisitesFromDocument(doc); if (CollectionUtils.isNotEmpty(nets)) { LOGGER.info("Found " + nets.size() + " prerequisite networks"); info.networks = nets; diff --git a/core/src/main/java/com/cloud/storage/template/Processor.java b/core/src/main/java/com/cloud/storage/template/Processor.java index 53fa6b76d04..15a3dec0c6e 100644 --- a/core/src/main/java/com/cloud/storage/template/Processor.java +++ b/core/src/main/java/com/cloud/storage/template/Processor.java @@ -23,14 +23,14 @@ import java.io.File; import java.io.IOException; import java.util.List; -import com.cloud.agent.api.storage.OVFEulaSectionTO; -import com.cloud.agent.api.storage.OVFPropertyTO; -import com.cloud.agent.api.storage.OVFVirtualHardwareSectionTO; +import com.cloud.agent.api.to.deployasis.OVFEulaSectionTO; +import com.cloud.agent.api.to.deployasis.OVFPropertyTO; +import com.cloud.agent.api.to.deployasis.OVFVirtualHardwareSectionTO; import com.cloud.agent.api.to.DatadiskTO; import com.cloud.exception.InternalErrorException; import com.cloud.storage.Storage.ImageFormat; import com.cloud.utils.component.Adapter; -import org.apache.cloudstack.api.net.NetworkPrerequisiteTO; +import com.cloud.agent.api.to.deployasis.OVFNetworkTO; /** * Generic interface to process different types of image formats @@ -59,7 +59,7 @@ public interface Processor extends Adapter { public String filename; public boolean isCorrupted; public List ovfProperties; - public List networks; + public List networks; public List disks; public OVFVirtualHardwareSectionTO hardwareSection; public List eulaSections; diff --git a/core/src/test/java/com/cloud/agent/api/storage/DownloadAnswerTest.java b/core/src/test/java/com/cloud/agent/api/storage/DownloadAnswerTest.java index 62bb3d65c83..c7dcc22572a 100644 --- a/core/src/test/java/com/cloud/agent/api/storage/DownloadAnswerTest.java +++ b/core/src/test/java/com/cloud/agent/api/storage/DownloadAnswerTest.java @@ -17,10 +17,11 @@ package com.cloud.agent.api.storage; import com.cloud.agent.api.Answer; +import com.cloud.agent.api.to.deployasis.OVFPropertyTO; import com.cloud.serializer.GsonHelper; import com.cloud.storage.VMTemplateStorageResourceAssoc; import com.google.gson.Gson; -import org.apache.cloudstack.api.net.NetworkPrerequisiteTO; +import com.cloud.agent.api.to.deployasis.OVFNetworkTO; import org.junit.Assert; import org.junit.Test; @@ -45,8 +46,8 @@ public class DownloadAnswerTest { { List properties = new ArrayList<>(); properties.add(new OVFPropertyTO()); - List networks = new ArrayList<>(); - networks.add(new NetworkPrerequisiteTO()); + List networks = new ArrayList<>(); + networks.add(new OVFNetworkTO()); answer.setOvfProperties(properties); answer.setNetworkRequirements(networks); diff --git a/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java index fb4fadd9500..7ed090db9ff 100755 --- a/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/engine/orchestration/src/main/java/com/cloud/vm/VirtualMachineManagerImpl.java @@ -1472,8 +1472,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac if (disk.getType() != Volume.Type.ISO) { final VolumeObjectTO vol = (VolumeObjectTO)disk.getData(); final VolumeVO volume = _volsDao.findById(vol.getId()); - if (vmSpec.getDeployAsIsInfo() != null && vmSpec.getDeployAsIsInfo().isDeployAsIs() - && StringUtils.isNotBlank(vol.getPath())) { + if (vmSpec.getDeployAsIsInfo() != null && StringUtils.isNotBlank(vol.getPath())) { volume.setPath(vol.getPath()); _volsDao.update(volume.getId(), volume); } diff --git a/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java index 5b635bd2255..892ae2bac5c 100644 --- a/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java +++ b/engine/orchestration/src/main/java/org/apache/cloudstack/engine/orchestration/NetworkOrchestrator.java @@ -40,9 +40,10 @@ import java.util.stream.Collectors; import javax.inject.Inject; import javax.naming.ConfigurationException; +import com.cloud.deployasis.dao.TemplateDeployAsIsDetailsDao; import org.apache.cloudstack.acl.ControlledEntity.ACLType; import org.apache.cloudstack.api.ApiConstants; -import org.apache.cloudstack.api.net.NetworkPrerequisiteTO; +import com.cloud.agent.api.to.deployasis.OVFNetworkTO; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.engine.cloud.entity.api.db.VMNetworkMapVO; import org.apache.cloudstack.engine.cloud.entity.api.db.dao.VMNetworkMapDao; @@ -181,7 +182,6 @@ import com.cloud.offerings.NetworkOfferingVO; import com.cloud.offerings.dao.NetworkOfferingDao; import com.cloud.offerings.dao.NetworkOfferingDetailsDao; import com.cloud.offerings.dao.NetworkOfferingServiceMapDao; -import com.cloud.storage.dao.VMTemplateDetailsDao; import com.cloud.user.Account; import com.cloud.user.ResourceLimitService; import com.cloud.user.User; @@ -304,7 +304,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra @Inject UserVmManager _userVmMgr; @Inject - VMTemplateDetailsDao templateDetailsDao; + TemplateDeployAsIsDetailsDao templateDeployAsIsDetailsDao; List networkGurus; @@ -884,7 +884,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra } } - List netprereqs = templateDetailsDao.listNetworkRequirementsByTemplateId(vm.getTemplate().getId()); + List netprereqs = templateDeployAsIsDetailsDao.listNetworkRequirementsByTemplateId(vm.getTemplate().getId()); if (size < netprereqs.size()) { size = netprereqs.size(); } diff --git a/engine/schema/src/main/java/com/cloud/deployasis/TemplateDeployAsIsDetailVO.java b/engine/schema/src/main/java/com/cloud/deployasis/TemplateDeployAsIsDetailVO.java new file mode 100644 index 00000000000..00a69cd0b0c --- /dev/null +++ b/engine/schema/src/main/java/com/cloud/deployasis/TemplateDeployAsIsDetailVO.java @@ -0,0 +1,94 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 com.cloud.deployasis; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Lob; +import javax.persistence.Table; + +import org.apache.cloudstack.api.ResourceDetail; + +@Entity +@Table(name = "template_deploy_as_is_details") +public class TemplateDeployAsIsDetailVO implements ResourceDetail { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private long id; + + @Column(name = "template_id") + private long templateId; + + @Column(name = "name") + private String name; + + @Lob + @Column(name = "value", length = 65535) + private String value; + + public TemplateDeployAsIsDetailVO() { + } + + public TemplateDeployAsIsDetailVO(long templateId, String name, String value) { + this.templateId = templateId; + this.name = name; + this.value = value; + } + + @Override + public long getId() { + return id; + } + + public long getResourceId() { + return templateId; + } + + public String getName() { + return name; + } + + public String getValue() { + return value; + } + + @Override + public boolean isDisplay() { + return true; + } + + public void setId(long id) { + this.id = id; + } + + public void setTemplateId(long resourceId) { + this.templateId = resourceId; + } + + public void setName(String name) { + this.name = name; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/engine/schema/src/main/java/com/cloud/deployasis/TemplateDeployAsIsDetailVO.java~Stashed changes b/engine/schema/src/main/java/com/cloud/deployasis/TemplateDeployAsIsDetailVO.java~Stashed changes new file mode 100644 index 00000000000..047d985d0bb --- /dev/null +++ b/engine/schema/src/main/java/com/cloud/deployasis/TemplateDeployAsIsDetailVO.java~Stashed changes @@ -0,0 +1,94 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 com.cloud.deployasis; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Lob; +import javax.persistence.Table; + +import org.apache.cloudstack.api.ResourceDetail; + +@Entity +@Table(name = "template_deploy_as_is_details") +public class TemplateDeployAsIsDetailVO implements ResourceDetail { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private long id; + + @Column(name = "template_id") + private long resourceId; + + @Column(name = "name") + private String name; + + @Lob + @Column(name = "value", length = 65535) + private String value; + + public TemplateDeployAsIsDetailVO() { + } + + public TemplateDeployAsIsDetailVO(long templateId, String name, String value) { + this.resourceId = templateId; + this.name = name; + this.value = value; + } + + @Override + public long getId() { + return id; + } + + public long getResourceId() { + return resourceId; + } + + public String getName() { + return name; + } + + public String getValue() { + return value; + } + + @Override + public boolean isDisplay() { + return true; + } + + public void setId(long id) { + this.id = id; + } + + public void setResourceId(long resourceId) { + this.resourceId = resourceId; + } + + public void setName(String name) { + this.name = name; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/engine/schema/src/main/java/com/cloud/deployasis/UserVmDeployAsIsDetailVO.java b/engine/schema/src/main/java/com/cloud/deployasis/UserVmDeployAsIsDetailVO.java new file mode 100644 index 00000000000..6cbc22b6b38 --- /dev/null +++ b/engine/schema/src/main/java/com/cloud/deployasis/UserVmDeployAsIsDetailVO.java @@ -0,0 +1,94 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 com.cloud.deployasis; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Lob; +import javax.persistence.Table; + +import org.apache.cloudstack.api.ResourceDetail; + +@Entity +@Table(name = "user_vm_deploy_as_is_details") +public class UserVmDeployAsIsDetailVO implements ResourceDetail { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private long id; + + @Column(name = "vm_id") + private long vmId; + + @Column(name = "name") + private String name; + + @Lob + @Column(name = "value", length = 65535) + private String value; + + public UserVmDeployAsIsDetailVO() { + } + + public UserVmDeployAsIsDetailVO(long vmId, String name, String value) { + this.vmId = vmId; + this.name = name; + this.value = value; + } + + @Override + public long getId() { + return id; + } + + public long getResourceId() { + return vmId; + } + + public String getName() { + return name; + } + + public String getValue() { + return value; + } + + @Override + public boolean isDisplay() { + return true; + } + + public void setId(long id) { + this.id = id; + } + + public void setVmId(long resourceId) { + this.vmId = resourceId; + } + + public void setName(String name) { + this.name = name; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/engine/schema/src/main/java/com/cloud/deployasis/UserVmDeployAsIsDetailVO.java~Stashed changes b/engine/schema/src/main/java/com/cloud/deployasis/UserVmDeployAsIsDetailVO.java~Stashed changes new file mode 100644 index 00000000000..b56b4a49464 --- /dev/null +++ b/engine/schema/src/main/java/com/cloud/deployasis/UserVmDeployAsIsDetailVO.java~Stashed changes @@ -0,0 +1,94 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 com.cloud.deployasis; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Lob; +import javax.persistence.Table; + +import org.apache.cloudstack.api.ResourceDetail; + +@Entity +@Table(name = "user_vm_deploy_as_is_details") +public class UserVmDeployAsIsDetailVO implements ResourceDetail { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private long id; + + @Column(name = "vm_id") + private long resourceId; + + @Column(name = "name") + private String name; + + @Lob + @Column(name = "value", length = 65535) + private String value; + + public UserVmDeployAsIsDetailVO() { + } + + public UserVmDeployAsIsDetailVO(long vmId, String name, String value) { + this.resourceId = vmId; + this.name = name; + this.value = value; + } + + @Override + public long getId() { + return id; + } + + public long getResourceId() { + return resourceId; + } + + public String getName() { + return name; + } + + public String getValue() { + return value; + } + + @Override + public boolean isDisplay() { + return true; + } + + public void setId(long id) { + this.id = id; + } + + public void setResourceId(long resourceId) { + this.resourceId = resourceId; + } + + public void setName(String name) { + this.name = name; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/engine/schema/src/main/java/com/cloud/deployasis/dao/TemplateDeployAsIsDetailsDao.java b/engine/schema/src/main/java/com/cloud/deployasis/dao/TemplateDeployAsIsDetailsDao.java new file mode 100644 index 00000000000..ebbc1eabeb1 --- /dev/null +++ b/engine/schema/src/main/java/com/cloud/deployasis/dao/TemplateDeployAsIsDetailsDao.java @@ -0,0 +1,32 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 com.cloud.deployasis.dao; + +import com.cloud.agent.api.to.deployasis.OVFPropertyTO; +import com.cloud.deployasis.TemplateDeployAsIsDetailVO; +import com.cloud.utils.db.GenericDao; +import com.cloud.agent.api.to.deployasis.OVFNetworkTO; +import org.apache.cloudstack.resourcedetail.ResourceDetailsDao; + +import java.util.List; + +public interface TemplateDeployAsIsDetailsDao extends GenericDao, ResourceDetailsDao { + + OVFPropertyTO findPropertyByTemplateAndKey(long templateId, String key); + List listDetailsByTemplateIdMatchingPrefix(long templateId, String prefix); + List listNetworkRequirementsByTemplateId(long templateId); +} diff --git a/engine/schema/src/main/java/com/cloud/deployasis/dao/TemplateDeployAsIsDetailsDaoImpl.java b/engine/schema/src/main/java/com/cloud/deployasis/dao/TemplateDeployAsIsDetailsDaoImpl.java new file mode 100644 index 00000000000..df21d4b4872 --- /dev/null +++ b/engine/schema/src/main/java/com/cloud/deployasis/dao/TemplateDeployAsIsDetailsDaoImpl.java @@ -0,0 +1,83 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 com.cloud.deployasis.dao; + +import com.cloud.agent.api.to.deployasis.OVFPropertyTO; +import com.cloud.deployasis.DeployAsIsConstants; +import com.cloud.deployasis.TemplateDeployAsIsDetailVO; +import com.cloud.utils.db.SearchCriteria; +import com.google.gson.Gson; +import com.cloud.agent.api.to.deployasis.OVFNetworkTO; +import org.apache.cloudstack.resourcedetail.ResourceDetailsDaoBase; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; + +@Component +public class TemplateDeployAsIsDetailsDaoImpl extends ResourceDetailsDaoBase implements TemplateDeployAsIsDetailsDao { + + private Gson gson = new Gson(); + + public TemplateDeployAsIsDetailsDaoImpl() { + } + + @Override + public void addDetail(long resourceId, String key, String value, boolean display) { + super.addDetail(new TemplateDeployAsIsDetailVO(resourceId, key, value)); + } + + @Override + public OVFPropertyTO findPropertyByTemplateAndKey(long templateId, String key) { + SearchCriteria sc = createSearchCriteria(); + sc.addAnd("templateId", SearchCriteria.Op.EQ, templateId); + sc.addAnd("name", SearchCriteria.Op.EQ, key.startsWith(DeployAsIsConstants.ACS_PROPERTY_PREFIX) ? key : DeployAsIsConstants.ACS_PROPERTY_PREFIX + key); + OVFPropertyTO property = null; + TemplateDeployAsIsDetailVO detail = findOneBy(sc); + if (detail != null) { + property = gson.fromJson(detail.getValue(), OVFPropertyTO.class); + } + return property; + } + + @Override + public List listDetailsByTemplateIdMatchingPrefix(long templateId, String prefix) { + SearchCriteria ssc = createSearchCriteria(); + ssc.addAnd("templateId", SearchCriteria.Op.EQ, templateId); + ssc.addAnd("name", SearchCriteria.Op.LIKE, prefix + "%"); + + return search(ssc, null); + } + + @Override + public List listNetworkRequirementsByTemplateId(long templateId) { + List networkDetails = listDetailsByTemplateIdMatchingPrefix(templateId, DeployAsIsConstants.REQUIRED_NETWORK_PREFIX); + List networkPrereqs = new ArrayList<>(); + for (TemplateDeployAsIsDetailVO property : networkDetails) { + OVFNetworkTO ovfPropertyTO = gson.fromJson(property.getValue(), OVFNetworkTO.class); + networkPrereqs.add(ovfPropertyTO); + } + networkPrereqs.sort(new Comparator() { + @Override + public int compare(OVFNetworkTO o1, OVFNetworkTO o2) { + return o1.getInstanceID() - o2.getInstanceID(); + } + }); + return networkPrereqs; + } +} diff --git a/engine/schema/src/main/java/com/cloud/deployasis/dao/TemplateDeployAsIsDetailsDaoImpl.java~Stashed changes b/engine/schema/src/main/java/com/cloud/deployasis/dao/TemplateDeployAsIsDetailsDaoImpl.java~Stashed changes new file mode 100644 index 00000000000..6f4ec01d1f4 --- /dev/null +++ b/engine/schema/src/main/java/com/cloud/deployasis/dao/TemplateDeployAsIsDetailsDaoImpl.java~Stashed changes @@ -0,0 +1,83 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 com.cloud.deployasis.dao; + +import com.cloud.agent.api.to.deployasis.OVFPropertyTO; +import com.cloud.deployasis.DeployAsIsConstants; +import com.cloud.deployasis.TemplateDeployAsIsDetailVO; +import com.cloud.utils.db.SearchCriteria; +import com.google.gson.Gson; +import com.cloud.agent.api.to.deployasis.OVFNetworkTO; +import org.apache.cloudstack.resourcedetail.ResourceDetailsDaoBase; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; + +@Component +public class TemplateDeployAsIsDetailsDaoImpl extends ResourceDetailsDaoBase implements TemplateDeployAsIsDetailsDao { + + private Gson gson = new Gson(); + + public TemplateDeployAsIsDetailsDaoImpl() { + } + + @Override + public void addDetail(long resourceId, String key, String value, boolean display) { + super.addDetail(new TemplateDeployAsIsDetailVO(resourceId, key, value)); + } + + @Override + public OVFPropertyTO findPropertyByTemplateAndKey(long templateId, String key) { + SearchCriteria sc = createSearchCriteria(); + sc.addAnd("resourceId", SearchCriteria.Op.EQ, templateId); + sc.addAnd("name", SearchCriteria.Op.EQ, key.startsWith(DeployAsIsConstants.ACS_PROPERTY_PREFIX) ? key : DeployAsIsConstants.ACS_PROPERTY_PREFIX + key); + OVFPropertyTO property = null; + TemplateDeployAsIsDetailVO detail = findOneBy(sc); + if (detail != null) { + property = gson.fromJson(detail.getValue(), OVFPropertyTO.class); + } + return property; + } + + @Override + public List listDetailsByTemplateIdMatchingPrefix(long templateId, String prefix) { + SearchCriteria ssc = createSearchCriteria(); + ssc.addAnd("resouceId", SearchCriteria.Op.EQ, templateId); + ssc.addAnd("name", SearchCriteria.Op.LIKE, prefix + "%"); + + return search(ssc, null); + } + + @Override + public List listNetworkRequirementsByTemplateId(long templateId) { + List networkDetails = listDetailsByTemplateIdMatchingPrefix(templateId, DeployAsIsConstants.REQUIRED_NETWORK_PREFIX); + List networkPrereqs = new ArrayList<>(); + for (TemplateDeployAsIsDetailVO property : networkDetails) { + OVFNetworkTO ovfPropertyTO = gson.fromJson(property.getValue(), OVFNetworkTO.class); + networkPrereqs.add(ovfPropertyTO); + } + networkPrereqs.sort(new Comparator() { + @Override + public int compare(OVFNetworkTO o1, OVFNetworkTO o2) { + return o1.getInstanceID() - o2.getInstanceID(); + } + }); + return networkPrereqs; + } +} diff --git a/engine/schema/src/main/java/com/cloud/deployasis/dao/UserVmDeployAsIsDetailsDao.java b/engine/schema/src/main/java/com/cloud/deployasis/dao/UserVmDeployAsIsDetailsDao.java new file mode 100644 index 00000000000..4366e464c1e --- /dev/null +++ b/engine/schema/src/main/java/com/cloud/deployasis/dao/UserVmDeployAsIsDetailsDao.java @@ -0,0 +1,24 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 com.cloud.deployasis.dao; + +import com.cloud.deployasis.UserVmDeployAsIsDetailVO; +import com.cloud.utils.db.GenericDao; +import org.apache.cloudstack.resourcedetail.ResourceDetailsDao; + +public interface UserVmDeployAsIsDetailsDao extends GenericDao, ResourceDetailsDao { +} diff --git a/engine/schema/src/main/java/com/cloud/deployasis/dao/UserVmDeployAsIsDetailsDaoImpl.java b/engine/schema/src/main/java/com/cloud/deployasis/dao/UserVmDeployAsIsDetailsDaoImpl.java new file mode 100644 index 00000000000..8dc5f4a1204 --- /dev/null +++ b/engine/schema/src/main/java/com/cloud/deployasis/dao/UserVmDeployAsIsDetailsDaoImpl.java @@ -0,0 +1,30 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you 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 com.cloud.deployasis.dao; + +import com.cloud.deployasis.UserVmDeployAsIsDetailVO; +import org.apache.cloudstack.resourcedetail.ResourceDetailsDaoBase; +import org.springframework.stereotype.Component; + +@Component +public class UserVmDeployAsIsDetailsDaoImpl extends ResourceDetailsDaoBase implements UserVmDeployAsIsDetailsDao { + + @Override + public void addDetail(long resourceId, String key, String value, boolean display) { + super.addDetail(new UserVmDeployAsIsDetailVO(resourceId, key, value)); + } +} diff --git a/engine/schema/src/main/java/com/cloud/storage/VMTemplateDetailVO.java b/engine/schema/src/main/java/com/cloud/storage/VMTemplateDetailVO.java index 574f4fc500e..5010edfa762 100755 --- a/engine/schema/src/main/java/com/cloud/storage/VMTemplateDetailVO.java +++ b/engine/schema/src/main/java/com/cloud/storage/VMTemplateDetailVO.java @@ -21,7 +21,6 @@ import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; -import javax.persistence.Lob; import javax.persistence.Table; import org.apache.cloudstack.api.ResourceDetail; @@ -40,8 +39,7 @@ public class VMTemplateDetailVO implements ResourceDetail { @Column(name = "name") private String name; - @Lob - @Column(name = "value", length = 65535) + @Column(name = "value", length = 1024) private String value; @Column(name = "display") diff --git a/engine/schema/src/main/java/com/cloud/storage/dao/VMTemplateDetailsDao.java b/engine/schema/src/main/java/com/cloud/storage/dao/VMTemplateDetailsDao.java index 51c9cbbbb40..fe69630ae2e 100644 --- a/engine/schema/src/main/java/com/cloud/storage/dao/VMTemplateDetailsDao.java +++ b/engine/schema/src/main/java/com/cloud/storage/dao/VMTemplateDetailsDao.java @@ -16,25 +16,11 @@ // under the License. package com.cloud.storage.dao; -import com.cloud.agent.api.storage.OVFPropertyTO; -import com.cloud.agent.api.to.DatadiskTO; -import org.apache.cloudstack.api.net.NetworkPrerequisiteTO; import org.apache.cloudstack.resourcedetail.ResourceDetailsDao; import com.cloud.storage.VMTemplateDetailVO; import com.cloud.utils.db.GenericDao; -import java.util.List; - public interface VMTemplateDetailsDao extends GenericDao, ResourceDetailsDao { - boolean existsOption(long templateId, String key); - OVFPropertyTO findPropertyByTemplateAndKey(long templateId, String key); - void saveOptions(List opts); - List listPropertiesByTemplateId(long templateId); - List listNetworkRequirementsByTemplateId(long templateId); - List listDisksByTemplateId(long templateId); - - List listDetailsByTemplateIdMatchingPrefix(long templateId, String prefix); - String getTemplateEulaSectionsUrl(long templateId); } diff --git a/engine/schema/src/main/java/com/cloud/storage/dao/VMTemplateDetailsDaoImpl.java b/engine/schema/src/main/java/com/cloud/storage/dao/VMTemplateDetailsDaoImpl.java index d904e1a6de7..60e583be3e6 100644 --- a/engine/schema/src/main/java/com/cloud/storage/dao/VMTemplateDetailsDaoImpl.java +++ b/engine/schema/src/main/java/com/cloud/storage/dao/VMTemplateDetailsDaoImpl.java @@ -17,137 +17,17 @@ package com.cloud.storage.dao; -import java.util.ArrayList; -import java.util.Comparator; -import java.util.List; - -import org.apache.cloudstack.api.net.NetworkPrerequisiteTO; -import org.apache.cloudstack.resourcedetail.ResourceDetailsDaoBase; -import org.apache.commons.collections.CollectionUtils; -import org.apache.log4j.Logger; import org.springframework.stereotype.Component; -import com.cloud.agent.api.storage.OVFPropertyTO; -import com.cloud.agent.api.to.DatadiskTO; -import com.cloud.storage.ImageStore; +import org.apache.cloudstack.resourcedetail.ResourceDetailsDaoBase; + import com.cloud.storage.VMTemplateDetailVO; -import com.cloud.utils.db.SearchBuilder; -import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.TransactionLegacy; -import com.google.gson.Gson; @Component public class VMTemplateDetailsDaoImpl extends ResourceDetailsDaoBase implements VMTemplateDetailsDao { - private final static Logger LOGGER = Logger.getLogger(VMTemplateDetailsDaoImpl.class); - - Gson gson = new Gson(); - - SearchBuilder OptionsSearchBuilder; - - public VMTemplateDetailsDaoImpl() { - super(); - OptionsSearchBuilder = createSearchBuilder(); - OptionsSearchBuilder.and("resourceId", OptionsSearchBuilder.entity().getResourceId(), SearchCriteria.Op.EQ); - OptionsSearchBuilder.and("name", OptionsSearchBuilder.entity().getName(), SearchCriteria.Op.EQ); - OptionsSearchBuilder.done(); - } - @Override public void addDetail(long resourceId, String key, String value, boolean display) { super.addDetail(new VMTemplateDetailVO(resourceId, key, value, display)); } - - @Override - public boolean existsOption(long templateId, String key) { - return findPropertyByTemplateAndKey(templateId, key) != null; - } - - @Override - public OVFPropertyTO findPropertyByTemplateAndKey(long templateId, String key) { - SearchCriteria sc = OptionsSearchBuilder.create(); - sc.setParameters("resourceId", templateId); - sc.setParameters("name", key.startsWith(ImageStore.ACS_PROPERTY_PREFIX) ? key : ImageStore.ACS_PROPERTY_PREFIX + key); - OVFPropertyTO property = null; - VMTemplateDetailVO detail = findOneBy(sc); - if (detail != null) { - property = gson.fromJson(detail.getValue(), OVFPropertyTO.class); - } - return property; - } - - @Override - public void saveOptions(List opts) { - if (CollectionUtils.isEmpty(opts)) { - return; - } - TransactionLegacy txn = TransactionLegacy.currentTxn(); - txn.start(); - for (OVFPropertyTO opt : opts) { - String json = gson.toJson(opt); - VMTemplateDetailVO templateDetailVO = new VMTemplateDetailVO(opt.getTemplateId(), ImageStore.ACS_PROPERTY_PREFIX + opt.getKey(), json, opt.isUserConfigurable()); - persist(templateDetailVO); - } - txn.commit(); - } - - @Override - public List listPropertiesByTemplateId(long templateId) { - List ovfProperties = listDetailsByTemplateIdMatchingPrefix(templateId, ImageStore.ACS_PROPERTY_PREFIX); - List properties = new ArrayList<>(); - for (VMTemplateDetailVO property : ovfProperties) { - OVFPropertyTO ovfPropertyTO = gson.fromJson(property.getValue(), OVFPropertyTO.class); - properties.add(ovfPropertyTO); - } - return properties; - } - - @Override - public List listNetworkRequirementsByTemplateId(long templateId) { - List networkDetails = listDetailsByTemplateIdMatchingPrefix(templateId, ImageStore.REQUIRED_NETWORK_PREFIX); - List networkPrereqs = new ArrayList<>(); - for (VMTemplateDetailVO property : networkDetails) { - NetworkPrerequisiteTO ovfPropertyTO = gson.fromJson(property.getValue(), NetworkPrerequisiteTO.class); - networkPrereqs.add(ovfPropertyTO); - } - networkPrereqs.sort(new Comparator() { - @Override - public int compare(NetworkPrerequisiteTO o1, NetworkPrerequisiteTO o2) { - return o1.getInstanceID() - o2.getInstanceID(); - } - }); - return networkPrereqs; - } - - @Override - public List listDisksByTemplateId(long templateId) { - List diskDefinitions = listDetailsByTemplateIdMatchingPrefix(templateId, ImageStore.DISK_DEFINITION_PREFIX); - List disks = new ArrayList<>(); - for (VMTemplateDetailVO detail : diskDefinitions) { - DatadiskTO datadiskTO = gson.fromJson(detail.getValue(), DatadiskTO.class); - disks.add(datadiskTO); - } - return disks; - } - - @Override - public List listDetailsByTemplateIdMatchingPrefix(long templateId, String prefix) { - SearchCriteria ssc = createSearchCriteria(); - ssc.addAnd("resourceId", SearchCriteria.Op.EQ, templateId); - ssc.addAnd("name", SearchCriteria.Op.LIKE, prefix + "%"); - - return search(ssc, null); - } - - @Override - public String getTemplateEulaSectionsUrl(long templateId) { - List details = findDetails(templateId, ImageStore.OVF_EULA_SECTION_PREFIX); - if (CollectionUtils.isEmpty(details)) { - return null; - } - if (details.size() > 1) { - LOGGER.error("Multiple details for EULA sections for template " + templateId + " returning one"); - } - return details.get(0).getValue(); - } } \ No newline at end of file diff --git a/engine/schema/src/main/java/com/cloud/vm/dao/UserVmDaoImpl.java b/engine/schema/src/main/java/com/cloud/vm/dao/UserVmDaoImpl.java index 6bf0dc23168..25479d6658a 100644 --- a/engine/schema/src/main/java/com/cloud/vm/dao/UserVmDaoImpl.java +++ b/engine/schema/src/main/java/com/cloud/vm/dao/UserVmDaoImpl.java @@ -30,7 +30,6 @@ import javax.annotation.PostConstruct; import javax.inject.Inject; import com.cloud.offerings.dao.NetworkOfferingServiceMapDao; -import com.cloud.storage.ImageStore; import org.apache.commons.collections.CollectionUtils; import org.apache.log4j.Logger; @@ -383,25 +382,13 @@ public class UserVmDaoImpl extends GenericDaoBase implements Use List details = new ArrayList(); for (Map.Entry entry : detailsStr.entrySet()) { - boolean display = visibilityMap.getOrDefault(entry.getKey(), true) && displayOVFDetails(entry.getKey()); + boolean display = visibilityMap.getOrDefault(entry.getKey(), true); details.add(new UserVmDetailVO(vm.getId(), entry.getKey(), entry.getValue(), display)); } _detailsDao.saveDetails(details); } - /* - Do not display VM properties parsed from OVF, handled internally - */ - private boolean displayOVFDetails(String key) { - if (key.startsWith(ImageStore.ACS_PROPERTY_PREFIX) || key.startsWith(ImageStore.OVF_HARDWARE_ITEM_PREFIX) || - key.startsWith(ImageStore.OVF_HARDWARE_CONFIGURATION_PREFIX) || key.startsWith(ImageStore.DISK_DEFINITION_PREFIX) || - key.startsWith(ImageStore.REQUIRED_NETWORK_PREFIX) || key.startsWith(ImageStore.OVF_EULA_SECTION_PREFIX)) { - return false; - } - return true; - } - @Override public List listPodIdsHavingVmsforAccount(long zoneId, long accountId) { TransactionLegacy txn = TransactionLegacy.currentTxn(); diff --git a/engine/schema/src/main/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml b/engine/schema/src/main/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml index cde3518e7d2..67b40101d55 100644 --- a/engine/schema/src/main/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml +++ b/engine/schema/src/main/resources/META-INF/cloudstack/core/spring-engine-schema-core-daos-context.xml @@ -295,4 +295,6 @@ + + diff --git a/engine/schema/src/main/resources/META-INF/db/schema-41400to41500.sql b/engine/schema/src/main/resources/META-INF/db/schema-41400to41500.sql index b7e94cc0e86..12c2a8e12ba 100644 --- a/engine/schema/src/main/resources/META-INF/db/schema-41400to41500.sql +++ b/engine/schema/src/main/resources/META-INF/db/schema-41400to41500.sql @@ -473,6 +473,92 @@ ADD CONSTRAINT `fk_template_spool_ref__template_id` ON DELETE NO ACTION ON UPDATE NO ACTION; + +CREATE TABLE IF NOT EXISTS `cloud`.`vsphere_storage_policy` ( + `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT, + `uuid` varchar(255) UNIQUE, + `zone_id` bigint(20) unsigned NOT NULL COMMENT 'id of the zone', + `policy_id` varchar(255) NOT NULL COMMENT 'the identifier of the Storage Policy in vSphere DataCenter', + `name` varchar(255) NOT NULL COMMENT 'name of the storage policy', + `description` text COMMENT 'description of the storage policy', + `update_time` datetime COMMENT 'last updated when policy imported', + `removed` datetime COMMENT 'date removed', + PRIMARY KEY (`id`), + KEY `fk_vsphere_storage_policy__zone_id` (`zone_id`), + UNIQUE KEY (`zone_id`, `policy_id`), + CONSTRAINT `fk_vsphere_storage_policy__zone_id` FOREIGN KEY (`zone_id`) REFERENCES `data_center` (`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +ALTER TABLE `cloud`.`storage_pool` ADD COLUMN `parent` BIGINT(20) UNSIGNED NOT NULL DEFAULT 0 COMMENT 'ID of the Datastore cluster (storage pool) if this is a child in that Datastore cluster'; + +-- Added parent column to support datastore clusters in vmware vsphere +DROP VIEW IF EXISTS `cloud`.`storage_pool_view`; +CREATE VIEW `cloud`.`storage_pool_view` AS + SELECT + `storage_pool`.`id` AS `id`, + `storage_pool`.`uuid` AS `uuid`, + `storage_pool`.`name` AS `name`, + `storage_pool`.`status` AS `status`, + `storage_pool`.`path` AS `path`, + `storage_pool`.`pool_type` AS `pool_type`, + `storage_pool`.`host_address` AS `host_address`, + `storage_pool`.`created` AS `created`, + `storage_pool`.`removed` AS `removed`, + `storage_pool`.`capacity_bytes` AS `capacity_bytes`, + `storage_pool`.`capacity_iops` AS `capacity_iops`, + `storage_pool`.`scope` AS `scope`, + `storage_pool`.`hypervisor` AS `hypervisor`, + `storage_pool`.`storage_provider_name` AS `storage_provider_name`, + `storage_pool`.`parent` AS `parent`, + `cluster`.`id` AS `cluster_id`, + `cluster`.`uuid` AS `cluster_uuid`, + `cluster`.`name` AS `cluster_name`, + `cluster`.`cluster_type` AS `cluster_type`, + `data_center`.`id` AS `data_center_id`, + `data_center`.`uuid` AS `data_center_uuid`, + `data_center`.`name` AS `data_center_name`, + `data_center`.`networktype` AS `data_center_type`, + `host_pod_ref`.`id` AS `pod_id`, + `host_pod_ref`.`uuid` AS `pod_uuid`, + `host_pod_ref`.`name` AS `pod_name`, + `storage_pool_tags`.`tag` AS `tag`, + `op_host_capacity`.`used_capacity` AS `disk_used_capacity`, + `op_host_capacity`.`reserved_capacity` AS `disk_reserved_capacity`, + `async_job`.`id` AS `job_id`, + `async_job`.`uuid` AS `job_uuid`, + `async_job`.`job_status` AS `job_status`, + `async_job`.`account_id` AS `job_account_id` + FROM + ((((((`storage_pool` + LEFT JOIN `cluster` ON ((`storage_pool`.`cluster_id` = `cluster`.`id`))) + LEFT JOIN `data_center` ON ((`storage_pool`.`data_center_id` = `data_center`.`id`))) + LEFT JOIN `host_pod_ref` ON ((`storage_pool`.`pod_id` = `host_pod_ref`.`id`))) + LEFT JOIN `storage_pool_tags` ON (((`storage_pool_tags`.`pool_id` = `storage_pool`.`id`)))) + LEFT JOIN `op_host_capacity` ON (((`storage_pool`.`id` = `op_host_capacity`.`host_id`) + AND (`op_host_capacity`.`capacity_type` IN (3 , 9))))) + LEFT JOIN `async_job` ON (((`async_job`.`instance_id` = `storage_pool`.`id`) + AND (`async_job`.`instance_type` = 'StoragePool') + AND (`async_job`.`job_status` = 0)))); + + +CREATE TABLE `cloud`.`template_deploy_as_is_details` ( + `id` bigint unsigned NOT NULL auto_increment, + `template_id` bigint unsigned NOT NULL COMMENT 'template id', + `name` varchar(255) NOT NULL, + `value` TEXT, + PRIMARY KEY (`id`), + CONSTRAINT `fk_template_deploy_as_is_details__template_id` FOREIGN KEY `fk_template_deploy_as_is_details__template_id`(`template_id`) REFERENCES `vm_template`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +CREATE TABLE `cloud`.`user_vm_deploy_as_is_details` ( + `id` bigint unsigned NOT NULL auto_increment, + `vm_id` bigint unsigned NOT NULL COMMENT 'virtual machine id', + `name` varchar(255) NOT NULL, + `value` TEXT, + PRIMARY KEY (`id`), + CONSTRAINT `fk_user_vm_deploy_as_is_details__vm_id` FOREIGN KEY `fk_user_vm_deploy_as_is_details__vm_id`(`vm_id`) REFERENCES `vm_instance`(`id`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + ALTER TABLE `cloud`.`image_store` ADD COLUMN `readonly` boolean DEFAULT false COMMENT 'defines status of image store'; ALTER VIEW `cloud`.`image_store_view` AS diff --git a/engine/storage/src/main/java/org/apache/cloudstack/storage/image/BaseImageStoreDriverImpl.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/image/BaseImageStoreDriverImpl.java index 77d97793405..58c24537d57 100644 --- a/engine/storage/src/main/java/org/apache/cloudstack/storage/image/BaseImageStoreDriverImpl.java +++ b/engine/storage/src/main/java/org/apache/cloudstack/storage/image/BaseImageStoreDriverImpl.java @@ -18,7 +18,6 @@ */ package org.apache.cloudstack.storage.image; -import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; import java.sql.PreparedStatement; @@ -33,19 +32,8 @@ import java.util.stream.Collectors; import javax.inject.Inject; -import com.cloud.agent.api.storage.OVFConfigurationTO; -import com.cloud.agent.api.storage.OVFEulaSectionTO; -import com.cloud.agent.api.storage.OVFPropertyTO; -import com.cloud.agent.api.storage.OVFVirtualHardwareItemTO; -import com.cloud.agent.api.storage.OVFVirtualHardwareSectionTO; -import com.cloud.storage.ImageStore; import com.cloud.storage.Upload; -import com.cloud.storage.VMTemplateDetailVO; -import com.cloud.utils.compression.CompressionUtil; -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import org.apache.cloudstack.api.net.NetworkPrerequisiteTO; -import org.apache.commons.collections.CollectionUtils; +import org.apache.cloudstack.storage.image.deployasis.DeployAsIsHelper; import org.apache.log4j.Logger; import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; @@ -89,7 +77,6 @@ import com.cloud.storage.VMTemplateStorageResourceAssoc; import com.cloud.storage.VMTemplateVO; import com.cloud.storage.VolumeVO; import com.cloud.storage.dao.VMTemplateDao; -import com.cloud.storage.dao.VMTemplateDetailsDao; import com.cloud.storage.dao.VMTemplateZoneDao; import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.download.DownloadMonitor; @@ -123,14 +110,14 @@ public abstract class BaseImageStoreDriverImpl implements ImageStoreDriver { @Inject AlertManager _alertMgr; @Inject - VMTemplateDetailsDao templateDetailsDao; - @Inject DefaultEndPointSelector _defaultEpSelector; @Inject AccountDao _accountDao; @Inject ResourceLimitService _resourceLimitMgr; @Inject + DeployAsIsHelper deployAsIsHelper; + @Inject HostDao hostDao; @Inject CommandExecLogDao _cmdExecLogDao; @@ -143,14 +130,6 @@ public abstract class BaseImageStoreDriverImpl implements ImageStoreDriver { protected String _proxy = null; - private static Gson gson; - - static { - GsonBuilder builder = new GsonBuilder(); - builder.disableHtmlEscaping(); - gson = builder.create(); - } - protected Proxy getHttpProxy() { if (_proxy == null) { return null; @@ -211,91 +190,6 @@ public abstract class BaseImageStoreDriverImpl implements ImageStoreDriver { } } - /** - * Persist OVF properties as template details for template with id = templateId - */ - private void persistOVFProperties(List ovfProperties, long templateId) { - if (LOGGER.isTraceEnabled()) { - LOGGER.trace(String.format("saving properties for template %d as details", templateId)); - } - for (OVFPropertyTO property : ovfProperties) { - if (LOGGER.isTraceEnabled()) { - LOGGER.trace(String.format("saving property %s for template %d as detail", property.getKey(), templateId)); - } - persistOvfPropertyAsSetOfTemplateDetails(templateId, property); - } - } - - private void persistOvfPropertyAsSetOfTemplateDetails(long templateId, OVFPropertyTO property) { - String key = property.getKey(); - String propKey = ImageStore.ACS_PROPERTY_PREFIX + key; - try { - String propValue = gson.toJson(property); - savePropertyAttribute(templateId, propKey, propValue); - } catch (RuntimeException re) { - LOGGER.error("gson marshalling of property object fails: " + propKey,re); - } - } - - private void persistNetworkRequirements(List networkRequirements, long templateId) { - if (LOGGER.isTraceEnabled()) { - LOGGER.trace(String.format("saving network requirements for template %d as details", templateId)); - } - for (NetworkPrerequisiteTO network : networkRequirements) { - if (LOGGER.isTraceEnabled()) { - LOGGER.trace(String.format("saving property %s for template %d as detail", network.getName(), templateId)); - } - persistRequiredNetworkAsASingleTemplateDetail(templateId, network); - } - } - - private void persistDiskDefinitions(List disks, long templateId) { - if (LOGGER.isTraceEnabled()) { - LOGGER.trace(String.format("saving disk definitionsn for template %d as details", templateId)); - } - for (DatadiskTO disk : disks) { - if (LOGGER.isTraceEnabled()) { - LOGGER.trace(String.format("saving property %s for template %d as detail", disk.getDiskId(), templateId)); - } - persistDiskDefinitionAsASingleTemplateDetail(templateId, disk); - } - } - - private void persistRequiredNetworkAsASingleTemplateDetail(long templateId, NetworkPrerequisiteTO network) { - String key = network.getName(); - String propKey = ImageStore.REQUIRED_NETWORK_PREFIX + key; - try { - String propValue = gson.toJson(network); - savePropertyAttribute(templateId, propKey, propValue); - } catch (RuntimeException re) { - LOGGER.warn("gson marshalling of network object fails: " + propKey,re); - } - } - - private void persistDiskDefinitionAsASingleTemplateDetail(long templateId, DatadiskTO disk) { - String key = disk.getDiskId(); - String propKey = ImageStore.DISK_DEFINITION_PREFIX + key; - try { - String propValue = gson.toJson(disk); - savePropertyAttribute(templateId, propKey, propValue); - } catch (RuntimeException re) { - LOGGER.warn("gson marshalling of disk definition object fails: " + propKey,re); - } - } - - private void savePropertyAttribute(long templateId, String key, String value) { - if ( templateDetailsDao.findDetail(templateId,key) != null) { - LOGGER.debug(String.format("detail '%s' existed for template %d, deleting.", key, templateId)); - templateDetailsDao.removeDetail(templateId,key); - } - if (LOGGER.isTraceEnabled()) { - LOGGER.trace(String.format("template detail for template %d to save is '%s': '%s'", templateId, key, value)); - } - VMTemplateDetailVO detailVO = new VMTemplateDetailVO(templateId, key, value, false); - LOGGER.debug("Persisting template details " + detailVO.getName() + " from OVF properties for template " + templateId); - templateDetailsDao.persist(detailVO); - } - protected Void createTemplateAsyncCallback(AsyncCallbackDispatcher callback, CreateContext context) { if (LOGGER.isDebugEnabled()) { @@ -304,17 +198,14 @@ public abstract class BaseImageStoreDriverImpl implements ImageStoreDriver { DownloadAnswer answer = callback.getResult(); DataObject obj = context.data; DataStore store = obj.getDataStore(); - List ovfProperties = answer.getOvfProperties(); - List networkRequirements = answer.getNetworkRequirements(); - List disks = answer.getDisks(); - OVFVirtualHardwareSectionTO ovfHardwareSection = answer.getOvfHardwareSection(); - List eulaSections = answer.getEulaSections(); VMTemplateVO template = _templateDao.findById(obj.getId()); TemplateDataStoreVO tmpltStoreVO = _templateStoreDao.findByStoreTemplate(store.getId(), obj.getId()); if (tmpltStoreVO != null) { if (tmpltStoreVO.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) { - persistExtraDetails(obj, ovfProperties, networkRequirements, disks, ovfHardwareSection, eulaSections); + if (template.isDeployAsIs()) { + deployAsIsHelper.persistTemplateDeployAsIsDetails(template.getId(), answer); + } if (LOGGER.isDebugEnabled()) { LOGGER.debug("Template is already in DOWNLOADED state, ignore further incoming DownloadAnswer"); } @@ -354,7 +245,9 @@ public abstract class BaseImageStoreDriverImpl implements ImageStoreDriver { templateDaoBuilder.setChecksum(answer.getCheckSum()); _templateDao.update(obj.getId(), templateDaoBuilder); } - persistExtraDetails(obj, ovfProperties, networkRequirements, disks, ovfHardwareSection, eulaSections); + if (template.isDeployAsIs()) { + deployAsIsHelper.persistTemplateDeployAsIsDetails(template.getId(), answer); + } CreateCmdResult result = new CreateCmdResult(null, null); caller.complete(result); @@ -362,76 +255,6 @@ public abstract class BaseImageStoreDriverImpl implements ImageStoreDriver { return null; } - private void persistExtraDetails(DataObject obj, List ovfProperties, List networkRequirements, List disks, OVFVirtualHardwareSectionTO ovfHardwareSection, List eulaSections) { - if (LOGGER.isTraceEnabled()) { - LOGGER.trace(String.format("saving %d ovf properties for template '%s' as details", ovfProperties != null ? ovfProperties.size() : 0, obj.getUuid())); - } - if (CollectionUtils.isNotEmpty(ovfProperties)) { - persistOVFProperties(ovfProperties, obj.getId()); - } - if (LOGGER.isTraceEnabled()) { - LOGGER.trace(String.format("saving %d required network requirements for template '%s' as details", networkRequirements != null ? networkRequirements.size() : 0, obj.getUuid())); - } - if (CollectionUtils.isNotEmpty(networkRequirements)) { - persistNetworkRequirements(networkRequirements, obj.getId()); - } - if (LOGGER.isTraceEnabled()) { - LOGGER.trace(String.format("saving %d disks definitions for template '%s' as details", disks != null ? disks.size() : 0, obj.getUuid())); - } - if (CollectionUtils.isNotEmpty(disks)) { - persistDiskDefinitions(disks, obj.getId()); - } - if (CollectionUtils.isNotEmpty(eulaSections)) { - persistEulaSectionsAsTemplateDetails(eulaSections, obj.getId()); - } - persistOVFHardwareSectionAsTemplateDetails(ovfHardwareSection, obj.getId()); - } - - private void persistEulaSectionsAsTemplateDetails(List eulaSections, long templateId) { - CompressionUtil compressionUtil = new CompressionUtil(); - for (OVFEulaSectionTO eulaSectionTO : eulaSections) { - String key = ImageStore.OVF_EULA_SECTION_PREFIX + eulaSectionTO.getIndex() + "-" + eulaSectionTO.getInfo(); - byte[] compressedLicense = eulaSectionTO.getCompressedLicense(); - try { - String detailValue = compressionUtil.decompressByteArary(compressedLicense); - savePropertyAttribute(templateId, key, detailValue); - } catch (IOException e) { - LOGGER.error("Could not decompress the license for template " + templateId, e); - } - } - } - - /** - * Persist template details for template with ID=templateId, with name=key and value=json(object) - */ - private void persistTemplateDetailGsonEncoded(long templateId, String key, Object object) { - try { - String propValue = gson.toJson(object); - savePropertyAttribute(templateId, key, propValue); - } catch (RuntimeException re) { - LOGGER.error("gson marshalling of property object fails: " + key, re); - } - } - - private void persistOVFHardwareSectionAsTemplateDetails(OVFVirtualHardwareSectionTO ovfHardwareSection, long templateId) { - if (ovfHardwareSection != null) { - if (CollectionUtils.isNotEmpty(ovfHardwareSection.getConfigurations())) { - for (OVFConfigurationTO configuration : ovfHardwareSection.getConfigurations()) { - String key = configuration.getId(); - String propKey = ImageStore.OVF_HARDWARE_CONFIGURATION_PREFIX + configuration.getIndex() + "-" + key; - persistTemplateDetailGsonEncoded(templateId, propKey, configuration); - } - } - if (CollectionUtils.isNotEmpty(ovfHardwareSection.getCommonHardwareItems())) { - for (OVFVirtualHardwareItemTO item : ovfHardwareSection.getCommonHardwareItems()) { - String key = item.getResourceType().getName().trim().replaceAll("\\s","") + "-" + item.getInstanceId(); - String propKey = ImageStore.OVF_HARDWARE_ITEM_PREFIX + key; - persistTemplateDetailGsonEncoded(templateId, propKey, item); - } - } - } - } - protected Void createVolumeAsyncCallback(AsyncCallbackDispatcher callback, CreateContext context) { DownloadAnswer answer = callback.getResult(); diff --git a/engine/storage/src/main/java/org/apache/cloudstack/storage/image/deployasis/DeployAsIsHelper.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/image/deployasis/DeployAsIsHelper.java new file mode 100644 index 00000000000..b23326b0406 --- /dev/null +++ b/engine/storage/src/main/java/org/apache/cloudstack/storage/image/deployasis/DeployAsIsHelper.java @@ -0,0 +1,15 @@ +package org.apache.cloudstack.storage.image.deployasis; + +import com.cloud.agent.api.storage.DownloadAnswer; +import com.cloud.vm.VirtualMachineProfile; + +import java.util.Map; + +public interface DeployAsIsHelper { + + void persistTemplateDeployAsIsDetails(long templateId, DownloadAnswer answer); + Map getVirtualMachineDeployAsIsProperties(VirtualMachineProfile vmId); + + String getAllocatedVirtualMachineTemplatePath(VirtualMachineProfile vm, String configuration, String destStoragePool); + String getAllocatedVirtualMachineDestinationStoragePool(VirtualMachineProfile vm); +} diff --git a/engine/storage/src/main/java/org/apache/cloudstack/storage/image/deployasis/DeployAsIsHelperImpl.java b/engine/storage/src/main/java/org/apache/cloudstack/storage/image/deployasis/DeployAsIsHelperImpl.java new file mode 100644 index 00000000000..69982cd798d --- /dev/null +++ b/engine/storage/src/main/java/org/apache/cloudstack/storage/image/deployasis/DeployAsIsHelperImpl.java @@ -0,0 +1,212 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you 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.apache.cloudstack.storage.image.deployasis; + +import com.cloud.agent.api.storage.DownloadAnswer; +import com.cloud.agent.api.to.DataStoreTO; +import com.cloud.agent.api.to.DataTO; +import com.cloud.agent.api.to.DiskTO; +import com.cloud.agent.api.to.deployasis.OVFConfigurationTO; +import com.cloud.agent.api.to.deployasis.OVFEulaSectionTO; +import com.cloud.agent.api.to.deployasis.OVFPropertyTO; +import com.cloud.agent.api.to.deployasis.OVFVirtualHardwareItemTO; +import com.cloud.agent.api.to.deployasis.OVFVirtualHardwareSectionTO; +import com.cloud.agent.api.to.deployasis.TemplateDeployAsIsInformationTO; +import com.cloud.deployasis.DeployAsIsConstants; +import com.cloud.deployasis.TemplateDeployAsIsDetailVO; +import com.cloud.deployasis.UserVmDeployAsIsDetailVO; +import com.cloud.deployasis.dao.TemplateDeployAsIsDetailsDao; +import com.cloud.deployasis.dao.UserVmDeployAsIsDetailsDao; +import com.cloud.storage.VMTemplateStoragePoolVO; +import com.cloud.storage.Volume; +import com.cloud.storage.dao.VMTemplatePoolDao; +import com.cloud.utils.compression.CompressionUtil; +import com.cloud.utils.crypt.DBEncryptionUtil; +import com.cloud.vm.VirtualMachineProfile; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.cloud.agent.api.to.deployasis.OVFNetworkTO; +import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; +import org.apache.commons.collections.CollectionUtils; +import org.apache.log4j.Logger; +import org.springframework.stereotype.Component; + +import javax.inject.Inject; +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Component +public class DeployAsIsHelperImpl implements DeployAsIsHelper { + + private static final Logger LOGGER = Logger.getLogger(DeployAsIsHelperImpl.class); + private static Gson gson; + + @Inject + private TemplateDeployAsIsDetailsDao templateDeployAsIsDetailsDao; + @Inject + private UserVmDeployAsIsDetailsDao userVmDeployAsIsDetailsDao; + @Inject + private PrimaryDataStoreDao storagePoolDao; + @Inject + private VMTemplatePoolDao templateStoragePoolDao; + + static { + GsonBuilder builder = new GsonBuilder(); + builder.disableHtmlEscaping(); + gson = builder.create(); + } + + public void persistTemplateDeployAsIsDetails(long templateId, DownloadAnswer answer) { + List ovfProperties = answer.getOvfProperties(); + List networkRequirements = answer.getNetworkRequirements(); + OVFVirtualHardwareSectionTO ovfHardwareSection = answer.getOvfHardwareSection(); + List eulaSections = answer.getEulaSections(); + + if (CollectionUtils.isNotEmpty(ovfProperties)) { + persistTemplateDeployAsIsInformationTOList(templateId, ovfProperties); + } + if (CollectionUtils.isNotEmpty(networkRequirements)) { + persistTemplateDeployAsIsInformationTOList(templateId, networkRequirements); + } + if (CollectionUtils.isNotEmpty(eulaSections)) { + persistTemplateDeployAsIsInformationTOList(templateId, eulaSections); + } + if (ovfHardwareSection != null) { + if (CollectionUtils.isNotEmpty(ovfHardwareSection.getConfigurations())) { + persistTemplateDeployAsIsInformationTOList(templateId, ovfHardwareSection.getConfigurations()); + } + if (CollectionUtils.isNotEmpty(ovfHardwareSection.getCommonHardwareItems())) { + persistTemplateDeployAsIsInformationTOList(templateId, ovfHardwareSection.getCommonHardwareItems()); + } + } + } + + @Override + public Map getVirtualMachineDeployAsIsProperties(VirtualMachineProfile vm) { + Map map = new HashMap<>(); + List details = userVmDeployAsIsDetailsDao.listDetails(vm.getId()); + if (CollectionUtils.isNotEmpty(details)) { + for (UserVmDeployAsIsDetailVO detail : details) { + OVFPropertyTO property = templateDeployAsIsDetailsDao.findPropertyByTemplateAndKey(vm.getTemplateId(), detail.getName()); + String value = property.isPassword() ? DBEncryptionUtil.decrypt(detail.getValue()) : detail.getValue(); + map.put(detail.getName(), value); + } + } + return map; + } + + @Override + public String getAllocatedVirtualMachineTemplatePath(VirtualMachineProfile vm, String configuration, String destStoragePool) { + StoragePoolVO storagePoolVO = storagePoolDao.findByUuid(destStoragePool); + VMTemplateStoragePoolVO tmplRef = templateStoragePoolDao.findByPoolTemplate(storagePoolVO.getId(), + vm.getTemplate().getId(), configuration); + if (tmplRef != null) { + return tmplRef.getInstallPath(); + } + return null; + } + + @Override + public String getAllocatedVirtualMachineDestinationStoragePool(VirtualMachineProfile vm) { + if (vm != null) { + if (CollectionUtils.isNotEmpty(vm.getDisks())) { + for (DiskTO disk : vm.getDisks()) { + if (disk.getType() == Volume.Type.ISO) { + continue; + } + DataTO data = disk.getData(); + if (data != null) { + DataStoreTO dataStore = data.getDataStore(); + if (dataStore != null) { + return dataStore.getUuid(); + } + } + } + } + } + return null; + } + + private void persistTemplateDeployAsIsInformationTOList(long templateId, + List informationTOList) { + for (TemplateDeployAsIsInformationTO informationTO : informationTOList) { + String propKey = getKeyFromInformationTO(informationTO); + if (LOGGER.isTraceEnabled()) { + LOGGER.trace(String.format("Saving property %s for template %d as detail", propKey, templateId)); + } + String propValue = null; + try { + propValue = getValueFromInformationTO(informationTO); + } catch (RuntimeException re) { + LOGGER.error("gson marshalling of property object fails: " + propKey,re); + } catch (IOException e) { + LOGGER.error("Could not decompress the license for template " + templateId, e); + } + saveTemplateDeployAsIsPropertyAttribute(templateId, propKey, propValue); + } + } + + private String getValueFromInformationTO(TemplateDeployAsIsInformationTO informationTO) throws IOException { + if (informationTO instanceof OVFEulaSectionTO) { + CompressionUtil compressionUtil = new CompressionUtil(); + byte[] compressedLicense = ((OVFEulaSectionTO) informationTO).getCompressedLicense(); + return compressionUtil.decompressByteArary(compressedLicense); + } + return gson.toJson(informationTO); + } + + private String getKeyFromInformationTO(TemplateDeployAsIsInformationTO informationTO) { + if (informationTO instanceof OVFPropertyTO) { + return DeployAsIsConstants.ACS_PROPERTY_PREFIX + ((OVFPropertyTO) informationTO).getKey(); + } else if (informationTO instanceof OVFNetworkTO) { + return DeployAsIsConstants.REQUIRED_NETWORK_PREFIX + ((OVFNetworkTO) informationTO).getName(); + } else if (informationTO instanceof OVFConfigurationTO) { + return DeployAsIsConstants.OVF_HARDWARE_CONFIGURATION_PREFIX + + ((OVFConfigurationTO) informationTO).getIndex() + "-" + ((OVFConfigurationTO) informationTO).getId(); + } else if (informationTO instanceof OVFVirtualHardwareItemTO) { + String key = ((OVFVirtualHardwareItemTO) informationTO).getResourceType().getName().trim().replaceAll("\\s","") + + "-" + ((OVFVirtualHardwareItemTO) informationTO).getInstanceId(); + return DeployAsIsConstants.OVF_HARDWARE_ITEM_PREFIX + key; + } else if (informationTO instanceof OVFEulaSectionTO) { + return DeployAsIsConstants.OVF_EULA_SECTION_PREFIX + ((OVFEulaSectionTO) informationTO).getIndex() + + "-" + ((OVFEulaSectionTO) informationTO).getInfo(); + } + return null; + } + + private void saveTemplateDeployAsIsPropertyAttribute(long templateId, String key, String value) { + if (LOGGER.isTraceEnabled()) { + LOGGER.trace(String.format("Saving property %s for template %d as detail", key, templateId)); + } + if (templateDeployAsIsDetailsDao.findDetail(templateId,key) != null) { + LOGGER.debug(String.format("Detail '%s' existed for template %d, deleting.", key, templateId)); + templateDeployAsIsDetailsDao.removeDetail(templateId,key); + } + if (LOGGER.isTraceEnabled()) { + LOGGER.trace(String.format("Template detail for template %d to save is '%s': '%s'", templateId, key, value)); + } + TemplateDeployAsIsDetailVO detailVO = new TemplateDeployAsIsDetailVO(templateId, key, value); + LOGGER.debug("Persisting template details " + detailVO.getName() + " from OVF properties for template " + templateId); + templateDeployAsIsDetailsDao.persist(detailVO); + } + +} diff --git a/engine/storage/src/main/resources/META-INF/cloudstack/core/spring-engine-storage-core-context.xml b/engine/storage/src/main/resources/META-INF/cloudstack/core/spring-engine-storage-core-context.xml index 33385b5ae00..5cecb224125 100644 --- a/engine/storage/src/main/resources/META-INF/cloudstack/core/spring-engine-storage-core-context.xml +++ b/engine/storage/src/main/resources/META-INF/cloudstack/core/spring-engine-storage-core-context.xml @@ -72,4 +72,6 @@ + + diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/guru/VmwareVmImplementer.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/guru/VmwareVmImplementer.java index 7ffc88af531..56a875d8ab2 100644 --- a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/guru/VmwareVmImplementer.java +++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/guru/VmwareVmImplementer.java @@ -16,9 +16,7 @@ // under the License. package com.cloud.hypervisor.guru; -import com.cloud.agent.api.storage.OVFPropertyTO; import com.cloud.agent.api.to.DeployAsIsInfoTO; -import com.cloud.agent.api.to.DiskTO; import com.cloud.agent.api.to.NicTO; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.exception.InsufficientAddressCapacityException; @@ -35,12 +33,8 @@ import com.cloud.network.dao.NetworkDao; import com.cloud.network.dao.NetworkVO; import com.cloud.storage.GuestOSHypervisorVO; import com.cloud.storage.GuestOSVO; -import com.cloud.storage.ImageStore; -import com.cloud.storage.VMTemplateStoragePoolVO; -import com.cloud.storage.Volume; import com.cloud.storage.dao.GuestOSDao; import com.cloud.storage.dao.GuestOSHypervisorDao; -import com.cloud.storage.dao.VMTemplateDetailsDao; import com.cloud.storage.dao.VMTemplatePoolDao; import com.cloud.template.VirtualMachineTemplate; import com.cloud.utils.exception.CloudRuntimeException; @@ -51,10 +45,8 @@ import com.cloud.vm.VirtualMachineProfile; import com.cloud.vm.VmDetailConstants; import com.cloud.vm.dao.DomainRouterDao; import com.cloud.vm.dao.NicDao; -import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao; -import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; -import org.apache.commons.collections.CollectionUtils; +import org.apache.cloudstack.storage.image.deployasis.DeployAsIsHelper; import org.apache.commons.lang.BooleanUtils; import org.apache.log4j.Logger; @@ -65,7 +57,6 @@ import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.stream.Collectors; class VmwareVmImplementer { private static final Logger LOGGER = Logger.getLogger(VmwareVmImplementer.class); @@ -89,9 +80,9 @@ class VmwareVmImplementer { @Inject VMTemplatePoolDao templateStoragePoolDao; @Inject - VMTemplateDetailsDao templateDetailsDao; - @Inject VmwareManager vmwareMgr; + @Inject + DeployAsIsHelper deployAsIsHelper; private Boolean globalNestedVirtualisationEnabled; private Boolean globalNestedVPerVMEnabled; @@ -183,9 +174,7 @@ class VmwareVmImplementer { } if (deployAsIs) { - List ovfProperties = getOvfPropertyList(vm, details); - handleOvfProperties(vm, to, details, ovfProperties); - setDeployAsIsParams(vm, to, details); + setDeployAsIsInfoTO(vm, to, details); } setDetails(to, details); @@ -193,44 +182,25 @@ class VmwareVmImplementer { return to; } - private void setDeployAsIsParams(VirtualMachineProfile vm, VirtualMachineTO to, Map details) { - DeployAsIsInfoTO info = new DeployAsIsInfoTO(); - - String configuration = null; - if (details.containsKey(VmDetailConstants.DEPLOY_AS_IS_CONFIGURATION)) { - configuration = details.get(VmDetailConstants.DEPLOY_AS_IS_CONFIGURATION); - info.setDeploymentConfiguration(configuration); - } - - // Deploy as-is disks are all allocated to the same storage pool - String deployAsIsStoreUuid = vm.getDisks().get(0).getData().getDataStore().getUuid(); - StoragePoolVO storagePoolVO = storagePoolDao.findByUuid(deployAsIsStoreUuid); - VMTemplateStoragePoolVO tmplRef = templateStoragePoolDao.findByPoolTemplate(storagePoolVO.getId(), vm.getTemplate().getId(), configuration); - if (tmplRef != null) { - info.setTemplatePath(tmplRef.getInstallPath()); - } - - info.setDeployAsIs(true); + /** + * Set the information relevant for deploy-as-is VMs on the VM TO + */ + private void setDeployAsIsInfoTO(VirtualMachineProfile vm, VirtualMachineTO to, Map details) { + String configuration = details.getOrDefault(VmDetailConstants.DEPLOY_AS_IS_CONFIGURATION, null); + Map properties = deployAsIsHelper.getVirtualMachineDeployAsIsProperties(vm); + String destStoragePool = deployAsIsHelper.getAllocatedVirtualMachineDestinationStoragePool(vm); + String templatePath = deployAsIsHelper.getAllocatedVirtualMachineTemplatePath(vm, configuration, destStoragePool); + DeployAsIsInfoTO info = new DeployAsIsInfoTO(templatePath, destStoragePool, properties); to.setDeployAsIsInfo(info); } private void setDetails(VirtualMachineTO to, Map details) { - Map detailsToSend = new HashMap<>(); - for (String key: details.keySet()) { - if (key.startsWith(ImageStore.OVF_EULA_SECTION_PREFIX) || - key.startsWith(ImageStore.OVF_HARDWARE_CONFIGURATION_PREFIX) || - key.startsWith(ImageStore.OVF_HARDWARE_ITEM_PREFIX)) { - if (LOGGER.isTraceEnabled()) { - LOGGER.trace(String.format("Discarding detail for VM %s: %s => %s", to.getName(), key, details.get(key))); - } - continue; - } - if (LOGGER.isTraceEnabled()) { + if (LOGGER.isTraceEnabled()) { + for (String key : details.keySet()) { LOGGER.trace(String.format("Detail for VM %s: %s => %s", to.getName(), key, details.get(key))); } - detailsToSend.put(key, details.get(key)); } - to.setDetails(detailsToSend); + to.setDetails(details); } private void configureDomainRouterNicsAndDetails(VirtualMachineProfile vm, VirtualMachineTO to, Map details, List nicProfiles) { @@ -318,49 +288,6 @@ class VmwareVmImplementer { } } - private void handleOvfProperties(VirtualMachineProfile vm, VirtualMachineTO to, Map details, List ovfProperties) { - if (CollectionUtils.isNotEmpty(ovfProperties)) { - removeOvfPropertiesFromDetails(ovfProperties, details); - to.setOvfProperties(ovfProperties); - } - } - - private DiskTO getRootDiskTOFromVM(VirtualMachineProfile vm) { - DiskTO rootDiskTO; - List rootDiskList; - rootDiskList = vm.getDisks().stream().filter(x -> x.getType() == Volume.Type.ROOT).collect(Collectors.toList()); - if (rootDiskList.size() != 1) { - if (vm.getTemplate().isDeployAsIs()) { - rootDiskList = vm.getDisks().stream().filter(x -> x.getType() == null).collect(Collectors.toList()); - if (rootDiskList.size() < 1) { - throw new CloudRuntimeException("Did not find a template to serve as root disk for VM " + vm.getHostName()); - } - } else { - throw new CloudRuntimeException("Did not find only one root disk for VM " + vm.getHostName()); - } - } - rootDiskTO = rootDiskList.get(0); - return rootDiskTO; - } - - private List getOvfPropertyList(VirtualMachineProfile vm, Map details) { - List ovfProperties = new ArrayList(); - for (String detailKey : details.keySet()) { - if (detailKey.startsWith(ImageStore.ACS_PROPERTY_PREFIX)) { - OVFPropertyTO propertyTO = templateDetailsDao.findPropertyByTemplateAndKey(vm.getTemplateId(), detailKey); - String vmPropertyKey = detailKey.replace(ImageStore.ACS_PROPERTY_PREFIX, ""); - if (propertyTO == null) { - LOGGER.warn(String.format("OVF property %s not found on template, discarding", vmPropertyKey)); - continue; - } - propertyTO.setKey(vmPropertyKey); - propertyTO.setValue(details.get(detailKey)); - ovfProperties.add(propertyTO); - } - } - return ovfProperties; - } - private void addReservationDetails(long clusterId, Map details) { details.put(VMwareGuru.VmwareReserveCpu.key(), VMwareGuru.VmwareReserveCpu.valueIn(clusterId).toString()); details.put(VMwareGuru.VmwareReserveMemory.key(), VMwareGuru.VmwareReserveMemory.valueIn(clusterId).toString()); @@ -408,16 +335,6 @@ class VmwareVmImplementer { // details.put(VmDetailConstants.BOOT_TYPE, to.getBootType()); } - /* - Remove OVF properties from details to be sent to hypervisor (avoid duplicate data) - */ - private void removeOvfPropertiesFromDetails(List ovfProperties, Map details) { - for (OVFPropertyTO propertyTO : ovfProperties) { - String key = propertyTO.getKey(); - details.remove(ApiConstants.PROPERTIES + "-" + key); - } - } - /** * Adds {@code 'nestedVirtualizationFlag'} value to {@code details} due to if it should be enabled or not * @param details vm details should not be null diff --git a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java index 810a4d38117..f4d2c6d424c 100644 --- a/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/plugins/hypervisors/vmware/src/main/java/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -47,7 +47,6 @@ import javax.xml.datatype.XMLGregorianCalendar; import com.cloud.agent.api.to.DataTO; import com.cloud.agent.api.to.DeployAsIsInfoTO; -import com.cloud.storage.ImageStore; import com.cloud.agent.api.ValidateVcenterDetailsCommand; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.storage.configdrive.ConfigDrive; @@ -56,7 +55,6 @@ import org.apache.cloudstack.storage.to.VolumeObjectTO; import org.apache.cloudstack.utils.volume.VirtualMachineDiskInfo; import org.apache.cloudstack.vm.UnmanagedInstanceTO; import org.apache.commons.collections.CollectionUtils; -import org.apache.commons.collections.MapUtils; import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.math.NumberUtils; @@ -180,7 +178,7 @@ import com.cloud.agent.api.storage.CreatePrivateTemplateAnswer; import com.cloud.agent.api.storage.DestroyCommand; import com.cloud.agent.api.storage.MigrateVolumeAnswer; import com.cloud.agent.api.storage.MigrateVolumeCommand; -import com.cloud.agent.api.storage.OVFPropertyTO; +import com.cloud.agent.api.to.deployasis.OVFPropertyTO; import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer; import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand; import com.cloud.agent.api.storage.ResizeVolumeAnswer; @@ -253,7 +251,6 @@ import com.cloud.utils.ExecutionResult; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; import com.cloud.utils.Ternary; -import com.cloud.utils.crypt.DBEncryptionUtil; import com.cloud.utils.db.DB; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.exception.ExceptionUtil; @@ -1842,14 +1839,13 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa DiskTO[] specDisks = vmSpec.getDisks(); DeployAsIsInfoTO deployAsIsInfo = vmSpec.getDeployAsIsInfo(); - boolean installAsIs = deployAsIsInfo != null && deployAsIsInfo.isDeployAsIs(); + boolean installAsIs = deployAsIsInfo != null; if (installAsIs && dcMo.findVm(vmInternalCSName) == null) { if (s_logger.isTraceEnabled()) { s_logger.trace("Deploying OVA from as is"); } String deployAsIsTemplate = deployAsIsInfo.getTemplatePath(); - String destDatastore = getDatastoreFromSpecDisks(specDisks); - String deploymentConfiguration = deployAsIsInfo.getDeploymentConfiguration(); + String destDatastore = deployAsIsInfo.getDestStoragePool(); vmInVcenter = _storageProcessor.cloneVMFromTemplate(deployAsIsTemplate, vmInternalCSName, destDatastore); mapSpecDisksToClonedDisks(vmInVcenter, vmInternalCSName, specDisks); } @@ -1996,7 +1992,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa if (s_logger.isTraceEnabled()) { s_logger.trace(String.format("current count(s) desired: %d/ found:%d. now adding device to device count for vApp config ISO", totalChangeDevices, hackDeviceCount)); } - if (vmSpec.getOvfProperties() != null) { + if (deployAsIsInfo != null && deployAsIsInfo.getProperties() != null) { totalChangeDevices++; } @@ -2381,18 +2377,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa // config video card configureVideoCard(vmMo, vmSpec, vmConfigSpec); - // Set OVF properties (if available) - List ovfProperties = vmSpec.getOvfProperties(); - VmConfigInfo templateVappConfig; - if (ovfProperties != null) { - VirtualMachineMO templateVMmo = dcMo.findVm(deployAsIsInfo.getTemplatePath()); - templateVappConfig = templateVMmo.getConfigInfo().getVAppConfig(); - // Set OVF properties (if available) - if (CollectionUtils.isNotEmpty(ovfProperties)) { - s_logger.info("Copying OVF properties from template and setting them to the values the user provided"); - copyVAppConfigsFromTemplate(templateVappConfig, ovfProperties, vmConfigSpec); - } - } + setDeployAsIsProperties(vmMo, deployAsIsInfo, vmConfigSpec); setBootOptions(vmSpec, bootMode, vmConfigSpec); @@ -2483,26 +2468,17 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa } } - private String getDatastoreFromSpecDisks(DiskTO[] specDisks) { - if (specDisks.length == 0) { - return null; + /** + * Set OVF properties (if available) + */ + private void setDeployAsIsProperties(VirtualMachineMO vmMo, DeployAsIsInfoTO deployAsIsInfo, + VirtualMachineConfigSpec vmConfigSpec) throws Exception { + if (deployAsIsInfo != null) { + Map properties = deployAsIsInfo.getProperties(); + VmConfigInfo vAppConfig = vmMo.getConfigInfo().getVAppConfig(); + s_logger.info("Copying OVF properties to the values the user provided"); + setVAppPropertiesToConfigSpec(vAppConfig, properties, vmConfigSpec); } - - Map> psDisksMap = Arrays.asList(specDisks).stream() - .filter(x -> x.getType() != Volume.Type.ISO && x.getData() != null && x.getData().getDataStore() != null) - .collect(Collectors.groupingBy(x -> x.getData().getDataStore().getUuid())); - - String dataStore; - if (MapUtils.isEmpty(psDisksMap)) { - s_logger.error("Could not find a destination datastore for VM volumes"); - return null; - } else { - dataStore = psDisksMap.keySet().iterator().next(); - if (psDisksMap.keySet().size() > 1) { - s_logger.info("Found multiple destination datastores for VM volumes, selecting " + dataStore); - } - } - return dataStore; } /** @@ -2624,17 +2600,14 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa /** * Set the properties section from existing vApp configuration and values set on ovfProperties */ - protected List copyVAppConfigPropertySectionFromOVF(VmConfigInfo vAppConfig, List ovfProperties) { + protected List copyVAppConfigPropertySectionFromOVF(VmConfigInfo vAppConfig, Map ovfProperties) { List productFromOvf = vAppConfig.getProperty(); List specs = new ArrayList<>(); - Map> ovfMap = getOVFMap(ovfProperties); for (VAppPropertyInfo info : productFromOvf) { VAppPropertySpec spec = new VAppPropertySpec(); - if (ovfMap.containsKey(info.getId())) { - Pair pair = ovfMap.get(info.getId()); - String value = pair.first(); - boolean isPassword = pair.second(); - info.setValue(isPassword ? DBEncryptionUtil.decrypt(value) : value); + if (ovfProperties.containsKey(info.getId())) { + String value = ovfProperties.get(info.getId()); + info.setValue(value); } spec.setInfo(info); spec.setOperation(ArrayUpdateOperation.ADD); @@ -2662,9 +2635,9 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa * Set the vApp configuration to vmConfig spec, copying existing configuration from vAppConfig * and seting properties values from ovfProperties */ - protected void copyVAppConfigsFromTemplate(VmConfigInfo vAppConfig, - List ovfProperties, - VirtualMachineConfigSpec vmConfig) throws Exception { + protected void setVAppPropertiesToConfigSpec(VmConfigInfo vAppConfig, + Map ovfProperties, + VirtualMachineConfigSpec vmConfig) throws Exception { VmConfigSpec vmConfigSpec = new VmConfigSpec(); vmConfigSpec.getEula().addAll(vAppConfig.getEula()); vmConfigSpec.setInstallBootStopDelay(vAppConfig.getInstallBootStopDelay()); @@ -3009,10 +2982,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa private static void configCustomExtraOption(List extraOptions, VirtualMachineTO vmSpec) { // we no longer to validation anymore for (Map.Entry entry : vmSpec.getDetails().entrySet()) { - if (entry.getKey().equalsIgnoreCase(VmDetailConstants.BOOT_MODE) || - entry.getKey().startsWith(ImageStore.REQUIRED_NETWORK_PREFIX) || - entry.getKey().startsWith(ImageStore.ACS_PROPERTY_PREFIX) || - entry.getKey().startsWith(ImageStore.DISK_DEFINITION_PREFIX)) { + if (entry.getKey().equalsIgnoreCase(VmDetailConstants.BOOT_MODE)) { continue; } OptionValue newVal = new OptionValue(); diff --git a/server/src/main/java/com/cloud/api/query/dao/TemplateJoinDaoImpl.java b/server/src/main/java/com/cloud/api/query/dao/TemplateJoinDaoImpl.java index e51dd1e3f9c..9cfe710fd71 100644 --- a/server/src/main/java/com/cloud/api/query/dao/TemplateJoinDaoImpl.java +++ b/server/src/main/java/com/cloud/api/query/dao/TemplateJoinDaoImpl.java @@ -26,6 +26,9 @@ import java.util.Set; import javax.inject.Inject; +import com.cloud.deployasis.DeployAsIsConstants; +import com.cloud.deployasis.TemplateDeployAsIsDetailVO; +import com.cloud.deployasis.dao.TemplateDeployAsIsDetailsDao; import org.apache.cloudstack.api.ApiConstants; import org.apache.cloudstack.utils.security.DigestHelper; import org.apache.log4j.Logger; @@ -83,6 +86,8 @@ public class TemplateJoinDaoImpl extends GenericDaoBaseWithTagInformation tmpltIdPairSearch; @@ -240,6 +245,8 @@ public class TemplateJoinDaoImpl extends GenericDaoBaseWithTagInformation details = _templateDetailsDao.listDetailsKeyPairs(template.getId()); templateResponse.setDetails(details); + + setDeployAsIsDetails(template, templateResponse); } // update tag information @@ -272,6 +279,19 @@ public class TemplateJoinDaoImpl extends GenericDaoBaseWithTagInformation deployAsIsDetails = templateDeployAsIsDetailsDao.listDetails(template.getId()); + for (TemplateDeployAsIsDetailVO deployAsIsDetailVO : deployAsIsDetails) { + if (deployAsIsDetailVO.getName().startsWith(DeployAsIsConstants.OVF_HARDWARE_ITEM_PREFIX)) { + //Do not list hardware items + continue; + } + templateResponse.addDeployAsIsDetail(deployAsIsDetailVO.getName(), deployAsIsDetailVO.getValue()); + } + } + } + //TODO: This is to keep compatibility with 4.1 API, where updateTemplateCmd and updateIsoCmd will return a simpler TemplateResponse // compared to listTemplates and listIsos. @Override diff --git a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java index a7f01cb1be3..8395467039d 100644 --- a/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/main/java/com/cloud/vm/UserVmManagerImpl.java @@ -47,12 +47,12 @@ import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; -import com.cloud.agent.api.storage.OVFPropertyTO; +import com.cloud.agent.api.to.deployasis.OVFPropertyTO; +import com.cloud.deployasis.UserVmDeployAsIsDetailVO; +import com.cloud.deployasis.dao.UserVmDeployAsIsDetailsDao; import com.cloud.exception.UnsupportedServiceException; import com.cloud.hypervisor.Hypervisor; -import com.cloud.storage.ImageStore; -import com.cloud.storage.VMTemplateDetailVO; -import com.cloud.storage.dao.VMTemplateDetailsDao; +import com.cloud.deployasis.dao.TemplateDeployAsIsDetailsDao; import org.apache.cloudstack.acl.ControlledEntity.ACLType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; import org.apache.cloudstack.affinity.AffinityGroupService; @@ -83,7 +83,7 @@ import org.apache.cloudstack.api.command.user.vm.UpgradeVMCmd; import org.apache.cloudstack.api.command.user.vmgroup.CreateVMGroupCmd; import org.apache.cloudstack.api.command.user.vmgroup.DeleteVMGroupCmd; import org.apache.cloudstack.api.command.user.volume.ResizeVolumeCmd; -import org.apache.cloudstack.api.net.NetworkPrerequisiteTO; +import com.cloud.agent.api.to.deployasis.OVFNetworkTO; import org.apache.cloudstack.context.CallContext; import org.apache.cloudstack.engine.cloud.entity.api.VirtualMachineEntity; import org.apache.cloudstack.engine.cloud.entity.api.db.dao.VMNetworkMapDao; @@ -507,7 +507,9 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir @Inject private ResourceTagDao resourceTagDao; @Inject - private VMTemplateDetailsDao templateDetailsDao; + private TemplateDeployAsIsDetailsDao templateDeployAsIsDetailsDao; + @Inject + private UserVmDeployAsIsDetailsDao userVmDeployAsIsDetailsDao; private ScheduledExecutorService _executor = null; private ScheduledExecutorService _vmIpFetchExecutor = null; @@ -2503,17 +2505,6 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } } } - for (String detailName : details.keySet()) { - if (s_logger.isTraceEnabled()) { - s_logger.trace(String.format("looking for vm detail '%s'", detailName)); - } - if (detailName.startsWith(ImageStore.ACS_PROPERTY_PREFIX)) { - OVFPropertyTO propertyTO = templateDetailsDao.findPropertyByTemplateAndKey(vmInstance.getTemplateId(),detailName); - if (propertyTO != null && propertyTO.isPassword()) { - details.put(detailName, DBEncryptionUtil.encrypt(details.get(detailName))); - } - } - } vmInstance.setDetails(details); _vmDao.saveDetails(vmInstance); } @@ -4007,11 +3998,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } vm.setDetail(VmDetailConstants.DEPLOY_VM, "true"); - copyDiskDetailsToVm(vm, template); - - setPropertiesOnVM(vm, userVmOVFPropertiesMap); - - copyNetworkRequirementsToVm(vm, template); + persistVMDeployAsIsProperties(vm, userVmOVFPropertiesMap); _vmDao.saveDetails(vm); if (!isImport) { @@ -4056,33 +4043,15 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir }); } - private void copyNetworkRequirementsToVm(UserVmVO vm, VirtualMachineTemplate template) { - if (template.isDeployAsIs()) { - List details = templateDetailsDao.listDetailsByTemplateIdMatchingPrefix(template.getId(), ImageStore.REQUIRED_NETWORK_PREFIX); - for (VMTemplateDetailVO detail : details) { - vm.setDetail(detail.getName(), detail.getValue()); - } - } - } - - private void copyDiskDetailsToVm(UserVmVO vm, VirtualMachineTemplate template) { - if (template.isDeployAsIs()) { - List details = templateDetailsDao.listDetailsByTemplateIdMatchingPrefix(template.getId(), ImageStore.DISK_DEFINITION_PREFIX); - for (VMTemplateDetailVO detail : details) { - vm.setDetail(detail.getName(), detail.getValue()); - } - } - } - /** * take the properties and set them on the vm. * consider should we be complete, and make sure all default values are copied as well if known? * I.E. iterate over the template details as well to copy any that are not defined yet. */ - private void setPropertiesOnVM(UserVmVO vm, Map userVmOVFPropertiesMap) { + private void persistVMDeployAsIsProperties(UserVmVO vm, Map userVmOVFPropertiesMap) { if (MapUtils.isNotEmpty(userVmOVFPropertiesMap)) { for (String key : userVmOVFPropertiesMap.keySet()) { - String detailKey = ImageStore.ACS_PROPERTY_PREFIX + key; + String detailKey = key; String value = userVmOVFPropertiesMap.get(key); // Sanitize boolean values to expected format and encrypt passwords @@ -4092,7 +4061,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir } else if (value.equalsIgnoreCase("False")) { value = "False"; } else { - OVFPropertyTO propertyTO = templateDetailsDao.findPropertyByTemplateAndKey(vm.getTemplateId(), key); + OVFPropertyTO propertyTO = templateDeployAsIsDetailsDao.findPropertyByTemplateAndKey(vm.getTemplateId(), key); if (propertyTO != null && propertyTO.isPassword()) { value = DBEncryptionUtil.encrypt(value); } @@ -4101,7 +4070,8 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir if (s_logger.isTraceEnabled()) { s_logger.trace(String.format("setting property '%s' as '%s' with value '%s'", key, detailKey, value)); } - vm.setDetail(detailKey, value); + UserVmDeployAsIsDetailVO detail = new UserVmDeployAsIsDetailVO(vm.getId(), detailKey, value); + userVmDeployAsIsDetailsDao.persist(detail); } } } @@ -7378,19 +7348,19 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir private LinkedHashMap getVmOvfNetworkMapping(DataCenter zone, Account owner, VirtualMachineTemplate template, Map vmNetworkMapping) throws InsufficientCapacityException, ResourceAllocationException { LinkedHashMap mapping = new LinkedHashMap<>(); if (ImageFormat.OVA.equals(template.getFormat())) { - List networkPrerequisiteTOList = - templateDetailsDao.listNetworkRequirementsByTemplateId(template.getId()); - if (CollectionUtils.isNotEmpty(networkPrerequisiteTOList)) { + List OVFNetworkTOList = + templateDeployAsIsDetailsDao.listNetworkRequirementsByTemplateId(template.getId()); + if (CollectionUtils.isNotEmpty(OVFNetworkTOList)) { Network lastMappedNetwork = null; - for (NetworkPrerequisiteTO networkPrerequisiteTO : networkPrerequisiteTOList) { - Long networkId = vmNetworkMapping.get(networkPrerequisiteTO.getInstanceID()); + for (OVFNetworkTO OVFNetworkTO : OVFNetworkTOList) { + Long networkId = vmNetworkMapping.get(OVFNetworkTO.getInstanceID()); if (networkId == null && lastMappedNetwork == null) { lastMappedNetwork = getNetworkForOvfNetworkMapping(zone, owner); } if (networkId == null) { networkId = lastMappedNetwork.getId(); } - mapping.put(networkPrerequisiteTO.getInstanceID(), networkId); + mapping.put(OVFNetworkTO.getInstanceID(), networkId); } } } diff --git a/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/template/DownloadManagerImpl.java b/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/template/DownloadManagerImpl.java index fec8eab8ce2..d60d7b8fb20 100644 --- a/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/template/DownloadManagerImpl.java +++ b/services/secondary-storage/server/src/main/java/org/apache/cloudstack/storage/template/DownloadManagerImpl.java @@ -37,10 +37,10 @@ import java.util.concurrent.Executors; import javax.naming.ConfigurationException; -import com.cloud.agent.api.storage.OVFEulaSectionTO; -import com.cloud.agent.api.storage.OVFVirtualHardwareSectionTO; +import com.cloud.agent.api.to.deployasis.OVFEulaSectionTO; +import com.cloud.agent.api.to.deployasis.OVFVirtualHardwareSectionTO; import com.cloud.agent.api.to.DatadiskTO; -import com.cloud.agent.api.storage.OVFPropertyTO; +import com.cloud.agent.api.to.deployasis.OVFPropertyTO; import com.cloud.storage.template.Processor; import com.cloud.storage.template.S3TemplateDownloader; import com.cloud.storage.template.TemplateDownloader; @@ -58,7 +58,7 @@ import com.cloud.storage.template.RawImageProcessor; import com.cloud.storage.template.TARProcessor; import com.cloud.storage.template.VhdProcessor; import com.cloud.storage.template.TemplateConstants; -import org.apache.cloudstack.api.net.NetworkPrerequisiteTO; +import com.cloud.agent.api.to.deployasis.OVFNetworkTO; import org.apache.cloudstack.storage.command.DownloadCommand; import org.apache.cloudstack.storage.command.DownloadCommand.ResourceType; import org.apache.cloudstack.storage.command.DownloadProgressCommand; @@ -132,7 +132,7 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager private final long id; private final ResourceType resourceType; private List ovfProperties; - private List networks; + private List networks; private List disks; private OVFVirtualHardwareSectionTO hardwareSection; private List eulaSections; @@ -239,11 +239,11 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager this.ovfProperties = ovfProperties; } - public List getNetworks() { + public List getNetworks() { return networks; } - public void setNetworks(List networks) { + public void setNetworks(List networks) { this.networks = networks; }