mirror of
				https://github.com/apache/cloudstack.git
				synced 2025-10-26 08:42:29 +01:00 
			
		
		
		
	Add new template and vm deploy as is details table and refactor
This commit is contained in:
		
							parent
							
								
									fab6b41c90
								
							
						
					
					
						commit
						bb4ce2118d
					
				| @ -39,10 +39,15 @@ import javax.xml.transform.TransformerFactory; | |||||||
| import javax.xml.transform.dom.DOMSource; | import javax.xml.transform.dom.DOMSource; | ||||||
| import javax.xml.transform.stream.StreamResult; | 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.configuration.Resource.ResourceType; | ||||||
| import com.cloud.exception.InternalErrorException; | import com.cloud.exception.InternalErrorException; | ||||||
| import com.cloud.utils.compression.CompressionUtil; | 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.collections.CollectionUtils; | ||||||
| import org.apache.commons.lang.StringUtils; | import org.apache.commons.lang.StringUtils; | ||||||
| import org.apache.commons.lang.math.NumberUtils; | import org.apache.commons.lang.math.NumberUtils; | ||||||
| @ -573,7 +578,7 @@ public class OVFHelper { | |||||||
|         return null; |         return null; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public List<NetworkPrerequisiteTO> getNetPrerequisitesFromDocument(Document doc) throws InternalErrorException { |     public List<OVFNetworkTO> getNetPrerequisitesFromDocument(Document doc) throws InternalErrorException { | ||||||
|         if (doc == null) { |         if (doc == null) { | ||||||
|             if (s_logger.isTraceEnabled()) { |             if (s_logger.isTraceEnabled()) { | ||||||
|                 s_logger.trace("no document to parse; returning no prerequiste networks"); |                 s_logger.trace("no document to parse; returning no prerequiste networks"); | ||||||
| @ -581,7 +586,7 @@ public class OVFHelper { | |||||||
|             return Collections.emptyList(); |             return Collections.emptyList(); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         Map<String, NetworkPrerequisiteTO> nets = getNetworksFromDocumentTree(doc); |         Map<String, OVFNetworkTO> nets = getNetworksFromDocumentTree(doc); | ||||||
| 
 | 
 | ||||||
|         checkForOnlyOneSystemNode(doc); |         checkForOnlyOneSystemNode(doc); | ||||||
| 
 | 
 | ||||||
| @ -590,7 +595,7 @@ public class OVFHelper { | |||||||
|         return new ArrayList<>(nets.values()); |         return new ArrayList<>(nets.values()); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private void matchNicsToNets(Map<String, NetworkPrerequisiteTO> nets, Node systemElement) { |     private void matchNicsToNets(Map<String, OVFNetworkTO> nets, Node systemElement) { | ||||||
|         final DocumentTraversal traversal = (DocumentTraversal) systemElement; |         final DocumentTraversal traversal = (DocumentTraversal) systemElement; | ||||||
|         final NodeIterator iterator = traversal.createNodeIterator(systemElement, NodeFilter.SHOW_ELEMENT, null, true); |         final NodeIterator iterator = traversal.createNodeIterator(systemElement, NodeFilter.SHOW_ELEMENT, null, true); | ||||||
|         if (s_logger.isTraceEnabled()) { |         if (s_logger.isTraceEnabled()) { | ||||||
| @ -606,9 +611,9 @@ public class OVFHelper { | |||||||
|                     if(s_logger.isInfoEnabled()) { |                     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)); |                         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) { |                 if (e.getParentNode() != null) { | ||||||
|                     fillNicPrerequisites(thisNet,e.getParentNode()); |                     fillNicPrerequisites(thisNet,e.getParentNode()); | ||||||
|                 } |                 } | ||||||
| @ -625,7 +630,7 @@ public class OVFHelper { | |||||||
|      * @param nic the object to carry through the system |      * @param nic the object to carry through the system | ||||||
|      * @param parentNode the xml container node for nic data |      * @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 addressOnParentStr = getChildNodeValue(parentNode, "AddressOnParent"); | ||||||
|         String automaticAllocationStr = getChildNodeValue(parentNode, "AutomaticAllocation"); |         String automaticAllocationStr = getChildNodeValue(parentNode, "AutomaticAllocation"); | ||||||
|         String description = getChildNodeValue(parentNode, "Description"); |         String description = getChildNodeValue(parentNode, "Description"); | ||||||
| @ -667,9 +672,9 @@ public class OVFHelper { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private Map<String, NetworkPrerequisiteTO> getNetworksFromDocumentTree(Document doc) { |     private Map<String, OVFNetworkTO> getNetworksFromDocumentTree(Document doc) { | ||||||
|         NodeList networkElements = doc.getElementsByTagName("Network"); |         NodeList networkElements = doc.getElementsByTagName("Network"); | ||||||
|         Map<String, NetworkPrerequisiteTO> nets = new HashMap<>(); |         Map<String, OVFNetworkTO> nets = new HashMap<>(); | ||||||
|         for (int i = 0; i < networkElements.getLength(); i++) { |         for (int i = 0; i < networkElements.getLength(); i++) { | ||||||
| 
 | 
 | ||||||
|             Element networkElement = (Element)networkElements.item(i); |             Element networkElement = (Element)networkElements.item(i); | ||||||
| @ -677,7 +682,7 @@ public class OVFHelper { | |||||||
| 
 | 
 | ||||||
|             String description = getChildNodeValue(networkElement, "Description"); |             String description = getChildNodeValue(networkElement, "Description"); | ||||||
| 
 | 
 | ||||||
|             NetworkPrerequisiteTO network = new NetworkPrerequisiteTO(); |             OVFNetworkTO network = new OVFNetworkTO(); | ||||||
|             network.setName(networkName); |             network.setName(networkName); | ||||||
|             network.setNetworkDescription(description); |             network.setNetworkDescription(description); | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -16,36 +16,37 @@ | |||||||
| // under the License. | // under the License. | ||||||
| package com.cloud.agent.api.to; | package com.cloud.agent.api.to; | ||||||
| 
 | 
 | ||||||
|  | import com.cloud.agent.api.LogLevel; | ||||||
|  | 
 | ||||||
|  | import java.util.HashMap; | ||||||
|  | import java.util.Map; | ||||||
|  | 
 | ||||||
| public class DeployAsIsInfoTO { | public class DeployAsIsInfoTO { | ||||||
| 
 | 
 | ||||||
|     private boolean deployAsIs; |  | ||||||
|     private String templatePath; |     private String templatePath; | ||||||
|     private String deploymentConfiguration; |     private String destStoragePool; | ||||||
|  |     @LogLevel(LogLevel.Log4jLevel.Off) | ||||||
|  |     private Map<String, String> properties = new HashMap<>(); | ||||||
| 
 | 
 | ||||||
|     public DeployAsIsInfoTO() { |     public DeployAsIsInfoTO() { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public boolean isDeployAsIs() { |     public DeployAsIsInfoTO(String templatePath, String destStoragePool, Map<String, String> properties) { | ||||||
|         return deployAsIs; |         this.templatePath = templatePath; | ||||||
|     } |         this.destStoragePool = destStoragePool; | ||||||
| 
 |         this.properties = properties; | ||||||
|     public void setDeployAsIs(boolean deployAsIs) { |  | ||||||
|         this.deployAsIs = deployAsIs; |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public String getTemplatePath() { |     public String getTemplatePath() { | ||||||
|         return templatePath; |         return templatePath; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public void setTemplatePath(String templateInSecondaryPath) { |     public Map<String, String> getProperties() { | ||||||
|         this.templatePath = templateInSecondaryPath; |         return properties; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public String getDeploymentConfiguration() { |     public String getDestStoragePool() { | ||||||
|         return deploymentConfiguration; |         return destStoragePool; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public void setDeploymentConfiguration(String deploymentConfiguration) { |  | ||||||
|         this.deploymentConfiguration = deploymentConfiguration; |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -20,8 +20,6 @@ import java.util.List; | |||||||
| import java.util.Map; | import java.util.Map; | ||||||
| import java.util.HashMap; | 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.template.VirtualMachineTemplate.BootloaderType; | ||||||
| import com.cloud.vm.VirtualMachine; | import com.cloud.vm.VirtualMachine; | ||||||
| import com.cloud.vm.VirtualMachine.Type; | import com.cloud.vm.VirtualMachine.Type; | ||||||
| @ -80,8 +78,6 @@ public class VirtualMachineTO { | |||||||
| 
 | 
 | ||||||
|     Map<String, String> guestOsDetails = new HashMap<String, String>(); |     Map<String, String> guestOsDetails = new HashMap<String, String>(); | ||||||
|     Map<String, String> extraConfig = new HashMap<>(); |     Map<String, String> extraConfig = new HashMap<>(); | ||||||
|     @LogLevel(LogLevel.Log4jLevel.Off) |  | ||||||
|     List<OVFPropertyTO> ovfProperties; |  | ||||||
|     DeployAsIsInfoTO deployAsIsInfo; |     DeployAsIsInfoTO deployAsIsInfo; | ||||||
| 
 | 
 | ||||||
|     public VirtualMachineTO(long id, String instanceName, VirtualMachine.Type type, int cpus, Integer speed, long minRam, long maxRam, BootloaderType bootloader, |     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; |         return extraConfig; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public List<OVFPropertyTO> getOvfProperties() { |  | ||||||
|         return ovfProperties; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     public void setOvfProperties(List<OVFPropertyTO> ovfProperties) { |  | ||||||
|         this.ovfProperties = ovfProperties; |  | ||||||
|     } |  | ||||||
|     public String getBootType() { |     public String getBootType() { | ||||||
|         return bootType; |         return bootType; | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -16,11 +16,11 @@ | |||||||
| // specific language governing permissions and limitations | // specific language governing permissions and limitations | ||||||
| // under the License. | // under the License. | ||||||
| // | // | ||||||
| package com.cloud.agent.api.storage; | package com.cloud.agent.api.to.deployasis; | ||||||
| 
 | 
 | ||||||
| import java.util.List; | import java.util.List; | ||||||
| 
 | 
 | ||||||
| public class OVFConfigurationTO { | public class OVFConfigurationTO implements TemplateDeployAsIsInformationTO { | ||||||
| 
 | 
 | ||||||
|     private final String id; |     private final String id; | ||||||
|     private final String label; |     private final String label; | ||||||
| @ -16,16 +16,14 @@ | |||||||
| // specific language governing permissions and limitations | // specific language governing permissions and limitations | ||||||
| // under the License. | // under the License. | ||||||
| // | // | ||||||
| package com.cloud.agent.api.storage; | package com.cloud.agent.api.to.deployasis; | ||||||
| 
 | 
 | ||||||
| import com.cloud.agent.api.LogLevel; | import com.cloud.agent.api.LogLevel; | ||||||
| 
 | 
 | ||||||
| import java.io.Serializable; |  | ||||||
| 
 |  | ||||||
| /** | /** | ||||||
|  * End-user licence agreement |  * End-user licence agreement | ||||||
|  */ |  */ | ||||||
| public class OVFEulaSectionTO implements Serializable { | public class OVFEulaSectionTO implements TemplateDeployAsIsInformationTO { | ||||||
|     private String info; |     private String info; | ||||||
|     @LogLevel(LogLevel.Log4jLevel.Off) |     @LogLevel(LogLevel.Log4jLevel.Off) | ||||||
|     private byte[] compressedLicense; |     private byte[] compressedLicense; | ||||||
| @ -14,7 +14,7 @@ | |||||||
| // KIND, either express or implied.  See the License for the | // KIND, either express or implied.  See the License for the | ||||||
| // specific language governing permissions and limitations | // specific language governing permissions and limitations | ||||||
| // under the License. | // 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 |  * container for the network prerequisites as found in the appliance template | ||||||
| @ -38,7 +38,7 @@ package org.apache.cloudstack.api.net; | |||||||
|  * </Item> |  * </Item> | ||||||
|  * {code} |  * {code} | ||||||
|  */ |  */ | ||||||
| public class NetworkPrerequisiteTO { | public class OVFNetworkTO implements TemplateDeployAsIsInformationTO { | ||||||
|     String name; |     String name; | ||||||
|     String networkDescription; |     String networkDescription; | ||||||
| 
 | 
 | ||||||
| @ -17,7 +17,7 @@ | |||||||
| // under the License. | // under the License. | ||||||
| // | // | ||||||
| 
 | 
 | ||||||
| package com.cloud.agent.api.storage; | package com.cloud.agent.api.to.deployasis; | ||||||
| 
 | 
 | ||||||
| import com.cloud.agent.api.LogLevel; | 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.</Description> |  * Choose "Remote HTTP and SSH Client Routes" to route only traffic destined for the management client(s), when they are on remote networks.</Description> | ||||||
|  *       </Property> |  *       </Property> | ||||||
|  */ |  */ | ||||||
| public class OVFPropertyTO { | public class OVFPropertyTO implements TemplateDeployAsIsInformationTO { | ||||||
| 
 | 
 | ||||||
|     private String key; |     private String key; | ||||||
|     private String type; |     private String type; | ||||||
| @ -14,10 +14,10 @@ | |||||||
| // KIND, either express or implied.  See the License for the | // KIND, either express or implied.  See the License for the | ||||||
| // specific language governing permissions and limitations | // specific language governing permissions and limitations | ||||||
| // under the License. | // 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 | // 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 |     //From: https://schemas.dmtf.org/wbem/cim-html/2/CIM_ResourceAllocationSettingData.html | ||||||
|     public enum HardwareResourceType { |     public enum HardwareResourceType { | ||||||
| @ -16,11 +16,11 @@ | |||||||
| // specific language governing permissions and limitations | // specific language governing permissions and limitations | ||||||
| // under the License. | // under the License. | ||||||
| // | // | ||||||
| package com.cloud.agent.api.storage; | package com.cloud.agent.api.to.deployasis; | ||||||
| 
 | 
 | ||||||
| import java.util.List; | import java.util.List; | ||||||
| 
 | 
 | ||||||
| public class OVFVirtualHardwareSectionTO { | public class OVFVirtualHardwareSectionTO implements TemplateDeployAsIsInformationTO { | ||||||
| 
 | 
 | ||||||
|     public OVFVirtualHardwareSectionTO() { |     public OVFVirtualHardwareSectionTO() { | ||||||
|     } |     } | ||||||
| @ -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 { | ||||||
|  | } | ||||||
| @ -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-"; | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -21,13 +21,6 @@ import org.apache.cloudstack.api.InternalIdentity; | |||||||
| 
 | 
 | ||||||
| public interface ImageStore extends Identity, 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. |      * @return name of the object store. | ||||||
|      */ |      */ | ||||||
|  | |||||||
| @ -826,6 +826,7 @@ public class ApiConstants { | |||||||
|     public static final String BOOT_MODE = "bootmode"; |     public static final String BOOT_MODE = "bootmode"; | ||||||
|     public static final String BOOT_INTO_SETUP = "bootintosetup"; |     public static final String BOOT_INTO_SETUP = "bootintosetup"; | ||||||
|     public static final String DEPLOY_AS_IS = "deployasis"; |     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 CROSS_ZONES = "crossZones"; | ||||||
|     public static final String TEMPLATETYPE = "templatetype"; |     public static final String TEMPLATETYPE = "templatetype"; | ||||||
|     public static final String SOURCETEMPLATEID = "sourcetemplateid"; |     public static final String SOURCETEMPLATEID = "sourcetemplateid"; | ||||||
|  | |||||||
| @ -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.") |     @Param(description = "VMware only: true if template is deployed without orchestrating disks and networks but \"as-is\" defined in the template.") | ||||||
|     private Boolean deployAsIs; |     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<String, String> deployAsIsDetails; | ||||||
|  | 
 | ||||||
|     @SerializedName("parenttemplateid") |     @SerializedName("parenttemplateid") | ||||||
|     @Param(description = "if Datadisk template, then id of the root disk template this template belongs to") |     @Param(description = "if Datadisk template, then id of the root disk template this template belongs to") | ||||||
|     @Deprecated(since = "4.15") |     @Deprecated(since = "4.15") | ||||||
| @ -429,4 +433,19 @@ public class TemplateResponse extends BaseResponseWithTagInformation implements | |||||||
|     public void setRequiresHvm(Boolean requiresHvm) { |     public void setRequiresHvm(Boolean requiresHvm) { | ||||||
|         this.requiresHvm = requiresHvm; |         this.requiresHvm = requiresHvm; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     public Map<String, String> getDeployAsIsDetails() { | ||||||
|  |         return this.deployAsIsDetails; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void setDeployAsIsDetails(Map<String, String> details) { | ||||||
|  |         this.deployAsIsDetails = details; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void addDeployAsIsDetail(String key, String value) { | ||||||
|  |         if (this.deployAsIsDetails == null) { | ||||||
|  |             setDeployAsIsDetails(new HashMap<>()); | ||||||
|  |         } | ||||||
|  |         this.deployAsIsDetails.put(key,value); | ||||||
|  |     } | ||||||
| } | } | ||||||
|  | |||||||
| @ -16,6 +16,10 @@ | |||||||
| // under the License. | // under the License. | ||||||
| package com.cloud.agent.api.storage; | 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.Assert; | ||||||
| import org.junit.Test; | import org.junit.Test; | ||||||
| import org.xml.sax.SAXException; | import org.xml.sax.SAXException; | ||||||
|  | |||||||
| @ -26,9 +26,12 @@ import com.cloud.agent.api.Answer; | |||||||
| import com.cloud.agent.api.Command; | import com.cloud.agent.api.Command; | ||||||
| import com.cloud.agent.api.LogLevel; | import com.cloud.agent.api.LogLevel; | ||||||
| import com.cloud.agent.api.to.DatadiskTO; | 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; | ||||||
| import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; | 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 { | public class DownloadAnswer extends Answer { | ||||||
|     private String jobId; |     private String jobId; | ||||||
| @ -44,7 +47,7 @@ public class DownloadAnswer extends Answer { | |||||||
|     @LogLevel(LogLevel.Log4jLevel.Off) |     @LogLevel(LogLevel.Log4jLevel.Off) | ||||||
|     private List<OVFPropertyTO> ovfProperties; |     private List<OVFPropertyTO> ovfProperties; | ||||||
|     @LogLevel(LogLevel.Log4jLevel.Off) |     @LogLevel(LogLevel.Log4jLevel.Off) | ||||||
|     private List<NetworkPrerequisiteTO> networkRequirements; |     private List<OVFNetworkTO> networkRequirements; | ||||||
|     @LogLevel(LogLevel.Log4jLevel.Off) |     @LogLevel(LogLevel.Log4jLevel.Off) | ||||||
|     private List<DatadiskTO> disks; |     private List<DatadiskTO> disks; | ||||||
|     @LogLevel(LogLevel.Log4jLevel.Off) |     @LogLevel(LogLevel.Log4jLevel.Off) | ||||||
| @ -169,11 +172,11 @@ public class DownloadAnswer extends Answer { | |||||||
|         this.ovfProperties = ovfProperties; |         this.ovfProperties = ovfProperties; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public List<NetworkPrerequisiteTO> getNetworkRequirements() { |     public List<OVFNetworkTO> getNetworkRequirements() { | ||||||
|         return networkRequirements; |         return networkRequirements; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public void setNetworkRequirements(List<NetworkPrerequisiteTO> networkRequirements) { |     public void setNetworkRequirements(List<OVFNetworkTO> networkRequirements) { | ||||||
|         this.networkRequirements = networkRequirements; |         this.networkRequirements = networkRequirements; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -28,12 +28,12 @@ import javax.naming.ConfigurationException; | |||||||
| import javax.xml.parsers.DocumentBuilderFactory; | import javax.xml.parsers.DocumentBuilderFactory; | ||||||
| import javax.xml.parsers.ParserConfigurationException; | import javax.xml.parsers.ParserConfigurationException; | ||||||
| 
 | 
 | ||||||
| import com.cloud.agent.api.storage.OVFConfigurationTO; | import com.cloud.agent.api.to.deployasis.OVFConfigurationTO; | ||||||
| import com.cloud.agent.api.storage.OVFEulaSectionTO; | import com.cloud.agent.api.to.deployasis.OVFEulaSectionTO; | ||||||
| import com.cloud.agent.api.storage.OVFPropertyTO; | import com.cloud.agent.api.to.deployasis.OVFPropertyTO; | ||||||
| import com.cloud.agent.api.storage.OVFVirtualHardwareItemTO; | import com.cloud.agent.api.to.deployasis.OVFVirtualHardwareItemTO; | ||||||
| import com.cloud.agent.api.storage.OVFVirtualHardwareSectionTO; | import com.cloud.agent.api.to.deployasis.OVFVirtualHardwareSectionTO; | ||||||
| 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.collections.CollectionUtils; | ||||||
| import org.apache.log4j.Logger; | import org.apache.log4j.Logger; | ||||||
| import org.w3c.dom.Document; | import org.w3c.dom.Document; | ||||||
| @ -115,7 +115,7 @@ public class OVAProcessor extends AdapterBase implements Processor { | |||||||
|             info.disks = disks; |             info.disks = disks; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         List<NetworkPrerequisiteTO> nets = ovfHelper.getNetPrerequisitesFromDocument(doc); |         List<OVFNetworkTO> nets = ovfHelper.getNetPrerequisitesFromDocument(doc); | ||||||
|         if (CollectionUtils.isNotEmpty(nets)) { |         if (CollectionUtils.isNotEmpty(nets)) { | ||||||
|             LOGGER.info("Found " + nets.size() + " prerequisite networks"); |             LOGGER.info("Found " + nets.size() + " prerequisite networks"); | ||||||
|             info.networks = nets; |             info.networks = nets; | ||||||
|  | |||||||
| @ -23,14 +23,14 @@ import java.io.File; | |||||||
| import java.io.IOException; | import java.io.IOException; | ||||||
| import java.util.List; | import java.util.List; | ||||||
| 
 | 
 | ||||||
| import com.cloud.agent.api.storage.OVFEulaSectionTO; | import com.cloud.agent.api.to.deployasis.OVFEulaSectionTO; | ||||||
| import com.cloud.agent.api.storage.OVFPropertyTO; | import com.cloud.agent.api.to.deployasis.OVFPropertyTO; | ||||||
| import com.cloud.agent.api.storage.OVFVirtualHardwareSectionTO; | import com.cloud.agent.api.to.deployasis.OVFVirtualHardwareSectionTO; | ||||||
| import com.cloud.agent.api.to.DatadiskTO; | import com.cloud.agent.api.to.DatadiskTO; | ||||||
| import com.cloud.exception.InternalErrorException; | import com.cloud.exception.InternalErrorException; | ||||||
| import com.cloud.storage.Storage.ImageFormat; | import com.cloud.storage.Storage.ImageFormat; | ||||||
| import com.cloud.utils.component.Adapter; | 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 |  * Generic interface to process different types of image formats | ||||||
| @ -59,7 +59,7 @@ public interface Processor extends Adapter { | |||||||
|         public String filename; |         public String filename; | ||||||
|         public boolean isCorrupted; |         public boolean isCorrupted; | ||||||
|         public List<OVFPropertyTO> ovfProperties; |         public List<OVFPropertyTO> ovfProperties; | ||||||
|         public List<NetworkPrerequisiteTO> networks; |         public List<OVFNetworkTO> networks; | ||||||
|         public List<DatadiskTO> disks; |         public List<DatadiskTO> disks; | ||||||
|         public OVFVirtualHardwareSectionTO hardwareSection; |         public OVFVirtualHardwareSectionTO hardwareSection; | ||||||
|         public List<OVFEulaSectionTO> eulaSections; |         public List<OVFEulaSectionTO> eulaSections; | ||||||
|  | |||||||
| @ -17,10 +17,11 @@ | |||||||
| package com.cloud.agent.api.storage; | package com.cloud.agent.api.storage; | ||||||
| 
 | 
 | ||||||
| import com.cloud.agent.api.Answer; | import com.cloud.agent.api.Answer; | ||||||
|  | import com.cloud.agent.api.to.deployasis.OVFPropertyTO; | ||||||
| import com.cloud.serializer.GsonHelper; | import com.cloud.serializer.GsonHelper; | ||||||
| import com.cloud.storage.VMTemplateStorageResourceAssoc; | import com.cloud.storage.VMTemplateStorageResourceAssoc; | ||||||
| import com.google.gson.Gson; | 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.Assert; | ||||||
| import org.junit.Test; | import org.junit.Test; | ||||||
| 
 | 
 | ||||||
| @ -45,8 +46,8 @@ public class DownloadAnswerTest { | |||||||
|     { |     { | ||||||
|         List<OVFPropertyTO> properties = new ArrayList<>(); |         List<OVFPropertyTO> properties = new ArrayList<>(); | ||||||
|         properties.add(new OVFPropertyTO()); |         properties.add(new OVFPropertyTO()); | ||||||
|         List<NetworkPrerequisiteTO> networks = new ArrayList<>(); |         List<OVFNetworkTO> networks = new ArrayList<>(); | ||||||
|         networks.add(new NetworkPrerequisiteTO()); |         networks.add(new OVFNetworkTO()); | ||||||
| 
 | 
 | ||||||
|         answer.setOvfProperties(properties); |         answer.setOvfProperties(properties); | ||||||
|         answer.setNetworkRequirements(networks); |         answer.setNetworkRequirements(networks); | ||||||
|  | |||||||
| @ -1472,8 +1472,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac | |||||||
|             if (disk.getType() != Volume.Type.ISO) { |             if (disk.getType() != Volume.Type.ISO) { | ||||||
|                 final VolumeObjectTO vol = (VolumeObjectTO)disk.getData(); |                 final VolumeObjectTO vol = (VolumeObjectTO)disk.getData(); | ||||||
|                 final VolumeVO volume = _volsDao.findById(vol.getId()); |                 final VolumeVO volume = _volsDao.findById(vol.getId()); | ||||||
|                 if (vmSpec.getDeployAsIsInfo() != null && vmSpec.getDeployAsIsInfo().isDeployAsIs() |                 if (vmSpec.getDeployAsIsInfo() != null && StringUtils.isNotBlank(vol.getPath())) { | ||||||
|                         && StringUtils.isNotBlank(vol.getPath())) { |  | ||||||
|                     volume.setPath(vol.getPath()); |                     volume.setPath(vol.getPath()); | ||||||
|                     _volsDao.update(volume.getId(), volume); |                     _volsDao.update(volume.getId(), volume); | ||||||
|                 } |                 } | ||||||
|  | |||||||
| @ -40,9 +40,10 @@ import java.util.stream.Collectors; | |||||||
| import javax.inject.Inject; | import javax.inject.Inject; | ||||||
| import javax.naming.ConfigurationException; | import javax.naming.ConfigurationException; | ||||||
| 
 | 
 | ||||||
|  | import com.cloud.deployasis.dao.TemplateDeployAsIsDetailsDao; | ||||||
| import org.apache.cloudstack.acl.ControlledEntity.ACLType; | import org.apache.cloudstack.acl.ControlledEntity.ACLType; | ||||||
| import org.apache.cloudstack.api.ApiConstants; | 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.context.CallContext; | ||||||
| import org.apache.cloudstack.engine.cloud.entity.api.db.VMNetworkMapVO; | import org.apache.cloudstack.engine.cloud.entity.api.db.VMNetworkMapVO; | ||||||
| import org.apache.cloudstack.engine.cloud.entity.api.db.dao.VMNetworkMapDao; | 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.NetworkOfferingDao; | ||||||
| import com.cloud.offerings.dao.NetworkOfferingDetailsDao; | import com.cloud.offerings.dao.NetworkOfferingDetailsDao; | ||||||
| import com.cloud.offerings.dao.NetworkOfferingServiceMapDao; | import com.cloud.offerings.dao.NetworkOfferingServiceMapDao; | ||||||
| import com.cloud.storage.dao.VMTemplateDetailsDao; |  | ||||||
| import com.cloud.user.Account; | import com.cloud.user.Account; | ||||||
| import com.cloud.user.ResourceLimitService; | import com.cloud.user.ResourceLimitService; | ||||||
| import com.cloud.user.User; | import com.cloud.user.User; | ||||||
| @ -304,7 +304,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra | |||||||
|     @Inject |     @Inject | ||||||
|     UserVmManager _userVmMgr; |     UserVmManager _userVmMgr; | ||||||
|     @Inject |     @Inject | ||||||
|     VMTemplateDetailsDao templateDetailsDao; |     TemplateDeployAsIsDetailsDao templateDeployAsIsDetailsDao; | ||||||
| 
 | 
 | ||||||
|     List<NetworkGuru> networkGurus; |     List<NetworkGuru> networkGurus; | ||||||
| 
 | 
 | ||||||
| @ -884,7 +884,7 @@ public class NetworkOrchestrator extends ManagerBase implements NetworkOrchestra | |||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 List<NetworkPrerequisiteTO> netprereqs = templateDetailsDao.listNetworkRequirementsByTemplateId(vm.getTemplate().getId()); |                 List<OVFNetworkTO> netprereqs = templateDeployAsIsDetailsDao.listNetworkRequirementsByTemplateId(vm.getTemplate().getId()); | ||||||
|                 if (size < netprereqs.size()) { |                 if (size < netprereqs.size()) { | ||||||
|                     size = netprereqs.size(); |                     size = netprereqs.size(); | ||||||
|                 } |                 } | ||||||
|  | |||||||
| @ -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; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -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; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -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; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -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; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -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<TemplateDeployAsIsDetailVO, Long>, ResourceDetailsDao<TemplateDeployAsIsDetailVO> { | ||||||
|  | 
 | ||||||
|  |     OVFPropertyTO findPropertyByTemplateAndKey(long templateId, String key); | ||||||
|  |     List<TemplateDeployAsIsDetailVO> listDetailsByTemplateIdMatchingPrefix(long templateId, String prefix); | ||||||
|  |     List<OVFNetworkTO> listNetworkRequirementsByTemplateId(long templateId); | ||||||
|  | } | ||||||
| @ -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<TemplateDeployAsIsDetailVO> 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<TemplateDeployAsIsDetailVO> 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<TemplateDeployAsIsDetailVO> listDetailsByTemplateIdMatchingPrefix(long templateId, String prefix) { | ||||||
|  |         SearchCriteria<TemplateDeployAsIsDetailVO> ssc = createSearchCriteria(); | ||||||
|  |         ssc.addAnd("templateId", SearchCriteria.Op.EQ, templateId); | ||||||
|  |         ssc.addAnd("name", SearchCriteria.Op.LIKE, prefix + "%"); | ||||||
|  | 
 | ||||||
|  |         return search(ssc, null); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public List<OVFNetworkTO> listNetworkRequirementsByTemplateId(long templateId) { | ||||||
|  |         List<TemplateDeployAsIsDetailVO> networkDetails = listDetailsByTemplateIdMatchingPrefix(templateId, DeployAsIsConstants.REQUIRED_NETWORK_PREFIX); | ||||||
|  |         List<OVFNetworkTO> networkPrereqs = new ArrayList<>(); | ||||||
|  |         for (TemplateDeployAsIsDetailVO property : networkDetails) { | ||||||
|  |             OVFNetworkTO ovfPropertyTO = gson.fromJson(property.getValue(), OVFNetworkTO.class); | ||||||
|  |             networkPrereqs.add(ovfPropertyTO); | ||||||
|  |         } | ||||||
|  |         networkPrereqs.sort(new Comparator<OVFNetworkTO>() { | ||||||
|  |             @Override | ||||||
|  |             public int compare(OVFNetworkTO o1, OVFNetworkTO o2) { | ||||||
|  |                 return o1.getInstanceID() - o2.getInstanceID(); | ||||||
|  |             } | ||||||
|  |         }); | ||||||
|  |         return networkPrereqs; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -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<TemplateDeployAsIsDetailVO> 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<TemplateDeployAsIsDetailVO> 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<TemplateDeployAsIsDetailVO> listDetailsByTemplateIdMatchingPrefix(long templateId, String prefix) { | ||||||
|  |         SearchCriteria<TemplateDeployAsIsDetailVO> ssc = createSearchCriteria(); | ||||||
|  |         ssc.addAnd("resouceId", SearchCriteria.Op.EQ, templateId); | ||||||
|  |         ssc.addAnd("name", SearchCriteria.Op.LIKE, prefix + "%"); | ||||||
|  | 
 | ||||||
|  |         return search(ssc, null); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public List<OVFNetworkTO> listNetworkRequirementsByTemplateId(long templateId) { | ||||||
|  |         List<TemplateDeployAsIsDetailVO> networkDetails = listDetailsByTemplateIdMatchingPrefix(templateId, DeployAsIsConstants.REQUIRED_NETWORK_PREFIX); | ||||||
|  |         List<OVFNetworkTO> networkPrereqs = new ArrayList<>(); | ||||||
|  |         for (TemplateDeployAsIsDetailVO property : networkDetails) { | ||||||
|  |             OVFNetworkTO ovfPropertyTO = gson.fromJson(property.getValue(), OVFNetworkTO.class); | ||||||
|  |             networkPrereqs.add(ovfPropertyTO); | ||||||
|  |         } | ||||||
|  |         networkPrereqs.sort(new Comparator<OVFNetworkTO>() { | ||||||
|  |             @Override | ||||||
|  |             public int compare(OVFNetworkTO o1, OVFNetworkTO o2) { | ||||||
|  |                 return o1.getInstanceID() - o2.getInstanceID(); | ||||||
|  |             } | ||||||
|  |         }); | ||||||
|  |         return networkPrereqs; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -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<UserVmDeployAsIsDetailVO, Long>, ResourceDetailsDao<UserVmDeployAsIsDetailVO> { | ||||||
|  | } | ||||||
| @ -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<UserVmDeployAsIsDetailVO> implements UserVmDeployAsIsDetailsDao { | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public void addDetail(long resourceId, String key, String value, boolean display) { | ||||||
|  |         super.addDetail(new UserVmDeployAsIsDetailVO(resourceId, key, value)); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -21,7 +21,6 @@ import javax.persistence.Entity; | |||||||
| import javax.persistence.GeneratedValue; | import javax.persistence.GeneratedValue; | ||||||
| import javax.persistence.GenerationType; | import javax.persistence.GenerationType; | ||||||
| import javax.persistence.Id; | import javax.persistence.Id; | ||||||
| import javax.persistence.Lob; |  | ||||||
| import javax.persistence.Table; | import javax.persistence.Table; | ||||||
| 
 | 
 | ||||||
| import org.apache.cloudstack.api.ResourceDetail; | import org.apache.cloudstack.api.ResourceDetail; | ||||||
| @ -40,8 +39,7 @@ public class VMTemplateDetailVO implements ResourceDetail { | |||||||
|     @Column(name = "name") |     @Column(name = "name") | ||||||
|     private String name; |     private String name; | ||||||
| 
 | 
 | ||||||
|     @Lob |     @Column(name = "value", length = 1024) | ||||||
|     @Column(name = "value", length = 65535) |  | ||||||
|     private String value; |     private String value; | ||||||
| 
 | 
 | ||||||
|     @Column(name = "display") |     @Column(name = "display") | ||||||
|  | |||||||
| @ -16,25 +16,11 @@ | |||||||
| // under the License. | // under the License. | ||||||
| package com.cloud.storage.dao; | 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 org.apache.cloudstack.resourcedetail.ResourceDetailsDao; | ||||||
| 
 | 
 | ||||||
| import com.cloud.storage.VMTemplateDetailVO; | import com.cloud.storage.VMTemplateDetailVO; | ||||||
| import com.cloud.utils.db.GenericDao; | import com.cloud.utils.db.GenericDao; | ||||||
| 
 | 
 | ||||||
| import java.util.List; |  | ||||||
| 
 |  | ||||||
| public interface VMTemplateDetailsDao extends GenericDao<VMTemplateDetailVO, Long>, ResourceDetailsDao<VMTemplateDetailVO> { | public interface VMTemplateDetailsDao extends GenericDao<VMTemplateDetailVO, Long>, ResourceDetailsDao<VMTemplateDetailVO> { | ||||||
| 
 | 
 | ||||||
|     boolean existsOption(long templateId, String key); |  | ||||||
|     OVFPropertyTO findPropertyByTemplateAndKey(long templateId, String key); |  | ||||||
|     void saveOptions(List<OVFPropertyTO> opts); |  | ||||||
|     List<OVFPropertyTO> listPropertiesByTemplateId(long templateId); |  | ||||||
|     List<NetworkPrerequisiteTO> listNetworkRequirementsByTemplateId(long templateId); |  | ||||||
|     List<DatadiskTO> listDisksByTemplateId(long templateId); |  | ||||||
| 
 |  | ||||||
|     List<VMTemplateDetailVO> listDetailsByTemplateIdMatchingPrefix(long templateId, String prefix); |  | ||||||
|     String getTemplateEulaSectionsUrl(long templateId); |  | ||||||
| } | } | ||||||
|  | |||||||
| @ -17,137 +17,17 @@ | |||||||
| package com.cloud.storage.dao; | 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 org.springframework.stereotype.Component; | ||||||
| 
 | 
 | ||||||
| import com.cloud.agent.api.storage.OVFPropertyTO; | import org.apache.cloudstack.resourcedetail.ResourceDetailsDaoBase; | ||||||
| import com.cloud.agent.api.to.DatadiskTO; | 
 | ||||||
| import com.cloud.storage.ImageStore; |  | ||||||
| import com.cloud.storage.VMTemplateDetailVO; | 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 | @Component | ||||||
| public class VMTemplateDetailsDaoImpl extends ResourceDetailsDaoBase<VMTemplateDetailVO> implements VMTemplateDetailsDao { | public class VMTemplateDetailsDaoImpl extends ResourceDetailsDaoBase<VMTemplateDetailVO> implements VMTemplateDetailsDao { | ||||||
| 
 | 
 | ||||||
|     private final static Logger LOGGER = Logger.getLogger(VMTemplateDetailsDaoImpl.class); |  | ||||||
| 
 |  | ||||||
|     Gson gson = new Gson(); |  | ||||||
| 
 |  | ||||||
|     SearchBuilder<VMTemplateDetailVO> 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 |     @Override | ||||||
|     public void addDetail(long resourceId, String key, String value, boolean display) { |     public void addDetail(long resourceId, String key, String value, boolean display) { | ||||||
|         super.addDetail(new VMTemplateDetailVO(resourceId, key, value, 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<VMTemplateDetailVO> 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<OVFPropertyTO> 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<OVFPropertyTO> listPropertiesByTemplateId(long templateId) { |  | ||||||
|         List<VMTemplateDetailVO> ovfProperties = listDetailsByTemplateIdMatchingPrefix(templateId, ImageStore.ACS_PROPERTY_PREFIX); |  | ||||||
|         List<OVFPropertyTO> properties = new ArrayList<>(); |  | ||||||
|         for (VMTemplateDetailVO property : ovfProperties) { |  | ||||||
|             OVFPropertyTO ovfPropertyTO = gson.fromJson(property.getValue(), OVFPropertyTO.class); |  | ||||||
|             properties.add(ovfPropertyTO); |  | ||||||
|         } |  | ||||||
|         return properties; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public List<NetworkPrerequisiteTO> listNetworkRequirementsByTemplateId(long templateId) { |  | ||||||
|         List<VMTemplateDetailVO> networkDetails = listDetailsByTemplateIdMatchingPrefix(templateId, ImageStore.REQUIRED_NETWORK_PREFIX); |  | ||||||
|         List<NetworkPrerequisiteTO> networkPrereqs = new ArrayList<>(); |  | ||||||
|         for (VMTemplateDetailVO property : networkDetails) { |  | ||||||
|             NetworkPrerequisiteTO ovfPropertyTO = gson.fromJson(property.getValue(), NetworkPrerequisiteTO.class); |  | ||||||
|             networkPrereqs.add(ovfPropertyTO); |  | ||||||
|         } |  | ||||||
|         networkPrereqs.sort(new Comparator<NetworkPrerequisiteTO>() { |  | ||||||
|             @Override |  | ||||||
|             public int compare(NetworkPrerequisiteTO o1, NetworkPrerequisiteTO o2) { |  | ||||||
|                 return o1.getInstanceID() - o2.getInstanceID(); |  | ||||||
|             } |  | ||||||
|         }); |  | ||||||
|         return networkPrereqs; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public List<DatadiskTO> listDisksByTemplateId(long templateId) { |  | ||||||
|         List<VMTemplateDetailVO> diskDefinitions = listDetailsByTemplateIdMatchingPrefix(templateId, ImageStore.DISK_DEFINITION_PREFIX); |  | ||||||
|         List<DatadiskTO> disks = new ArrayList<>(); |  | ||||||
|         for (VMTemplateDetailVO detail : diskDefinitions) { |  | ||||||
|             DatadiskTO datadiskTO = gson.fromJson(detail.getValue(), DatadiskTO.class); |  | ||||||
|             disks.add(datadiskTO); |  | ||||||
|         } |  | ||||||
|         return disks; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     @Override |  | ||||||
|     public List<VMTemplateDetailVO> listDetailsByTemplateIdMatchingPrefix(long templateId, String prefix) { |  | ||||||
|         SearchCriteria<VMTemplateDetailVO> 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<VMTemplateDetailVO> 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(); |  | ||||||
|     } |  | ||||||
| } | } | ||||||
| @ -30,7 +30,6 @@ import javax.annotation.PostConstruct; | |||||||
| import javax.inject.Inject; | import javax.inject.Inject; | ||||||
| 
 | 
 | ||||||
| import com.cloud.offerings.dao.NetworkOfferingServiceMapDao; | import com.cloud.offerings.dao.NetworkOfferingServiceMapDao; | ||||||
| import com.cloud.storage.ImageStore; |  | ||||||
| import org.apache.commons.collections.CollectionUtils; | import org.apache.commons.collections.CollectionUtils; | ||||||
| import org.apache.log4j.Logger; | import org.apache.log4j.Logger; | ||||||
| 
 | 
 | ||||||
| @ -383,25 +382,13 @@ public class UserVmDaoImpl extends GenericDaoBase<UserVmVO, Long> implements Use | |||||||
| 
 | 
 | ||||||
|         List<UserVmDetailVO> details = new ArrayList<UserVmDetailVO>(); |         List<UserVmDetailVO> details = new ArrayList<UserVmDetailVO>(); | ||||||
|         for (Map.Entry<String, String> entry : detailsStr.entrySet()) { |         for (Map.Entry<String, String> 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)); |             details.add(new UserVmDetailVO(vm.getId(), entry.getKey(), entry.getValue(), display)); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         _detailsDao.saveDetails(details); |         _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 |     @Override | ||||||
|     public List<Long> listPodIdsHavingVmsforAccount(long zoneId, long accountId) { |     public List<Long> listPodIdsHavingVmsforAccount(long zoneId, long accountId) { | ||||||
|         TransactionLegacy txn = TransactionLegacy.currentTxn(); |         TransactionLegacy txn = TransactionLegacy.currentTxn(); | ||||||
|  | |||||||
| @ -295,4 +295,6 @@ | |||||||
|   <bean id="directDownloadCertificateHostMapDaoImpl" class="org.apache.cloudstack.direct.download.DirectDownloadCertificateHostMapDaoImpl" /> |   <bean id="directDownloadCertificateHostMapDaoImpl" class="org.apache.cloudstack.direct.download.DirectDownloadCertificateHostMapDaoImpl" /> | ||||||
|   <bean id="routerHealthCheckResultsDaoImpl" class="com.cloud.network.dao.RouterHealthCheckResultDaoImpl" /> |   <bean id="routerHealthCheckResultsDaoImpl" class="com.cloud.network.dao.RouterHealthCheckResultDaoImpl" /> | ||||||
|   <bean id="VsphereStoragePolicyDaoImpl" class="com.cloud.dc.dao.VsphereStoragePolicyDaoImpl" /> |   <bean id="VsphereStoragePolicyDaoImpl" class="com.cloud.dc.dao.VsphereStoragePolicyDaoImpl" /> | ||||||
|  |   <bean id="TemplateDeployAsIsDetailsDaoImpl" class="com.cloud.deployasis.dao.TemplateDeployAsIsDetailsDaoImpl" /> | ||||||
|  |   <bean id="UserVmDeployAsIsDetailsDaoImpl" class="com.cloud.deployasis.dao.UserVmDeployAsIsDetailsDaoImpl" /> | ||||||
| </beans> | </beans> | ||||||
|  | |||||||
| @ -473,6 +473,92 @@ ADD CONSTRAINT `fk_template_spool_ref__template_id` | |||||||
|   ON DELETE NO ACTION |   ON DELETE NO ACTION | ||||||
|   ON UPDATE 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 TABLE `cloud`.`image_store` ADD COLUMN `readonly` boolean DEFAULT false COMMENT 'defines status of image store'; | ||||||
| 
 | 
 | ||||||
| ALTER VIEW `cloud`.`image_store_view` AS | ALTER VIEW `cloud`.`image_store_view` AS | ||||||
|  | |||||||
| @ -18,7 +18,6 @@ | |||||||
|  */ |  */ | ||||||
| package org.apache.cloudstack.storage.image; | package org.apache.cloudstack.storage.image; | ||||||
| 
 | 
 | ||||||
| import java.io.IOException; |  | ||||||
| import java.net.URI; | import java.net.URI; | ||||||
| import java.net.URISyntaxException; | import java.net.URISyntaxException; | ||||||
| import java.sql.PreparedStatement; | import java.sql.PreparedStatement; | ||||||
| @ -33,19 +32,8 @@ import java.util.stream.Collectors; | |||||||
| 
 | 
 | ||||||
| import javax.inject.Inject; | 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.Upload; | ||||||
| import com.cloud.storage.VMTemplateDetailVO; | import org.apache.cloudstack.storage.image.deployasis.DeployAsIsHelper; | ||||||
| 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.log4j.Logger; | import org.apache.log4j.Logger; | ||||||
| 
 | 
 | ||||||
| import org.apache.cloudstack.engine.subsystem.api.storage.CopyCommandResult; | 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.VMTemplateVO; | ||||||
| import com.cloud.storage.VolumeVO; | import com.cloud.storage.VolumeVO; | ||||||
| import com.cloud.storage.dao.VMTemplateDao; | import com.cloud.storage.dao.VMTemplateDao; | ||||||
| import com.cloud.storage.dao.VMTemplateDetailsDao; |  | ||||||
| import com.cloud.storage.dao.VMTemplateZoneDao; | import com.cloud.storage.dao.VMTemplateZoneDao; | ||||||
| import com.cloud.storage.dao.VolumeDao; | import com.cloud.storage.dao.VolumeDao; | ||||||
| import com.cloud.storage.download.DownloadMonitor; | import com.cloud.storage.download.DownloadMonitor; | ||||||
| @ -123,14 +110,14 @@ public abstract class BaseImageStoreDriverImpl implements ImageStoreDriver { | |||||||
|     @Inject |     @Inject | ||||||
|     AlertManager _alertMgr; |     AlertManager _alertMgr; | ||||||
|     @Inject |     @Inject | ||||||
|     VMTemplateDetailsDao templateDetailsDao; |  | ||||||
|     @Inject |  | ||||||
|     DefaultEndPointSelector _defaultEpSelector; |     DefaultEndPointSelector _defaultEpSelector; | ||||||
|     @Inject |     @Inject | ||||||
|     AccountDao _accountDao; |     AccountDao _accountDao; | ||||||
|     @Inject |     @Inject | ||||||
|     ResourceLimitService _resourceLimitMgr; |     ResourceLimitService _resourceLimitMgr; | ||||||
|     @Inject |     @Inject | ||||||
|  |     DeployAsIsHelper deployAsIsHelper; | ||||||
|  |     @Inject | ||||||
|     HostDao hostDao; |     HostDao hostDao; | ||||||
|     @Inject |     @Inject | ||||||
|     CommandExecLogDao _cmdExecLogDao; |     CommandExecLogDao _cmdExecLogDao; | ||||||
| @ -143,14 +130,6 @@ public abstract class BaseImageStoreDriverImpl implements ImageStoreDriver { | |||||||
| 
 | 
 | ||||||
|     protected String _proxy = null; |     protected String _proxy = null; | ||||||
| 
 | 
 | ||||||
|     private static Gson gson; |  | ||||||
| 
 |  | ||||||
|     static { |  | ||||||
|         GsonBuilder builder = new GsonBuilder(); |  | ||||||
|         builder.disableHtmlEscaping(); |  | ||||||
|         gson = builder.create(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     protected Proxy getHttpProxy() { |     protected Proxy getHttpProxy() { | ||||||
|         if (_proxy == null) { |         if (_proxy == null) { | ||||||
|             return 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<OVFPropertyTO> 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<NetworkPrerequisiteTO> 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<DatadiskTO> 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<? extends BaseImageStoreDriverImpl, DownloadAnswer> callback, |     protected Void createTemplateAsyncCallback(AsyncCallbackDispatcher<? extends BaseImageStoreDriverImpl, DownloadAnswer> callback, | ||||||
|                                                CreateContext<CreateCmdResult> context) { |                                                CreateContext<CreateCmdResult> context) { | ||||||
|         if (LOGGER.isDebugEnabled()) { |         if (LOGGER.isDebugEnabled()) { | ||||||
| @ -304,17 +198,14 @@ public abstract class BaseImageStoreDriverImpl implements ImageStoreDriver { | |||||||
|         DownloadAnswer answer = callback.getResult(); |         DownloadAnswer answer = callback.getResult(); | ||||||
|         DataObject obj = context.data; |         DataObject obj = context.data; | ||||||
|         DataStore store = obj.getDataStore(); |         DataStore store = obj.getDataStore(); | ||||||
|         List<OVFPropertyTO> ovfProperties = answer.getOvfProperties(); |  | ||||||
|         List<NetworkPrerequisiteTO> networkRequirements = answer.getNetworkRequirements(); |  | ||||||
|         List<DatadiskTO> disks = answer.getDisks(); |  | ||||||
|         OVFVirtualHardwareSectionTO ovfHardwareSection = answer.getOvfHardwareSection(); |  | ||||||
|         List<OVFEulaSectionTO> eulaSections = answer.getEulaSections(); |  | ||||||
| 
 | 
 | ||||||
|         VMTemplateVO template = _templateDao.findById(obj.getId()); |         VMTemplateVO template = _templateDao.findById(obj.getId()); | ||||||
|         TemplateDataStoreVO tmpltStoreVO = _templateStoreDao.findByStoreTemplate(store.getId(), obj.getId()); |         TemplateDataStoreVO tmpltStoreVO = _templateStoreDao.findByStoreTemplate(store.getId(), obj.getId()); | ||||||
|         if (tmpltStoreVO != null) { |         if (tmpltStoreVO != null) { | ||||||
|             if (tmpltStoreVO.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) { |             if (tmpltStoreVO.getDownloadState() == VMTemplateStorageResourceAssoc.Status.DOWNLOADED) { | ||||||
|                 persistExtraDetails(obj, ovfProperties, networkRequirements, disks, ovfHardwareSection, eulaSections); |                 if (template.isDeployAsIs()) { | ||||||
|  |                     deployAsIsHelper.persistTemplateDeployAsIsDetails(template.getId(), answer); | ||||||
|  |                 } | ||||||
|                 if (LOGGER.isDebugEnabled()) { |                 if (LOGGER.isDebugEnabled()) { | ||||||
|                     LOGGER.debug("Template is already in DOWNLOADED state, ignore further incoming DownloadAnswer"); |                     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()); |                 templateDaoBuilder.setChecksum(answer.getCheckSum()); | ||||||
|                 _templateDao.update(obj.getId(), templateDaoBuilder); |                 _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); |             CreateCmdResult result = new CreateCmdResult(null, null); | ||||||
|             caller.complete(result); |             caller.complete(result); | ||||||
| @ -362,76 +255,6 @@ public abstract class BaseImageStoreDriverImpl implements ImageStoreDriver { | |||||||
|         return null; |         return null; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private void persistExtraDetails(DataObject obj, List<OVFPropertyTO> ovfProperties, List<NetworkPrerequisiteTO> networkRequirements, List<DatadiskTO> disks, OVFVirtualHardwareSectionTO ovfHardwareSection, List<OVFEulaSectionTO> 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<OVFEulaSectionTO> 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 |     protected Void | ||||||
|     createVolumeAsyncCallback(AsyncCallbackDispatcher<? extends BaseImageStoreDriverImpl, DownloadAnswer> callback, CreateContext<CreateCmdResult> context) { |     createVolumeAsyncCallback(AsyncCallbackDispatcher<? extends BaseImageStoreDriverImpl, DownloadAnswer> callback, CreateContext<CreateCmdResult> context) { | ||||||
|         DownloadAnswer answer = callback.getResult(); |         DownloadAnswer answer = callback.getResult(); | ||||||
|  | |||||||
| @ -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<String, String> getVirtualMachineDeployAsIsProperties(VirtualMachineProfile vmId); | ||||||
|  | 
 | ||||||
|  |     String getAllocatedVirtualMachineTemplatePath(VirtualMachineProfile vm, String configuration, String destStoragePool); | ||||||
|  |     String getAllocatedVirtualMachineDestinationStoragePool(VirtualMachineProfile vm); | ||||||
|  | } | ||||||
| @ -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<OVFPropertyTO> ovfProperties = answer.getOvfProperties(); | ||||||
|  |         List<OVFNetworkTO> networkRequirements = answer.getNetworkRequirements(); | ||||||
|  |         OVFVirtualHardwareSectionTO ovfHardwareSection = answer.getOvfHardwareSection(); | ||||||
|  |         List<OVFEulaSectionTO> 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<String, String> getVirtualMachineDeployAsIsProperties(VirtualMachineProfile vm) { | ||||||
|  |         Map<String, String> map = new HashMap<>(); | ||||||
|  |         List<UserVmDeployAsIsDetailVO> 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<? extends TemplateDeployAsIsInformationTO> 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); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -72,4 +72,6 @@ | |||||||
|      |      | ||||||
|     <bean id="imageStoreDetailsUtil" class="com.cloud.storage.ImageStoreDetailsUtil" /> |     <bean id="imageStoreDetailsUtil" class="com.cloud.storage.ImageStoreDetailsUtil" /> | ||||||
| 
 | 
 | ||||||
|  |     <bean id="deployAsIsImageStoreHelper" class="org.apache.cloudstack.storage.image.deployasis.DeployAsIsHelperImpl" /> | ||||||
|  | 
 | ||||||
| </beans> | </beans> | ||||||
|  | |||||||
| @ -16,9 +16,7 @@ | |||||||
| // under the License. | // under the License. | ||||||
| package com.cloud.hypervisor.guru; | 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.DeployAsIsInfoTO; | ||||||
| import com.cloud.agent.api.to.DiskTO; |  | ||||||
| import com.cloud.agent.api.to.NicTO; | import com.cloud.agent.api.to.NicTO; | ||||||
| import com.cloud.agent.api.to.VirtualMachineTO; | import com.cloud.agent.api.to.VirtualMachineTO; | ||||||
| import com.cloud.exception.InsufficientAddressCapacityException; | import com.cloud.exception.InsufficientAddressCapacityException; | ||||||
| @ -35,12 +33,8 @@ import com.cloud.network.dao.NetworkDao; | |||||||
| import com.cloud.network.dao.NetworkVO; | import com.cloud.network.dao.NetworkVO; | ||||||
| import com.cloud.storage.GuestOSHypervisorVO; | import com.cloud.storage.GuestOSHypervisorVO; | ||||||
| import com.cloud.storage.GuestOSVO; | 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.GuestOSDao; | ||||||
| import com.cloud.storage.dao.GuestOSHypervisorDao; | import com.cloud.storage.dao.GuestOSHypervisorDao; | ||||||
| import com.cloud.storage.dao.VMTemplateDetailsDao; |  | ||||||
| import com.cloud.storage.dao.VMTemplatePoolDao; | import com.cloud.storage.dao.VMTemplatePoolDao; | ||||||
| import com.cloud.template.VirtualMachineTemplate; | import com.cloud.template.VirtualMachineTemplate; | ||||||
| import com.cloud.utils.exception.CloudRuntimeException; | import com.cloud.utils.exception.CloudRuntimeException; | ||||||
| @ -51,10 +45,8 @@ import com.cloud.vm.VirtualMachineProfile; | |||||||
| import com.cloud.vm.VmDetailConstants; | import com.cloud.vm.VmDetailConstants; | ||||||
| import com.cloud.vm.dao.DomainRouterDao; | import com.cloud.vm.dao.DomainRouterDao; | ||||||
| import com.cloud.vm.dao.NicDao; | 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.PrimaryDataStoreDao; | ||||||
| import org.apache.cloudstack.storage.datastore.db.StoragePoolVO; | import org.apache.cloudstack.storage.image.deployasis.DeployAsIsHelper; | ||||||
| import org.apache.commons.collections.CollectionUtils; |  | ||||||
| import org.apache.commons.lang.BooleanUtils; | import org.apache.commons.lang.BooleanUtils; | ||||||
| import org.apache.log4j.Logger; | import org.apache.log4j.Logger; | ||||||
| 
 | 
 | ||||||
| @ -65,7 +57,6 @@ import java.util.Comparator; | |||||||
| import java.util.HashMap; | import java.util.HashMap; | ||||||
| import java.util.List; | import java.util.List; | ||||||
| import java.util.Map; | import java.util.Map; | ||||||
| import java.util.stream.Collectors; |  | ||||||
| 
 | 
 | ||||||
| class VmwareVmImplementer { | class VmwareVmImplementer { | ||||||
|     private static final Logger LOGGER = Logger.getLogger(VmwareVmImplementer.class); |     private static final Logger LOGGER = Logger.getLogger(VmwareVmImplementer.class); | ||||||
| @ -89,9 +80,9 @@ class VmwareVmImplementer { | |||||||
|     @Inject |     @Inject | ||||||
|     VMTemplatePoolDao templateStoragePoolDao; |     VMTemplatePoolDao templateStoragePoolDao; | ||||||
|     @Inject |     @Inject | ||||||
|     VMTemplateDetailsDao templateDetailsDao; |  | ||||||
|     @Inject |  | ||||||
|     VmwareManager vmwareMgr; |     VmwareManager vmwareMgr; | ||||||
|  |     @Inject | ||||||
|  |     DeployAsIsHelper deployAsIsHelper; | ||||||
| 
 | 
 | ||||||
|     private Boolean globalNestedVirtualisationEnabled; |     private Boolean globalNestedVirtualisationEnabled; | ||||||
|     private Boolean globalNestedVPerVMEnabled; |     private Boolean globalNestedVPerVMEnabled; | ||||||
| @ -183,9 +174,7 @@ class VmwareVmImplementer { | |||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         if (deployAsIs) { |         if (deployAsIs) { | ||||||
|             List<OVFPropertyTO> ovfProperties = getOvfPropertyList(vm, details); |             setDeployAsIsInfoTO(vm, to, details); | ||||||
|             handleOvfProperties(vm, to, details, ovfProperties); |  | ||||||
|             setDeployAsIsParams(vm, to, details); |  | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         setDetails(to, details); |         setDetails(to, details); | ||||||
| @ -193,44 +182,25 @@ class VmwareVmImplementer { | |||||||
|         return to; |         return to; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private void setDeployAsIsParams(VirtualMachineProfile vm, VirtualMachineTO to, Map<String, String> details) { |     /** | ||||||
|         DeployAsIsInfoTO info = new DeployAsIsInfoTO(); |      * Set the information relevant for deploy-as-is VMs on the VM TO | ||||||
| 
 |      */ | ||||||
|         String configuration = null; |     private void setDeployAsIsInfoTO(VirtualMachineProfile vm, VirtualMachineTO to, Map<String, String> details) { | ||||||
|         if (details.containsKey(VmDetailConstants.DEPLOY_AS_IS_CONFIGURATION)) { |         String configuration = details.getOrDefault(VmDetailConstants.DEPLOY_AS_IS_CONFIGURATION, null); | ||||||
|             configuration = details.get(VmDetailConstants.DEPLOY_AS_IS_CONFIGURATION); |         Map<String, String> properties = deployAsIsHelper.getVirtualMachineDeployAsIsProperties(vm); | ||||||
|             info.setDeploymentConfiguration(configuration); |         String destStoragePool = deployAsIsHelper.getAllocatedVirtualMachineDestinationStoragePool(vm); | ||||||
|         } |         String templatePath = deployAsIsHelper.getAllocatedVirtualMachineTemplatePath(vm, configuration, destStoragePool); | ||||||
| 
 |         DeployAsIsInfoTO info = new DeployAsIsInfoTO(templatePath, destStoragePool, properties); | ||||||
|         // 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); |  | ||||||
|         to.setDeployAsIsInfo(info); |         to.setDeployAsIsInfo(info); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private void setDetails(VirtualMachineTO to, Map<String, String> details) { |     private void setDetails(VirtualMachineTO to, Map<String, String> details) { | ||||||
|         Map<String, String> 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))); |                 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<String, String> details, List<NicProfile> nicProfiles) { |     private void configureDomainRouterNicsAndDetails(VirtualMachineProfile vm, VirtualMachineTO to, Map<String, String> details, List<NicProfile> nicProfiles) { | ||||||
| @ -318,49 +288,6 @@ class VmwareVmImplementer { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     private void handleOvfProperties(VirtualMachineProfile vm, VirtualMachineTO to, Map<String, String> details, List<OVFPropertyTO> ovfProperties) { |  | ||||||
|         if (CollectionUtils.isNotEmpty(ovfProperties)) { |  | ||||||
|             removeOvfPropertiesFromDetails(ovfProperties, details); |  | ||||||
|             to.setOvfProperties(ovfProperties); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     private DiskTO getRootDiskTOFromVM(VirtualMachineProfile vm) { |  | ||||||
|         DiskTO rootDiskTO; |  | ||||||
|         List<DiskTO> 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<OVFPropertyTO> getOvfPropertyList(VirtualMachineProfile vm, Map<String, String> details) { |  | ||||||
|         List<OVFPropertyTO> ovfProperties = new ArrayList<OVFPropertyTO>(); |  | ||||||
|         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<String, String> details) { |     private void addReservationDetails(long clusterId, Map<String, String> details) { | ||||||
|         details.put(VMwareGuru.VmwareReserveCpu.key(), VMwareGuru.VmwareReserveCpu.valueIn(clusterId).toString()); |         details.put(VMwareGuru.VmwareReserveCpu.key(), VMwareGuru.VmwareReserveCpu.valueIn(clusterId).toString()); | ||||||
|         details.put(VMwareGuru.VmwareReserveMemory.key(), VMwareGuru.VmwareReserveMemory.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()); | //        details.put(VmDetailConstants.BOOT_TYPE, to.getBootType()); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     /* |  | ||||||
|         Remove OVF properties from details to be sent to hypervisor (avoid duplicate data) |  | ||||||
|      */ |  | ||||||
|     private void removeOvfPropertiesFromDetails(List<OVFPropertyTO> ovfProperties, Map<String, String> 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 |      * Adds {@code 'nestedVirtualizationFlag'} value to {@code details} due to if it should be enabled or not | ||||||
|      * @param details vm details should not be null |      * @param details vm details should not be null | ||||||
|  | |||||||
| @ -47,7 +47,6 @@ import javax.xml.datatype.XMLGregorianCalendar; | |||||||
| 
 | 
 | ||||||
| import com.cloud.agent.api.to.DataTO; | import com.cloud.agent.api.to.DataTO; | ||||||
| import com.cloud.agent.api.to.DeployAsIsInfoTO; | import com.cloud.agent.api.to.DeployAsIsInfoTO; | ||||||
| import com.cloud.storage.ImageStore; |  | ||||||
| import com.cloud.agent.api.ValidateVcenterDetailsCommand; | import com.cloud.agent.api.ValidateVcenterDetailsCommand; | ||||||
| import org.apache.cloudstack.api.ApiConstants; | import org.apache.cloudstack.api.ApiConstants; | ||||||
| import org.apache.cloudstack.storage.configdrive.ConfigDrive; | 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.utils.volume.VirtualMachineDiskInfo; | ||||||
| import org.apache.cloudstack.vm.UnmanagedInstanceTO; | import org.apache.cloudstack.vm.UnmanagedInstanceTO; | ||||||
| import org.apache.commons.collections.CollectionUtils; | import org.apache.commons.collections.CollectionUtils; | ||||||
| import org.apache.commons.collections.MapUtils; |  | ||||||
| import org.apache.commons.lang.ArrayUtils; | import org.apache.commons.lang.ArrayUtils; | ||||||
| import org.apache.commons.lang.StringUtils; | import org.apache.commons.lang.StringUtils; | ||||||
| import org.apache.commons.lang.math.NumberUtils; | 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.DestroyCommand; | ||||||
| import com.cloud.agent.api.storage.MigrateVolumeAnswer; | import com.cloud.agent.api.storage.MigrateVolumeAnswer; | ||||||
| import com.cloud.agent.api.storage.MigrateVolumeCommand; | 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.PrimaryStorageDownloadAnswer; | ||||||
| import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand; | import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand; | ||||||
| import com.cloud.agent.api.storage.ResizeVolumeAnswer; | 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.NumbersUtil; | ||||||
| import com.cloud.utils.Pair; | import com.cloud.utils.Pair; | ||||||
| import com.cloud.utils.Ternary; | import com.cloud.utils.Ternary; | ||||||
| import com.cloud.utils.crypt.DBEncryptionUtil; |  | ||||||
| import com.cloud.utils.db.DB; | import com.cloud.utils.db.DB; | ||||||
| import com.cloud.utils.exception.CloudRuntimeException; | import com.cloud.utils.exception.CloudRuntimeException; | ||||||
| import com.cloud.utils.exception.ExceptionUtil; | import com.cloud.utils.exception.ExceptionUtil; | ||||||
| @ -1842,14 +1839,13 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa | |||||||
| 
 | 
 | ||||||
|             DiskTO[] specDisks = vmSpec.getDisks(); |             DiskTO[] specDisks = vmSpec.getDisks(); | ||||||
|             DeployAsIsInfoTO deployAsIsInfo = vmSpec.getDeployAsIsInfo(); |             DeployAsIsInfoTO deployAsIsInfo = vmSpec.getDeployAsIsInfo(); | ||||||
|             boolean installAsIs = deployAsIsInfo != null && deployAsIsInfo.isDeployAsIs(); |             boolean installAsIs = deployAsIsInfo != null; | ||||||
|             if (installAsIs && dcMo.findVm(vmInternalCSName) == null) { |             if (installAsIs && dcMo.findVm(vmInternalCSName) == null) { | ||||||
|                 if (s_logger.isTraceEnabled()) { |                 if (s_logger.isTraceEnabled()) { | ||||||
|                     s_logger.trace("Deploying OVA from as is"); |                     s_logger.trace("Deploying OVA from as is"); | ||||||
|                 } |                 } | ||||||
|                 String deployAsIsTemplate = deployAsIsInfo.getTemplatePath(); |                 String deployAsIsTemplate = deployAsIsInfo.getTemplatePath(); | ||||||
|                 String destDatastore = getDatastoreFromSpecDisks(specDisks); |                 String destDatastore = deployAsIsInfo.getDestStoragePool(); | ||||||
|                 String deploymentConfiguration = deployAsIsInfo.getDeploymentConfiguration(); |  | ||||||
|                 vmInVcenter = _storageProcessor.cloneVMFromTemplate(deployAsIsTemplate, vmInternalCSName, destDatastore); |                 vmInVcenter = _storageProcessor.cloneVMFromTemplate(deployAsIsTemplate, vmInternalCSName, destDatastore); | ||||||
|                 mapSpecDisksToClonedDisks(vmInVcenter, vmInternalCSName, specDisks); |                 mapSpecDisksToClonedDisks(vmInVcenter, vmInternalCSName, specDisks); | ||||||
|             } |             } | ||||||
| @ -1996,7 +1992,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa | |||||||
|             if (s_logger.isTraceEnabled()) { |             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)); |                 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++; |                 totalChangeDevices++; | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
| @ -2381,18 +2377,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa | |||||||
|             // config video card |             // config video card | ||||||
|             configureVideoCard(vmMo, vmSpec, vmConfigSpec); |             configureVideoCard(vmMo, vmSpec, vmConfigSpec); | ||||||
| 
 | 
 | ||||||
|             // Set OVF properties (if available) |             setDeployAsIsProperties(vmMo, deployAsIsInfo, vmConfigSpec); | ||||||
|             List<OVFPropertyTO> 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); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
| 
 | 
 | ||||||
|             setBootOptions(vmSpec, bootMode, 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) { |      * Set OVF properties (if available) | ||||||
|             return null; |      */ | ||||||
|  |     private void setDeployAsIsProperties(VirtualMachineMO vmMo, DeployAsIsInfoTO deployAsIsInfo, | ||||||
|  |                                          VirtualMachineConfigSpec vmConfigSpec) throws Exception { | ||||||
|  |         if (deployAsIsInfo != null) { | ||||||
|  |             Map<String, String> 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<String, List<DiskTO>> 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 |      * Set the properties section from existing vApp configuration and values set on ovfProperties | ||||||
|      */ |      */ | ||||||
|     protected List<VAppPropertySpec> copyVAppConfigPropertySectionFromOVF(VmConfigInfo vAppConfig, List<OVFPropertyTO> ovfProperties) { |     protected List<VAppPropertySpec> copyVAppConfigPropertySectionFromOVF(VmConfigInfo vAppConfig, Map<String, String> ovfProperties) { | ||||||
|         List<VAppPropertyInfo> productFromOvf = vAppConfig.getProperty(); |         List<VAppPropertyInfo> productFromOvf = vAppConfig.getProperty(); | ||||||
|         List<VAppPropertySpec> specs = new ArrayList<>(); |         List<VAppPropertySpec> specs = new ArrayList<>(); | ||||||
|         Map<String, Pair<String, Boolean>> ovfMap = getOVFMap(ovfProperties); |  | ||||||
|         for (VAppPropertyInfo info : productFromOvf) { |         for (VAppPropertyInfo info : productFromOvf) { | ||||||
|             VAppPropertySpec spec = new VAppPropertySpec(); |             VAppPropertySpec spec = new VAppPropertySpec(); | ||||||
|             if (ovfMap.containsKey(info.getId())) { |             if (ovfProperties.containsKey(info.getId())) { | ||||||
|                 Pair<String, Boolean> pair = ovfMap.get(info.getId()); |                 String value = ovfProperties.get(info.getId()); | ||||||
|                 String value = pair.first(); |                 info.setValue(value); | ||||||
|                 boolean isPassword = pair.second(); |  | ||||||
|                 info.setValue(isPassword ? DBEncryptionUtil.decrypt(value) : value); |  | ||||||
|             } |             } | ||||||
|             spec.setInfo(info); |             spec.setInfo(info); | ||||||
|             spec.setOperation(ArrayUpdateOperation.ADD); |             spec.setOperation(ArrayUpdateOperation.ADD); | ||||||
| @ -2662,8 +2635,8 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa | |||||||
|      * Set the vApp configuration to vmConfig spec, copying existing configuration from vAppConfig |      * Set the vApp configuration to vmConfig spec, copying existing configuration from vAppConfig | ||||||
|      * and seting properties values from ovfProperties |      * and seting properties values from ovfProperties | ||||||
|      */ |      */ | ||||||
|     protected void copyVAppConfigsFromTemplate(VmConfigInfo vAppConfig, |     protected void setVAppPropertiesToConfigSpec(VmConfigInfo vAppConfig, | ||||||
|                                                List<OVFPropertyTO> ovfProperties, |                                                  Map<String, String> ovfProperties, | ||||||
|                                                  VirtualMachineConfigSpec vmConfig) throws Exception { |                                                  VirtualMachineConfigSpec vmConfig) throws Exception { | ||||||
|         VmConfigSpec vmConfigSpec = new VmConfigSpec(); |         VmConfigSpec vmConfigSpec = new VmConfigSpec(); | ||||||
|         vmConfigSpec.getEula().addAll(vAppConfig.getEula()); |         vmConfigSpec.getEula().addAll(vAppConfig.getEula()); | ||||||
| @ -3009,10 +2982,7 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa | |||||||
|     private static void configCustomExtraOption(List<OptionValue> extraOptions, VirtualMachineTO vmSpec) { |     private static void configCustomExtraOption(List<OptionValue> extraOptions, VirtualMachineTO vmSpec) { | ||||||
|         // we no longer to validation anymore |         // we no longer to validation anymore | ||||||
|         for (Map.Entry<String, String> entry : vmSpec.getDetails().entrySet()) { |         for (Map.Entry<String, String> entry : vmSpec.getDetails().entrySet()) { | ||||||
|             if (entry.getKey().equalsIgnoreCase(VmDetailConstants.BOOT_MODE) || |             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)) { |  | ||||||
|                 continue; |                 continue; | ||||||
|             } |             } | ||||||
|             OptionValue newVal = new OptionValue(); |             OptionValue newVal = new OptionValue(); | ||||||
|  | |||||||
| @ -26,6 +26,9 @@ import java.util.Set; | |||||||
| 
 | 
 | ||||||
| import javax.inject.Inject; | 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.api.ApiConstants; | ||||||
| import org.apache.cloudstack.utils.security.DigestHelper; | import org.apache.cloudstack.utils.security.DigestHelper; | ||||||
| import org.apache.log4j.Logger; | import org.apache.log4j.Logger; | ||||||
| @ -83,6 +86,8 @@ public class TemplateJoinDaoImpl extends GenericDaoBaseWithTagInformation<Templa | |||||||
|     private ImageStoreDao dataStoreDao; |     private ImageStoreDao dataStoreDao; | ||||||
|     @Inject |     @Inject | ||||||
|     private VMTemplateDetailsDao _templateDetailsDao; |     private VMTemplateDetailsDao _templateDetailsDao; | ||||||
|  |     @Inject | ||||||
|  |     private TemplateDeployAsIsDetailsDao templateDeployAsIsDetailsDao; | ||||||
| 
 | 
 | ||||||
|     private final SearchBuilder<TemplateJoinVO> tmpltIdPairSearch; |     private final SearchBuilder<TemplateJoinVO> tmpltIdPairSearch; | ||||||
| 
 | 
 | ||||||
| @ -240,6 +245,8 @@ public class TemplateJoinDaoImpl extends GenericDaoBaseWithTagInformation<Templa | |||||||
|         if (detailsView.contains(ApiConstants.DomainDetails.all)) { |         if (detailsView.contains(ApiConstants.DomainDetails.all)) { | ||||||
|             Map<String, String> details = _templateDetailsDao.listDetailsKeyPairs(template.getId()); |             Map<String, String> details = _templateDetailsDao.listDetailsKeyPairs(template.getId()); | ||||||
|             templateResponse.setDetails(details); |             templateResponse.setDetails(details); | ||||||
|  | 
 | ||||||
|  |             setDeployAsIsDetails(template, templateResponse); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // update tag information |         // update tag information | ||||||
| @ -272,6 +279,19 @@ public class TemplateJoinDaoImpl extends GenericDaoBaseWithTagInformation<Templa | |||||||
|         return templateResponse; |         return templateResponse; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     private void setDeployAsIsDetails(TemplateJoinVO template, TemplateResponse templateResponse) { | ||||||
|  |         if (template.isDeployAsIs()) { | ||||||
|  |             List<TemplateDeployAsIsDetailVO> 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 |     //TODO: This is to keep compatibility with 4.1 API, where updateTemplateCmd and updateIsoCmd will return a simpler TemplateResponse | ||||||
|     // compared to listTemplates and listIsos. |     // compared to listTemplates and listIsos. | ||||||
|     @Override |     @Override | ||||||
|  | |||||||
| @ -47,12 +47,12 @@ import javax.xml.parsers.DocumentBuilder; | |||||||
| import javax.xml.parsers.DocumentBuilderFactory; | import javax.xml.parsers.DocumentBuilderFactory; | ||||||
| import javax.xml.parsers.ParserConfigurationException; | 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.exception.UnsupportedServiceException; | ||||||
| import com.cloud.hypervisor.Hypervisor; | import com.cloud.hypervisor.Hypervisor; | ||||||
| import com.cloud.storage.ImageStore; | import com.cloud.deployasis.dao.TemplateDeployAsIsDetailsDao; | ||||||
| import com.cloud.storage.VMTemplateDetailVO; |  | ||||||
| import com.cloud.storage.dao.VMTemplateDetailsDao; |  | ||||||
| import org.apache.cloudstack.acl.ControlledEntity.ACLType; | import org.apache.cloudstack.acl.ControlledEntity.ACLType; | ||||||
| import org.apache.cloudstack.acl.SecurityChecker.AccessType; | import org.apache.cloudstack.acl.SecurityChecker.AccessType; | ||||||
| import org.apache.cloudstack.affinity.AffinityGroupService; | 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.CreateVMGroupCmd; | ||||||
| import org.apache.cloudstack.api.command.user.vmgroup.DeleteVMGroupCmd; | import org.apache.cloudstack.api.command.user.vmgroup.DeleteVMGroupCmd; | ||||||
| import org.apache.cloudstack.api.command.user.volume.ResizeVolumeCmd; | 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.context.CallContext; | ||||||
| import org.apache.cloudstack.engine.cloud.entity.api.VirtualMachineEntity; | import org.apache.cloudstack.engine.cloud.entity.api.VirtualMachineEntity; | ||||||
| import org.apache.cloudstack.engine.cloud.entity.api.db.dao.VMNetworkMapDao; | import org.apache.cloudstack.engine.cloud.entity.api.db.dao.VMNetworkMapDao; | ||||||
| @ -507,7 +507,9 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir | |||||||
|     @Inject |     @Inject | ||||||
|     private ResourceTagDao resourceTagDao; |     private ResourceTagDao resourceTagDao; | ||||||
|     @Inject |     @Inject | ||||||
|     private VMTemplateDetailsDao templateDetailsDao; |     private TemplateDeployAsIsDetailsDao templateDeployAsIsDetailsDao; | ||||||
|  |     @Inject | ||||||
|  |     private UserVmDeployAsIsDetailsDao userVmDeployAsIsDetailsDao; | ||||||
| 
 | 
 | ||||||
|     private ScheduledExecutorService _executor = null; |     private ScheduledExecutorService _executor = null; | ||||||
|     private ScheduledExecutorService _vmIpFetchExecutor = 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); |                 vmInstance.setDetails(details); | ||||||
|                 _vmDao.saveDetails(vmInstance); |                 _vmDao.saveDetails(vmInstance); | ||||||
|             } |             } | ||||||
| @ -4007,11 +3998,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir | |||||||
|                 } |                 } | ||||||
|                 vm.setDetail(VmDetailConstants.DEPLOY_VM, "true"); |                 vm.setDetail(VmDetailConstants.DEPLOY_VM, "true"); | ||||||
| 
 | 
 | ||||||
|                 copyDiskDetailsToVm(vm, template); |                 persistVMDeployAsIsProperties(vm, userVmOVFPropertiesMap); | ||||||
| 
 |  | ||||||
|                 setPropertiesOnVM(vm, userVmOVFPropertiesMap); |  | ||||||
| 
 |  | ||||||
|                 copyNetworkRequirementsToVm(vm, template); |  | ||||||
| 
 | 
 | ||||||
|                 _vmDao.saveDetails(vm); |                 _vmDao.saveDetails(vm); | ||||||
|                 if (!isImport) { |                 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<VMTemplateDetailVO> 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<VMTemplateDetailVO> 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. |      * 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? |      * 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. |      * I.E. iterate over the template details as well to copy any that are not defined yet. | ||||||
|      */ |      */ | ||||||
|     private void setPropertiesOnVM(UserVmVO vm, Map<String, String> userVmOVFPropertiesMap) { |     private void persistVMDeployAsIsProperties(UserVmVO vm, Map<String, String> userVmOVFPropertiesMap) { | ||||||
|         if (MapUtils.isNotEmpty(userVmOVFPropertiesMap)) { |         if (MapUtils.isNotEmpty(userVmOVFPropertiesMap)) { | ||||||
|             for (String key : userVmOVFPropertiesMap.keySet()) { |             for (String key : userVmOVFPropertiesMap.keySet()) { | ||||||
|                 String detailKey = ImageStore.ACS_PROPERTY_PREFIX + key; |                 String detailKey = key; | ||||||
|                 String value = userVmOVFPropertiesMap.get(key); |                 String value = userVmOVFPropertiesMap.get(key); | ||||||
| 
 | 
 | ||||||
|                 // Sanitize boolean values to expected format and encrypt passwords |                 // 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")) { |                     } else if (value.equalsIgnoreCase("False")) { | ||||||
|                         value = "False"; |                         value = "False"; | ||||||
|                     } else { |                     } else { | ||||||
|                         OVFPropertyTO propertyTO = templateDetailsDao.findPropertyByTemplateAndKey(vm.getTemplateId(), key); |                         OVFPropertyTO propertyTO = templateDeployAsIsDetailsDao.findPropertyByTemplateAndKey(vm.getTemplateId(), key); | ||||||
|                         if (propertyTO != null && propertyTO.isPassword()) { |                         if (propertyTO != null && propertyTO.isPassword()) { | ||||||
|                             value = DBEncryptionUtil.encrypt(value); |                             value = DBEncryptionUtil.encrypt(value); | ||||||
|                         } |                         } | ||||||
| @ -4101,7 +4070,8 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir | |||||||
|                 if (s_logger.isTraceEnabled()) { |                 if (s_logger.isTraceEnabled()) { | ||||||
|                     s_logger.trace(String.format("setting property '%s' as '%s' with value '%s'", key, detailKey, value)); |                     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<Integer, Long> getVmOvfNetworkMapping(DataCenter zone, Account owner, VirtualMachineTemplate template, Map<Integer, Long> vmNetworkMapping) throws InsufficientCapacityException, ResourceAllocationException { |     private LinkedHashMap<Integer, Long> getVmOvfNetworkMapping(DataCenter zone, Account owner, VirtualMachineTemplate template, Map<Integer, Long> vmNetworkMapping) throws InsufficientCapacityException, ResourceAllocationException { | ||||||
|         LinkedHashMap<Integer, Long> mapping = new LinkedHashMap<>(); |         LinkedHashMap<Integer, Long> mapping = new LinkedHashMap<>(); | ||||||
|         if (ImageFormat.OVA.equals(template.getFormat())) { |         if (ImageFormat.OVA.equals(template.getFormat())) { | ||||||
|             List<NetworkPrerequisiteTO> networkPrerequisiteTOList = |             List<OVFNetworkTO> OVFNetworkTOList = | ||||||
|                     templateDetailsDao.listNetworkRequirementsByTemplateId(template.getId()); |                     templateDeployAsIsDetailsDao.listNetworkRequirementsByTemplateId(template.getId()); | ||||||
|             if (CollectionUtils.isNotEmpty(networkPrerequisiteTOList)) { |             if (CollectionUtils.isNotEmpty(OVFNetworkTOList)) { | ||||||
|                 Network lastMappedNetwork = null; |                 Network lastMappedNetwork = null; | ||||||
|                 for (NetworkPrerequisiteTO networkPrerequisiteTO : networkPrerequisiteTOList) { |                 for (OVFNetworkTO OVFNetworkTO : OVFNetworkTOList) { | ||||||
|                     Long networkId = vmNetworkMapping.get(networkPrerequisiteTO.getInstanceID()); |                     Long networkId = vmNetworkMapping.get(OVFNetworkTO.getInstanceID()); | ||||||
|                     if (networkId == null && lastMappedNetwork == null) { |                     if (networkId == null && lastMappedNetwork == null) { | ||||||
|                         lastMappedNetwork = getNetworkForOvfNetworkMapping(zone, owner); |                         lastMappedNetwork = getNetworkForOvfNetworkMapping(zone, owner); | ||||||
|                     } |                     } | ||||||
|                     if (networkId == null) { |                     if (networkId == null) { | ||||||
|                         networkId = lastMappedNetwork.getId(); |                         networkId = lastMappedNetwork.getId(); | ||||||
|                     } |                     } | ||||||
|                     mapping.put(networkPrerequisiteTO.getInstanceID(), networkId); |                     mapping.put(OVFNetworkTO.getInstanceID(), networkId); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  | |||||||
| @ -37,10 +37,10 @@ import java.util.concurrent.Executors; | |||||||
| 
 | 
 | ||||||
| import javax.naming.ConfigurationException; | import javax.naming.ConfigurationException; | ||||||
| 
 | 
 | ||||||
| import com.cloud.agent.api.storage.OVFEulaSectionTO; | import com.cloud.agent.api.to.deployasis.OVFEulaSectionTO; | ||||||
| import com.cloud.agent.api.storage.OVFVirtualHardwareSectionTO; | import com.cloud.agent.api.to.deployasis.OVFVirtualHardwareSectionTO; | ||||||
| import com.cloud.agent.api.to.DatadiskTO; | 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.Processor; | ||||||
| import com.cloud.storage.template.S3TemplateDownloader; | import com.cloud.storage.template.S3TemplateDownloader; | ||||||
| import com.cloud.storage.template.TemplateDownloader; | 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.TARProcessor; | ||||||
| import com.cloud.storage.template.VhdProcessor; | import com.cloud.storage.template.VhdProcessor; | ||||||
| import com.cloud.storage.template.TemplateConstants; | 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; | ||||||
| import org.apache.cloudstack.storage.command.DownloadCommand.ResourceType; | import org.apache.cloudstack.storage.command.DownloadCommand.ResourceType; | ||||||
| import org.apache.cloudstack.storage.command.DownloadProgressCommand; | import org.apache.cloudstack.storage.command.DownloadProgressCommand; | ||||||
| @ -132,7 +132,7 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager | |||||||
|         private final long id; |         private final long id; | ||||||
|         private final ResourceType resourceType; |         private final ResourceType resourceType; | ||||||
|         private List<OVFPropertyTO> ovfProperties; |         private List<OVFPropertyTO> ovfProperties; | ||||||
|         private List<NetworkPrerequisiteTO> networks; |         private List<OVFNetworkTO> networks; | ||||||
|         private List<DatadiskTO> disks; |         private List<DatadiskTO> disks; | ||||||
|         private OVFVirtualHardwareSectionTO hardwareSection; |         private OVFVirtualHardwareSectionTO hardwareSection; | ||||||
|         private List<OVFEulaSectionTO> eulaSections; |         private List<OVFEulaSectionTO> eulaSections; | ||||||
| @ -239,11 +239,11 @@ public class DownloadManagerImpl extends ManagerBase implements DownloadManager | |||||||
|             this.ovfProperties = ovfProperties; |             this.ovfProperties = ovfProperties; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         public List<NetworkPrerequisiteTO> getNetworks() { |         public List<OVFNetworkTO> getNetworks() { | ||||||
|             return networks; |             return networks; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         public void setNetworks(List<NetworkPrerequisiteTO> networks) { |         public void setNetworks(List<OVFNetworkTO> networks) { | ||||||
|             this.networks = networks; |             this.networks = networks; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user