// 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.agent.manager; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import javax.ejb.Local; import javax.naming.ConfigurationException; import org.apache.log4j.Logger; import com.cloud.agent.api.Answer; import com.cloud.agent.api.CheckVirtualMachineAnswer; import com.cloud.agent.api.CheckVirtualMachineCommand; import com.cloud.agent.api.CleanupNetworkRulesCmd; import com.cloud.agent.api.GetDomRVersionAnswer; import com.cloud.agent.api.GetDomRVersionCmd; import com.cloud.agent.api.GetVmStatsAnswer; import com.cloud.agent.api.GetVmStatsCommand; import com.cloud.agent.api.GetVncPortAnswer; import com.cloud.agent.api.GetVncPortCommand; import com.cloud.agent.api.MigrateAnswer; import com.cloud.agent.api.MigrateCommand; import com.cloud.agent.api.NetworkUsageAnswer; import com.cloud.agent.api.NetworkUsageCommand; import com.cloud.agent.api.RebootCommand; import com.cloud.agent.api.SecurityGroupRuleAnswer; import com.cloud.agent.api.SecurityGroupRulesCmd; import com.cloud.agent.api.StartAnswer; import com.cloud.agent.api.StartCommand; import com.cloud.agent.api.StopAnswer; import com.cloud.agent.api.StopCommand; import com.cloud.agent.api.VmStatsEntry; import com.cloud.agent.api.check.CheckSshAnswer; import com.cloud.agent.api.check.CheckSshCommand; import com.cloud.agent.api.proxy.CheckConsoleProxyLoadCommand; import com.cloud.agent.api.proxy.WatchConsoleProxyLoadCommand; import com.cloud.agent.api.routing.DhcpEntryCommand; import com.cloud.agent.api.routing.IpAssocCommand; import com.cloud.agent.api.routing.LoadBalancerConfigCommand; import com.cloud.agent.api.routing.SavePasswordCommand; import com.cloud.agent.api.routing.SetPortForwardingRulesCommand; import com.cloud.agent.api.routing.SetStaticNatRulesCommand; import com.cloud.agent.api.routing.VmDataCommand; import com.cloud.agent.api.to.NicTO; import com.cloud.agent.api.to.VirtualMachineTO; import com.cloud.network.Networks.TrafficType; import com.cloud.simulator.MockHost; import com.cloud.simulator.MockSecurityRulesVO; import com.cloud.simulator.MockVMVO; import com.cloud.simulator.MockVm; import com.cloud.simulator.dao.MockHostDao; import com.cloud.simulator.dao.MockSecurityRulesDao; import com.cloud.simulator.dao.MockVMDao; import com.cloud.utils.Pair; import com.cloud.utils.Ternary; import com.cloud.utils.component.Inject; import com.cloud.vm.VirtualMachine.State; @Local(value = { MockVmManager.class }) public class MockVmManagerImpl implements MockVmManager { private static final Logger s_logger = Logger.getLogger(MockVmManagerImpl.class); @Inject MockVMDao _mockVmDao = null; @Inject MockAgentManager _mockAgentMgr = null; @Inject MockHostDao _mockHostDao = null; @Inject MockSecurityRulesDao _mockSecurityDao = null; private Map<String, Map<String, Ternary<String,Long,Long>>> _securityRules = new ConcurrentHashMap<String, Map<String, Ternary<String, Long, Long>>>(); public MockVmManagerImpl() { } @Override public boolean configure(String name, Map<String, Object> params) throws ConfigurationException { return true; } public String startVM(String vmName, NicTO[] nics, int cpuHz, long ramSize, String bootArgs, String hostGuid) { MockHost host = _mockHostDao.findByGuid(hostGuid); if (host == null) { return "can't find host"; } MockVm vm = _mockVmDao.findByVmName(vmName); if(vm == null) { int vncPort = 0; if(vncPort < 0) return "Unable to allocate VNC port"; vm = new MockVMVO(); vm.setCpu(cpuHz); vm.setMemory(ramSize); vm.setState(State.Running); vm.setName(vmName); vm.setVncPort(vncPort); vm.setHostId(host.getId()); if(vmName.startsWith("s-")) { vm.setType("SecondaryStorageVm"); } else if (vmName.startsWith("v-")) { vm.setType("ConsoleProxy"); } else if (vmName.startsWith("r-")) { vm.setType("DomainRouter"); } else if (vmName.startsWith("i-")) { vm.setType("User"); } vm = _mockVmDao.persist((MockVMVO)vm); } else { if(vm.getState() == State.Stopped) { vm.setState(State.Running); _mockVmDao.update(vm.getId(), (MockVMVO)vm); } } if (vm.getState() == State.Running && vmName.startsWith("s-")) { String prvIp = null; String prvMac = null; String prvNetMask = null; for (NicTO nic : nics) { if (nic.getType() == TrafficType.Management) { prvIp = nic.getIp(); prvMac = nic.getMac(); prvNetMask = nic.getNetmask(); } } long dcId = 0; long podId = 0; String name = null; String vmType = null; String url = null; String[] args = bootArgs.trim().split(" "); for (String arg : args) { String[] params = arg.split("="); if (params.length < 1) { continue; } if (params[0].equalsIgnoreCase("zone")) { dcId = Long.parseLong(params[1]); } else if (params[0].equalsIgnoreCase("name")) { name = params[1]; } else if (params[0].equalsIgnoreCase("type")) { vmType = params[1]; } else if (params[0].equalsIgnoreCase("url")) { url = params[1]; } else if (params[0].equalsIgnoreCase("pod")) { podId = Long.parseLong(params[1]); } } _mockAgentMgr.handleSystemVMStart(vm.getId(), prvIp, prvMac, prvNetMask, dcId, podId, name, vmType, url); } return null; } public boolean rebootVM(String vmName) { MockVm vm = _mockVmDao.findByVmName(vmName); if(vm != null) { vm.setState(State.Running); _mockVmDao.update(vm.getId(), (MockVMVO)vm); } return true; } @Override public Map<String, MockVMVO> getVms(String hostGuid) { List<MockVMVO> vms = _mockVmDao.findByHostGuid(hostGuid); Map<String, MockVMVO> vmMap = new HashMap<String, MockVMVO>(); for (MockVMVO vm : vms) { vmMap.put(vm.getName(), vm); } return vmMap; } @Override public Map<String, State> getVmStates(String hostGuid) { Map<String, State> states = new HashMap<String, State>(); List<MockVMVO> vms = _mockVmDao.findByHostGuid(hostGuid); if (vms.isEmpty()) { return states; } for(MockVm vm : vms) { states.put(vm.getName(), vm.getState()); } return states; } @Override public boolean start() { return true; } @Override public boolean stop() { return true; } @Override public String getName() { return this.getClass().getSimpleName(); } @Override public Answer getVmStats(GetVmStatsCommand cmd) { HashMap<String, VmStatsEntry> vmStatsNameMap = new HashMap<String, VmStatsEntry>(); List<String> vmNames = cmd.getVmNames(); for (String vmName : vmNames) { VmStatsEntry entry = new VmStatsEntry(0, 0, 0, 0, "vm"); entry.setNetworkReadKBs(32768); // default values 256 KBps entry.setNetworkWriteKBs(16384); entry.setCPUUtilization(10); entry.setNumCPUs(1); vmStatsNameMap.put(vmName, entry); } return new GetVmStatsAnswer(cmd, vmStatsNameMap); } @Override public CheckVirtualMachineAnswer checkVmState(CheckVirtualMachineCommand cmd, String hostGuid) { MockVMVO vm = _mockVmDao.findByVmNameAndHost(cmd.getVmName(), hostGuid); if (vm == null) { return new CheckVirtualMachineAnswer(cmd, "can't find vm:" + cmd.getVmName()); } return new CheckVirtualMachineAnswer(cmd, vm.getState(), vm.getVncPort()); } @Override public Answer startVM(StartCommand cmd, SimulatorInfo info) { VirtualMachineTO vm = cmd.getVirtualMachine(); String result = startVM(vm.getName(), vm.getNics(), vm.getCpus()* vm.getSpeed(), vm.getMaxRam(), vm.getBootArgs(), info.getHostUuid()); if (result != null) { return new StartAnswer(cmd, result); } else { return new StartAnswer(cmd); } } @Override public CheckSshAnswer checkSshCommand(CheckSshCommand cmd) { return new CheckSshAnswer(cmd); } @Override public Answer SetStaticNatRules(SetStaticNatRulesCommand cmd) { return new Answer(cmd); } @Override public Answer SetPortForwardingRules(SetPortForwardingRulesCommand cmd) { return new Answer(cmd); } @Override public NetworkUsageAnswer getNetworkUsage(NetworkUsageCommand cmd) { return new NetworkUsageAnswer(cmd, null, 100L, 100L); } @Override public MigrateAnswer Migrate(MigrateCommand cmd, SimulatorInfo info) { String vmName = cmd.getVmName(); String destGuid = cmd.getHostGuid(); MockVMVO vm = _mockVmDao.findByVmNameAndHost(vmName, info.getHostUuid()); if (vm == null) { return new MigrateAnswer(cmd, false, "can;t find vm:" + vmName + " on host:" + info.getHostUuid(), null); } MockHost destHost = _mockHostDao.findByGuid(destGuid); if (destHost == null) { return new MigrateAnswer(cmd, false, "can;t find host:" + info.getHostUuid(), null); } vm.setHostId(destHost.getId()); _mockVmDao.update(vm.getId(), vm); return new MigrateAnswer(cmd, true,null, 0); } @Override public Answer IpAssoc(IpAssocCommand cmd) { return new Answer(cmd); } @Override public Answer LoadBalancerConfig(LoadBalancerConfigCommand cmd) { return new Answer(cmd); } @Override public Answer AddDhcpEntry(DhcpEntryCommand cmd) { return new Answer(cmd); } @Override public Answer setVmData(VmDataCommand cmd) { return new Answer(cmd); } @Override public Answer CleanupNetworkRules(CleanupNetworkRulesCmd cmd, SimulatorInfo info) { List<MockSecurityRulesVO> rules = _mockSecurityDao.findByHost(info.getHostUuid()); for (MockSecurityRulesVO rule : rules) { MockVMVO vm = _mockVmDao.findByVmNameAndHost(rule.getVmName(), info.getHostUuid()); if (vm == null) { _mockSecurityDao.remove(rule.getId()); } } return new Answer(cmd); } @Override public Answer stopVM(StopCommand cmd) { String vmName = cmd.getVmName(); MockVm vm = _mockVmDao.findByVmName(vmName); if(vm != null) { vm.setState(State.Stopped); _mockVmDao.update(vm.getId(), (MockVMVO)vm); } if (vmName.startsWith("s-")) { _mockAgentMgr.handleSystemVMStop(vm.getId()); } return new StopAnswer(cmd, null, new Integer(0), new Long(100), new Long(200)); } @Override public Answer rebootVM(RebootCommand cmd) { return new Answer(cmd); } @Override public Answer getVncPort(GetVncPortCommand cmd) { return new GetVncPortAnswer(cmd, 0); } @Override public Answer CheckConsoleProxyLoad(CheckConsoleProxyLoadCommand cmd) { return Answer.createUnsupportedCommandAnswer(cmd); } @Override public Answer WatchConsoleProxyLoad(WatchConsoleProxyLoadCommand cmd) { return Answer.createUnsupportedCommandAnswer(cmd); } @Override public GetDomRVersionAnswer getDomRVersion(GetDomRVersionCmd cmd) { return new GetDomRVersionAnswer(cmd, null, null, null); } @Override public SecurityGroupRuleAnswer AddSecurityGroupRules(SecurityGroupRulesCmd cmd, SimulatorInfo info) { if (!info.isEnabled()) { return new SecurityGroupRuleAnswer(cmd, false, "Disabled", SecurityGroupRuleAnswer.FailureReason.CANNOT_BRIDGE_FIREWALL); } Map<String, Ternary<String,Long, Long>> rules = _securityRules.get(info.getHostUuid()); if (rules == null) { logSecurityGroupAction(cmd, null); rules = new ConcurrentHashMap<String, Ternary<String, Long, Long>>(); rules.put(cmd.getVmName(), new Ternary<String,Long, Long>(cmd.getSignature(), cmd.getVmId(), cmd.getSeqNum())); _securityRules.put(info.getHostUuid(), rules); } else { logSecurityGroupAction(cmd, rules.get(cmd.getVmName())); rules.put(cmd.getVmName(), new Ternary<String, Long,Long>(cmd.getSignature(), cmd.getVmId(), cmd.getSeqNum())); } return new SecurityGroupRuleAnswer(cmd); } private boolean logSecurityGroupAction(SecurityGroupRulesCmd cmd, Ternary<String,Long, Long> rule) { String action = ", do nothing"; String reason = ", reason="; Long currSeqnum = rule == null? null: rule.third(); String currSig = rule == null? null: rule.first(); boolean updateSeqnoAndSig = false; if (currSeqnum != null) { if (cmd.getSeqNum() > currSeqnum) { s_logger.info("New seqno received: " + cmd.getSeqNum() + " curr=" + currSeqnum); updateSeqnoAndSig = true; if (!cmd.getSignature().equals(currSig)) { s_logger.info("New seqno received: " + cmd.getSeqNum() + " curr=" + currSeqnum + " new signature received:" + cmd.getSignature() + " curr=" + currSig + ", updated iptables"); action = ", updated iptables"; reason = reason + "seqno_increased_sig_changed"; } else { s_logger.info("New seqno received: " + cmd.getSeqNum() + " curr=" + currSeqnum + " no change in signature:" + cmd.getSignature() + ", do nothing"); reason = reason + "seqno_increased_sig_same"; } } else if (cmd.getSeqNum() < currSeqnum) { s_logger.info("Older seqno received: " + cmd.getSeqNum() + " curr=" + currSeqnum + ", do nothing"); reason = reason + "seqno_decreased"; } else { if (!cmd.getSignature().equals(currSig)) { s_logger.info("Identical seqno received: " + cmd.getSeqNum() + " new signature received:" + cmd.getSignature() + " curr=" + currSig + ", updated iptables"); action = ", updated iptables"; reason = reason + "seqno_same_sig_changed"; updateSeqnoAndSig = true; } else { s_logger.info("Identical seqno received: " + cmd.getSeqNum() + " curr=" + currSeqnum + " no change in signature:" + cmd.getSignature() + ", do nothing"); reason = reason + "seqno_same_sig_same"; } } } else { s_logger.info("New seqno received: " + cmd.getSeqNum() + " old=null"); updateSeqnoAndSig = true; action = ", updated iptables"; reason = ", seqno_new"; } s_logger.info("Programmed network rules for vm " + cmd.getVmName() + " seqno=" + cmd.getSeqNum() + " signature=" + cmd.getSignature() + " guestIp=" + cmd.getGuestIp() + ", numIngressRules=" + cmd.getIngressRuleSet().length + ", numEgressRules=" + cmd.getEgressRuleSet().length + " total cidrs=" + cmd.getTotalNumCidrs() + action + reason); return updateSeqnoAndSig; } @Override public Answer SavePassword(SavePasswordCommand cmd) { return new Answer(cmd); } @Override public HashMap<String, Pair<Long, Long>> syncNetworkGroups(SimulatorInfo info) { HashMap<String, Pair<Long, Long>> maps = new HashMap<String, Pair<Long, Long>>(); Map<String, Ternary<String, Long, Long>> rules = _securityRules.get(info.getHostUuid()); if (rules == null) { return maps; } for (Map.Entry<String,Ternary<String, Long, Long>> rule : rules.entrySet()) { maps.put(rule.getKey(), new Pair<Long, Long>(rule.getValue().second(), rule.getValue().third())); } return maps; } }