// Copyright 2012 Citrix Systems, Inc. Licensed under the // Apache License, Version 2.0 (the "License"); you may not use this // file except in compliance with the License. Citrix Systems, Inc. // reserves all rights not expressly granted by 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. // // Automatically generated by addcopyright.py at 04/03/2012 package com.cloud.storage.resource; import java.util.List; import org.apache.log4j.Logger; import com.cloud.agent.api.Answer; import com.cloud.agent.api.BackupSnapshotCommand; import com.cloud.agent.api.Command; import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand; import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand; import com.cloud.agent.api.CreateVolumeFromSnapshotCommand; import com.cloud.agent.api.storage.CopyVolumeCommand; import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand; import com.cloud.hypervisor.vmware.manager.VmwareHostService; import com.cloud.hypervisor.vmware.manager.VmwareStorageManager; import com.cloud.hypervisor.vmware.manager.VmwareStorageManagerImpl; import com.cloud.hypervisor.vmware.manager.VmwareStorageMount; import com.cloud.hypervisor.vmware.mo.ClusterMO; import com.cloud.hypervisor.vmware.mo.HostMO; import com.cloud.hypervisor.vmware.mo.VmwareHostType; import com.cloud.hypervisor.vmware.mo.VmwareHypervisorHost; import com.cloud.hypervisor.vmware.mo.VmwareHypervisorHostNetworkSummary; import com.cloud.hypervisor.vmware.util.VmwareContext; import com.cloud.hypervisor.vmware.util.VmwareHelper; import com.cloud.serializer.GsonHelper; import com.cloud.utils.Pair; import com.google.gson.Gson; import com.vmware.vim25.ManagedObjectReference; public class VmwareSecondaryStorageResourceHandler implements SecondaryStorageResourceHandler, VmwareHostService, VmwareStorageMount { private static final Logger s_logger = Logger.getLogger(VmwareSecondaryStorageResourceHandler.class); private final PremiumSecondaryStorageResource _resource; private final VmwareStorageManager _storageMgr; private final Gson _gson; /* private Map<String, HostMO> _activeHosts = new HashMap<String, HostMO>(); */ public VmwareSecondaryStorageResourceHandler(PremiumSecondaryStorageResource resource) { _resource = resource; _storageMgr = new VmwareStorageManagerImpl(this); _gson = GsonHelper.getGsonLogger(); } @Override public Answer executeRequest(Command cmd) { Answer answer; if (cmd instanceof PrimaryStorageDownloadCommand) { answer = execute((PrimaryStorageDownloadCommand)cmd); } else if(cmd instanceof BackupSnapshotCommand) { answer = execute((BackupSnapshotCommand)cmd); } else if(cmd instanceof CreatePrivateTemplateFromVolumeCommand) { answer = execute((CreatePrivateTemplateFromVolumeCommand)cmd); } else if(cmd instanceof CreatePrivateTemplateFromSnapshotCommand) { answer = execute((CreatePrivateTemplateFromSnapshotCommand)cmd); } else if(cmd instanceof CopyVolumeCommand) { answer = execute((CopyVolumeCommand)cmd); } else if(cmd instanceof CreateVolumeFromSnapshotCommand) { answer = execute((CreateVolumeFromSnapshotCommand)cmd); } else { answer = _resource.defaultAction(cmd); } // special handling to pass-back context info for cleanups if(cmd.getContextParam("execid") != null) { answer.setContextParam("execid", cmd.getContextParam("execid")); } if(cmd.getContextParam("checkpoint") != null) { answer.setContextParam("checkpoint", cmd.getContextParam("checkpoint")); } if(cmd.getContextParam("checkpoint2") != null) { answer.setContextParam("checkpoint2", cmd.getContextParam("checkpoint2")); } return answer; } private Answer execute(PrimaryStorageDownloadCommand cmd) { if (s_logger.isDebugEnabled()) { s_logger.debug("Executing resource PrimaryStorageDownloadCommand: " + _gson.toJson(cmd)); } return _storageMgr.execute(this, cmd); } private Answer execute(BackupSnapshotCommand cmd) { if (s_logger.isDebugEnabled()) { s_logger.debug("Executing resource BackupSnapshotCommand: " + _gson.toJson(cmd)); } return _storageMgr.execute(this, cmd); } private Answer execute(CreatePrivateTemplateFromVolumeCommand cmd) { if (s_logger.isDebugEnabled()) { s_logger.debug("Executing resource CreatePrivateTemplateFromVolumeCommand: " + _gson.toJson(cmd)); } return _storageMgr.execute(this, cmd); } private Answer execute(CreatePrivateTemplateFromSnapshotCommand cmd) { if (s_logger.isDebugEnabled()) { s_logger.debug("Executing resource CreatePrivateTemplateFromVolumeCommand: " + _gson.toJson(cmd)); } return _storageMgr.execute(this, cmd); } private Answer execute(CopyVolumeCommand cmd) { if (s_logger.isDebugEnabled()) { s_logger.debug("Executing resource CopyVolumeCommand: " + _gson.toJson(cmd)); } return _storageMgr.execute(this, cmd); } private Answer execute(CreateVolumeFromSnapshotCommand cmd) { if (s_logger.isDebugEnabled()) { s_logger.debug("Executing resource CreateVolumeFromSnapshotCommand: " + _gson.toJson(cmd)); } return _storageMgr.execute(this, cmd); } @Override public VmwareContext getServiceContext(Command cmd) { String guid = cmd.getContextParam("guid"); if(guid == null || guid.isEmpty()) { s_logger.error("Invalid command context parameter guid"); return null; } String username = cmd.getContextParam("username"); if(username == null || username.isEmpty()) { s_logger.error("Invalid command context parameter username"); return null; } String password = cmd.getContextParam("password"); // validate command guid parameter String[] tokens = guid.split("@"); if(tokens == null || tokens.length != 2) { s_logger.error("Invalid content in command context parameter guid"); return null; } String vCenterAddress = tokens[1]; String[] hostTokens = tokens[0].split(":"); if(hostTokens == null || hostTokens.length != 2) { s_logger.error("Invalid content in command context parameter guid"); return null; } try { _resource.ensureOutgoingRuleForAddress(vCenterAddress); VmwareContext context = null; // cached VmwareContext may be timed out in vCenter, give it a chance to reclaim a new context from factory for(int i = 0; i < 2; i++) { context = VmwareSecondaryStorageContextFactory.create(vCenterAddress, username, password); if(!validateContext(context, cmd)) { invalidateServiceContext(context); } } if(context != null) { context.registerStockObject("serviceconsole", cmd.getContextParam("serviceconsole")); context.registerStockObject("manageportgroup", cmd.getContextParam("manageportgroup")); } return context; } catch(Exception e) { s_logger.error("Unexpected exception " + e.toString(), e); return null; } } @Override public void invalidateServiceContext(VmwareContext context) { VmwareSecondaryStorageContextFactory.invalidate(context); } @Override public VmwareHypervisorHost getHyperHost(VmwareContext context, Command cmd) { String guid = cmd.getContextParam("guid"); assert(guid != null); String[] tokens = guid.split("@"); assert(tokens != null && tokens.length == 2); ManagedObjectReference morHyperHost = new ManagedObjectReference(); String[] hostTokens = tokens[0].split(":"); if(hostTokens == null || hostTokens.length != 2) { s_logger.error("Invalid content in command context parameter guid"); return null; } morHyperHost.setType(hostTokens[0]); morHyperHost.set_value(hostTokens[1]); if(morHyperHost.getType().equalsIgnoreCase("HostSystem")) { HostMO hostMo = new HostMO(context, morHyperHost); try { ManagedObjectReference mor = hostMo.getHyperHostCluster(); ClusterMO clusterMo = new ClusterMO(hostMo.getContext(), mor); List<Pair<ManagedObjectReference, String>> hostsInCluster = clusterMo.getClusterHosts(); for(Pair<ManagedObjectReference, String> hostPair : hostsInCluster) { HostMO hostIteratorMo = new HostMO(hostMo.getContext(), hostPair.first()); VmwareHypervisorHostNetworkSummary netSummary = hostIteratorMo.getHyperHostNetworkSummary( hostIteratorMo.getHostType() == VmwareHostType.ESXi ? cmd.getContextParam("manageportgroup") : cmd.getContextParam("serviceconsole")); _resource.ensureOutgoingRuleForAddress(netSummary.getHostIp()); s_logger.info("Setup firewall rule for host: " + netSummary.getHostIp()); } } catch(Throwable e) { s_logger.warn("Unable to retrive host network information due to exception " + e.toString() + ", host: " + hostTokens[0] + "-" + hostTokens[1]); } return hostMo; } assert(false); return new ClusterMO(context, morHyperHost); } @Override public String getWorkerName(VmwareContext context, Command cmd, int workerSequence) { assert(cmd.getContextParam("worker") != null); assert(workerSequence < 2); if(workerSequence == 0) return cmd.getContextParam("worker"); return cmd.getContextParam("worker2"); } @Override public String getMountPoint(String storageUrl) { return _resource.getRootDir(storageUrl); } private boolean validateContext(VmwareContext context, Command cmd) { String guid = cmd.getContextParam("guid"); assert(guid != null); String[] tokens = guid.split("@"); assert(tokens != null && tokens.length == 2); ManagedObjectReference morHyperHost = new ManagedObjectReference(); String[] hostTokens = tokens[0].split(":"); assert(hostTokens.length == 2); morHyperHost.setType(hostTokens[0]); morHyperHost.set_value(hostTokens[1]); if(morHyperHost.getType().equalsIgnoreCase("HostSystem")) { HostMO hostMo = new HostMO(context, morHyperHost); try { VmwareHypervisorHostNetworkSummary netSummary = hostMo.getHyperHostNetworkSummary( hostMo.getHostType() == VmwareHostType.ESXi ? cmd.getContextParam("manageportgroup") : cmd.getContextParam("serviceconsole")); assert(netSummary != null); if(netSummary.getHostIp() != null && !netSummary.getHostIp().isEmpty()) { if(s_logger.isDebugEnabled()) { s_logger.debug("Context validation succeeded. Validated via host: " + netSummary.getHostIp() + ", guid: " + guid); } return true; } s_logger.warn("Context validation failed due to invalid host network summary"); return false; } catch(Throwable e) { s_logger.warn("Context validation failed due to " + VmwareHelper.getExceptionMessage(e)); return false; } } assert(false); return true; } }