diff --git a/server/src/com/cloud/baremetal/BareMetalVmManagerImpl.java b/server/src/com/cloud/baremetal/BareMetalVmManagerImpl.java index 2677e5ce384..59533e2c64e 100755 --- a/server/src/com/cloud/baremetal/BareMetalVmManagerImpl.java +++ b/server/src/com/cloud/baremetal/BareMetalVmManagerImpl.java @@ -73,6 +73,7 @@ import com.cloud.user.SSHKeyPair; import com.cloud.user.User; import com.cloud.user.UserContext; import com.cloud.uservm.UserVm; +import com.cloud.utils.IdentityProxy; import com.cloud.utils.NumbersUtil; import com.cloud.utils.Pair; import com.cloud.utils.component.Adapters; @@ -100,61 +101,61 @@ import com.cloud.vm.VirtualMachineProfile.Param; @Local(value={BareMetalVmManager.class, BareMetalVmService.class}) public class BareMetalVmManagerImpl extends UserVmManagerImpl implements BareMetalVmManager, BareMetalVmService, Manager, - StateListener { - private static final Logger s_logger = Logger.getLogger(BareMetalVmManagerImpl.class); - private ConfigurationDao _configDao; - @Inject PxeServerManager _pxeMgr; - @Inject ResourceManager _resourceMgr; - +StateListener { + private static final Logger s_logger = Logger.getLogger(BareMetalVmManagerImpl.class); + private ConfigurationDao _configDao; + @Inject PxeServerManager _pxeMgr; + @Inject ResourceManager _resourceMgr; + @Inject (adapter=TemplateAdapter.class) protected Adapters _adapters; - @Override - public boolean attachISOToVM(long vmId, long isoId, boolean attach) { - s_logger.warn("attachISOToVM is not supported by Bare Metal, just fake a true"); - return true; - } - - @Override - public Volume attachVolumeToVM(AttachVolumeCmd command) { - s_logger.warn("attachVolumeToVM is not supported by Bare Metal, return null"); - return null; - } - - @Override - public Volume detachVolumeFromVM(DetachVolumeCmd cmd) { - s_logger.warn("detachVolumeFromVM is not supported by Bare Metal, return null"); - return null; - } - - @Override - public UserVm upgradeVirtualMachine(UpgradeVMCmd cmd) { - s_logger.warn("upgradeVirtualMachine is not supported by Bare Metal, return null"); - return null; - } - - @Override + @Override + public boolean attachISOToVM(long vmId, long isoId, boolean attach) { + s_logger.warn("attachISOToVM is not supported by Bare Metal, just fake a true"); + return true; + } + + @Override + public Volume attachVolumeToVM(AttachVolumeCmd command) { + s_logger.warn("attachVolumeToVM is not supported by Bare Metal, return null"); + return null; + } + + @Override + public Volume detachVolumeFromVM(DetachVolumeCmd cmd) { + s_logger.warn("detachVolumeFromVM is not supported by Bare Metal, return null"); + return null; + } + + @Override + public UserVm upgradeVirtualMachine(UpgradeVMCmd cmd) { + s_logger.warn("upgradeVirtualMachine is not supported by Bare Metal, return null"); + return null; + } + + @Override public VMTemplateVO createPrivateTemplateRecord(CreateTemplateCmd cmd, Account templateOwner) throws ResourceAllocationException { - /*Baremetal creates record after host rebooting for imaging, in createPrivateTemplate*/ - return null; - } - - @Override @DB + /*Baremetal creates record after host rebooting for imaging, in createPrivateTemplate*/ + return null; + } + + @Override @DB public VMTemplateVO createPrivateTemplate(CreateTemplateCmd cmd) throws CloudRuntimeException { - Long vmId = cmd.getVmId(); - if (vmId == null) { - throw new InvalidParameterValueException("VM ID is null"); - } - - UserVmVO vm = _vmDao.findById(vmId); - if (vm == null) { - throw new InvalidParameterValueException("Cannot find VM for ID " + vmId); - } - - Long hostId = (vm.getHostId() == null ? vm.getLastHostId() : vm.getHostId()); + Long vmId = cmd.getVmId(); + if (vmId == null) { + throw new InvalidParameterValueException("VM ID is null", null); + } + + UserVmVO vm = _vmDao.findById(vmId); + if (vm == null) { + throw new InvalidParameterValueException("Cannot find VM by ID", null); + } + + Long hostId = (vm.getHostId() == null ? vm.getLastHostId() : vm.getHostId()); HostVO host = _hostDao.findById(hostId); if (host == null) { - throw new InvalidParameterValueException("Cannot find host with id " + hostId); + throw new InvalidParameterValueException("Cannot find host by id", null); } List pxes = _resourceMgr.listAllUpAndEnabledHosts(Host.Type.PxeServer, null, host.getPodId(), host.getDataCenterId()); @@ -163,7 +164,7 @@ public class BareMetalVmManagerImpl extends UserVmManagerImpl implements BareMet } if (pxes.size() > 1) { - CloudRuntimeException ex = new CloudRuntimeException("Multiple PXE servers found in Pod " + host.getPodId() + " in Zone with specified id"); + CloudRuntimeException ex = new CloudRuntimeException("Multiple PXE servers found in Pod " + host.getPodId() + " in Zone with specified id"); ex.addProxyObject("data_center", host.getDataCenterId(), "zoneId"); throw ex; } @@ -177,12 +178,12 @@ public class BareMetalVmManagerImpl extends UserVmManagerImpl implements BareMet Long userId = UserContext.current().getCallerUserId(); userId = (userId == null ? User.UID_SYSTEM : userId); AccountVO account = _accountDao.findById(vm.getAccountId()); - + try { TemplateProfile tmplProfile; tmplProfile = adapter.prepare(false, userId, cmd.getTemplateName(), cmd.getDisplayText(), cmd.getBits(), false, false, cmd.getUrl(), cmd.isPublic(), cmd.isFeatured(), false, "BareMetal", cmd.getOsTypeId(), pxe.getDataCenterId(), HypervisorType.BareMetal, account.getAccountName(), account.getDomainId(), "0", true, cmd.getDetails()); - + if (!_pxeMgr.prepareCreateTemplate(_pxeMgr.getPxeServerType(pxe), pxe.getId(), vm, cmd.getUrl())) { throw new Exception("Prepare PXE boot file for host " + hostId + " failed"); } @@ -206,117 +207,123 @@ public class BareMetalVmManagerImpl extends UserVmManagerImpl implements BareMet s_logger.debug("Create baremetal tempalte for host " + hostId + " failed", e); throw new CloudRuntimeException(e.getMessage()); } - } + } - @Override - public UserVm createVirtualMachine(DeployVMCmd cmd) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException, - StorageUnavailableException, ResourceAllocationException { - Account caller = UserContext.current().getCaller(); + @Override + public UserVm createVirtualMachine(DeployVMCmd cmd) throws InsufficientCapacityException, ResourceUnavailableException, ConcurrentOperationException, + StorageUnavailableException, ResourceAllocationException { + Account caller = UserContext.current().getCaller(); - String accountName = cmd.getAccountName(); - Long domainId = cmd.getDomainId(); - List networkList = cmd.getNetworkIds(); - String group = cmd.getGroup(); + String accountName = cmd.getAccountName(); + Long domainId = cmd.getDomainId(); + List networkList = cmd.getNetworkIds(); + String group = cmd.getGroup(); - Account owner = _accountDao.findActiveAccount(accountName, domainId); - if (owner == null) { - throw new InvalidParameterValueException("Unable to find account " + accountName + " in domain " + domainId); - } - - _accountMgr.checkAccess(caller, null, true, owner); - long accountId = owner.getId(); - - DataCenterVO dc = _dcDao.findById(cmd.getZoneId()); - if (dc == null) { - throw new InvalidParameterValueException("Unable to find zone: " + cmd.getZoneId()); - } - - if(Grouping.AllocationState.Disabled == dc.getAllocationState() && !_accountMgr.isRootAdmin(caller.getType())){ - throw new PermissionDeniedException("Cannot perform this operation, Zone is currently disabled: "+ cmd.getZoneId() ); - } - - if (dc.getDomainId() != null) { - DomainVO domain = _domainDao.findById(dc.getDomainId()); - if (domain == null) { - throw new CloudRuntimeException("Unable to find the domain " + dc.getDomainId() + " for the zone: " + dc); - } - _configMgr.checkZoneAccess(caller, dc); - _configMgr.checkZoneAccess(owner, dc); - } - - // check if account/domain is with in resource limits to create a new vm - _resourceLimitMgr.checkResourceLimit(owner, ResourceType.user_vm); - - ServiceOfferingVO offering = _serviceOfferingDao.findById(cmd.getServiceOfferingId()); - if (offering == null || offering.getRemoved() != null) { - throw new InvalidParameterValueException("Unable to find service offering: " + cmd.getServiceOfferingId()); + Account owner = _accountDao.findActiveAccount(accountName, domainId); + if (owner == null) { + List idList = new ArrayList(); + idList.add(new IdentityProxy("domain", domainId, "domainId")); + throw new InvalidParameterValueException("Unable to find account " + accountName + " in domain with specified id", idList); } - - VMTemplateVO template = _templateDao.findById(cmd.getTemplateId()); + + _accountMgr.checkAccess(caller, null, true, owner); + long accountId = owner.getId(); + + DataCenterVO dc = _dcDao.findById(cmd.getZoneId()); + if (dc == null) { + throw new InvalidParameterValueException("Unable to find zone by id", null); + } + + if(Grouping.AllocationState.Disabled == dc.getAllocationState() && !_accountMgr.isRootAdmin(caller.getType())){ + throw new PermissionDeniedException("Cannot perform this operation, Zone is currently disabled: "+ cmd.getZoneId() ); + } + + if (dc.getDomainId() != null) { + DomainVO domain = _domainDao.findById(dc.getDomainId()); + if (domain == null) { + throw new CloudRuntimeException("Unable to find the domain " + dc.getDomainId() + " for the zone: " + dc); + } + _configMgr.checkZoneAccess(caller, dc); + _configMgr.checkZoneAccess(owner, dc); + } + + // check if account/domain is with in resource limits to create a new vm + _resourceLimitMgr.checkResourceLimit(owner, ResourceType.user_vm); + + ServiceOfferingVO offering = _serviceOfferingDao.findById(cmd.getServiceOfferingId()); + if (offering == null || offering.getRemoved() != null) { + throw new InvalidParameterValueException("Unable to find service offering by id", null); + } + + VMTemplateVO template = _templateDao.findById(cmd.getTemplateId()); // Make sure a valid template ID was specified if (template == null || template.getRemoved() != null) { - throw new InvalidParameterValueException("Unable to use template " + cmd.getTemplateId()); + throw new InvalidParameterValueException("Unable to use template since it couldn't be found by id or has been marked as removed", null); } - + if (template.getTemplateType().equals(TemplateType.SYSTEM)) { - throw new InvalidParameterValueException("Unable to use system template " + cmd.getTemplateId()+" to deploy a user vm"); + List idList = new ArrayList(); + idList.add(new IdentityProxy(template, cmd.getTemplateId(), "templateId")); + throw new InvalidParameterValueException("Unable to use system template with specified id to deploy a user vm", idList); } if (template.getFormat() != Storage.ImageFormat.BAREMETAL) { - throw new InvalidParameterValueException("Unable to use non Bare Metal template" + cmd.getTemplateId() +" to deploy a bare metal vm"); + List idList = new ArrayList(); + idList.add(new IdentityProxy(template, cmd.getTemplateId(), "templateId")); + throw new InvalidParameterValueException("Unable to use non Bare Metal template with specified id to deploy a bare metal vm", idList); } - + String userData = cmd.getUserData(); byte [] decodedUserData = null; if (userData != null) { if (userData.length() >= 2 * MAX_USER_DATA_LENGTH_BYTES) { - throw new InvalidParameterValueException("User data is too long"); + throw new InvalidParameterValueException("User data is too long", null); } decodedUserData = org.apache.commons.codec.binary.Base64.decodeBase64(userData.getBytes()); if (decodedUserData.length > MAX_USER_DATA_LENGTH_BYTES){ - throw new InvalidParameterValueException("User data is too long"); + throw new InvalidParameterValueException("User data is too long", null); } if (decodedUserData.length < 1) { - throw new InvalidParameterValueException("User data is too short"); + throw new InvalidParameterValueException("User data is too short", null); } } - + // Find an SSH public key corresponding to the key pair name, if one is given String sshPublicKey = null; if (cmd.getSSHKeyPairName() != null && !cmd.getSSHKeyPairName().equals("")) { Account account = UserContext.current().getCaller(); - SSHKeyPair pair = _sshKeyPairDao.findByName(account.getAccountId(), account.getDomainId(), cmd.getSSHKeyPairName()); - if (pair == null) { - throw new InvalidParameterValueException("A key pair with name '" + cmd.getSSHKeyPairName() + "' was not found."); + SSHKeyPair pair = _sshKeyPairDao.findByName(account.getAccountId(), account.getDomainId(), cmd.getSSHKeyPairName()); + if (pair == null) { + throw new InvalidParameterValueException("A key pair with name '" + cmd.getSSHKeyPairName() + "' was not found.", null); } - sshPublicKey = pair.getPublicKey(); - } + sshPublicKey = pair.getPublicKey(); + } - _accountMgr.checkAccess(caller, null, true, template); + _accountMgr.checkAccess(caller, null, true, template); - DataCenterDeployment plan = new DataCenterDeployment(dc.getId()); + DataCenterDeployment plan = new DataCenterDeployment(dc.getId()); - s_logger.debug("Allocating in the DB for bare metal vm"); - - if (dc.getNetworkType() != NetworkType.Basic || networkList != null) { - s_logger.warn("Bare Metal only supports basical network mode now, switch to baisc network automatically"); - } - - Network defaultNetwork = _networkMgr.getExclusiveGuestNetwork(dc.getId()); - if (defaultNetwork == null) { - throw new InvalidParameterValueException("Unable to find a default network to start a vm"); - } - - - networkList = new ArrayList(); - networkList.add(defaultNetwork.getId()); - - List> networks = new ArrayList>(); + s_logger.debug("Allocating in the DB for bare metal vm"); + + if (dc.getNetworkType() != NetworkType.Basic || networkList != null) { + s_logger.warn("Bare Metal only supports basical network mode now, switch to baisc network automatically"); + } + + Network defaultNetwork = _networkMgr.getExclusiveGuestNetwork(dc.getId()); + if (defaultNetwork == null) { + throw new InvalidParameterValueException("Unable to find a default network to start a vm", null); + } + + + networkList = new ArrayList(); + networkList.add(defaultNetwork.getId()); + + List> networks = new ArrayList>(); for (Long networkId : networkList) { NetworkVO network = _networkDao.findById(networkId); if (network == null) { - throw new InvalidParameterValueException("Unable to find network by id " + networkId); + throw new InvalidParameterValueException("Unable to find network by id ", null); } else { if (network.getGuestType() != Network.GuestType.Shared) { //Check account permissions @@ -328,9 +335,9 @@ public class BareMetalVmManagerImpl extends UserVmManagerImpl implements BareMet networks.add(new Pair(network, null)); } } - + long id = _vmDao.getNextInSequence(Long.class, "id"); - + String hostName = cmd.getName(); String instanceName = VirtualMachineName.getVmName(id, owner.getId(), _instance); if (hostName == null) { @@ -339,79 +346,81 @@ public class BareMetalVmManagerImpl extends UserVmManagerImpl implements BareMet //verify hostName (hostname doesn't have to be unique) if (!NetUtils.verifyDomainNameLabel(hostName, true)) { throw new InvalidParameterValueException("Invalid name. Vm name can contain ASCII letters 'a' through 'z', the digits '0' through '9', " + - "and the hyphen ('-'), must be between 1 and 63 characters long, and can't start or end with \"-\" and can't start with digit"); + "and the hyphen ('-'), must be between 1 and 63 characters long, and can't start or end with \"-\" and can't start with digit", null); } } - + UserVmVO vm = new UserVmVO(id, instanceName, cmd.getDisplayName(), template.getId(), HypervisorType.BareMetal, template.getGuestOSId(), offering.getOfferHA(), false, domainId, owner.getId(), offering.getId(), userData, hostName); - + if (sshPublicKey != null) { vm.setDetail("SSH.PublicKey", sshPublicKey); } - if (_itMgr.allocate(vm, template, offering, null, null, networks, null, plan, cmd.getHypervisor(), owner) == null) { - return null; - } - + if (_itMgr.allocate(vm, template, offering, null, null, networks, null, plan, cmd.getHypervisor(), owner) == null) { + return null; + } - if (s_logger.isDebugEnabled()) { - s_logger.debug("Successfully allocated DB entry for " + vm); - } - if (s_logger.isDebugEnabled()) { - s_logger.debug("Successfully allocated DB entry for " + vm); - } - UserContext.current().setEventDetails("Vm Id: " + vm.getId()); - UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VM_CREATE, accountId, cmd.getZoneId(), vm.getId(), vm.getHostName(), offering.getId(), template.getId(), HypervisorType.BareMetal.toString()); - _usageEventDao.persist(usageEvent); + if (s_logger.isDebugEnabled()) { + s_logger.debug("Successfully allocated DB entry for " + vm); + } - _resourceLimitMgr.incrementResourceCount(accountId, ResourceType.user_vm); + if (s_logger.isDebugEnabled()) { + s_logger.debug("Successfully allocated DB entry for " + vm); + } + UserContext.current().setEventDetails("Vm Id: " + vm.getId()); + UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VM_CREATE, accountId, cmd.getZoneId(), vm.getId(), vm.getHostName(), offering.getId(), template.getId(), HypervisorType.BareMetal.toString()); + _usageEventDao.persist(usageEvent); - // Assign instance to the group - try { - if (group != null) { - boolean addToGroup = addInstanceToGroup(Long.valueOf(id), group); - if (!addToGroup) { - throw new CloudRuntimeException("Unable to assign Vm to the group " + group); - } - } - } catch (Exception ex) { - throw new CloudRuntimeException("Unable to assign Vm to the group " + group); - } + _resourceLimitMgr.incrementResourceCount(accountId, ResourceType.user_vm); - return vm; - } - - public UserVm startVirtualMachine(DeployVMCmd cmd) throws ResourceUnavailableException, InsufficientCapacityException, ConcurrentOperationException { - UserVmVO vm = _vmDao.findById(cmd.getInstanceId()); - - List servers = _resourceMgr.listAllUpAndEnabledHostsInOneZoneByType(Host.Type.PxeServer, vm.getDataCenterIdToDeployIn()); - if (servers.size() == 0) { - throw new CloudRuntimeException("Cannot find PXE server, please make sure there is one PXE server per zone"); - } - HostVO pxeServer = servers.get(0); - - VMTemplateVO template = _templateDao.findById(vm.getTemplateId()); - if (template == null || template.getFormat() != Storage.ImageFormat.BAREMETAL) { - throw new InvalidParameterValueException("Invalid template with id = " + vm.getTemplateId()); - } - - Map params = new HashMap(); - params.put(Param.PxeSeverType, _pxeMgr.getPxeServerType(pxeServer)); + // Assign instance to the group + try { + if (group != null) { + boolean addToGroup = addInstanceToGroup(Long.valueOf(id), group); + if (!addToGroup) { + throw new CloudRuntimeException("Unable to assign Vm to the group " + group); + } + } + } catch (Exception ex) { + throw new CloudRuntimeException("Unable to assign Vm to the group " + group); + } - return startVirtualMachine(cmd, params); - } - - - public UserVm startVirtualMachine(StartVMCmd cmd) throws ResourceUnavailableException, InsufficientCapacityException, ConcurrentOperationException { + return vm; + } + + @Override + public UserVm startVirtualMachine(DeployVMCmd cmd) throws ResourceUnavailableException, InsufficientCapacityException, ConcurrentOperationException { + UserVmVO vm = _vmDao.findById(cmd.getInstanceId()); + + List servers = _resourceMgr.listAllUpAndEnabledHostsInOneZoneByType(Host.Type.PxeServer, vm.getDataCenterIdToDeployIn()); + if (servers.size() == 0) { + throw new CloudRuntimeException("Cannot find PXE server, please make sure there is one PXE server per zone"); + } + HostVO pxeServer = servers.get(0); + + VMTemplateVO template = _templateDao.findById(vm.getTemplateId()); + if (template == null || template.getFormat() != Storage.ImageFormat.BAREMETAL) { + throw new InvalidParameterValueException("Cannot locate template by id", null); + } + + Map params = new HashMap(); + params.put(Param.PxeSeverType, _pxeMgr.getPxeServerType(pxeServer)); + + return startVirtualMachine(cmd, params); + } + + + @Override + public UserVm startVirtualMachine(StartVMCmd cmd) throws ResourceUnavailableException, InsufficientCapacityException, ConcurrentOperationException { UserVmVO vm = _vmDao.findById(cmd.getInstanceId()); VMTemplateVO template = _templateDao.findById(vm.getTemplateId()); if (template == null || template.getFormat() != Storage.ImageFormat.BAREMETAL) { - throw new InvalidParameterValueException("Invalid template with id = " + vm.getTemplateId()); + throw new InvalidParameterValueException("Cannot locate template by id", null); } - + Map params = null; if (vm.isUpdateParameters()) { List servers = _resourceMgr.listAllUpAndEnabledHostsInOneZoneByType(Host.Type.PxeServer, vm.getDataCenterIdToDeployIn()); @@ -422,140 +431,140 @@ public class BareMetalVmManagerImpl extends UserVmManagerImpl implements BareMet params = new HashMap(); params.put(Param.PxeSeverType, _pxeMgr.getPxeServerType(pxeServer)); } - + Pair> vmDetailsPair = super.startVirtualMachine(vm.getId(), cmd.getHostId(), params); return vmDetailsPair.first(); } - @Override - public boolean configure(String name, Map params) throws ConfigurationException { - _name = name; + @Override + public boolean configure(String name, Map params) throws ConfigurationException { + _name = name; - ComponentLocator locator = ComponentLocator.getCurrentLocator(); - _configDao = locator.getDao(ConfigurationDao.class); - if (_configDao == null) { - throw new ConfigurationException("Unable to get the configuration dao."); - } + ComponentLocator locator = ComponentLocator.getCurrentLocator(); + _configDao = locator.getDao(ConfigurationDao.class); + if (_configDao == null) { + throw new ConfigurationException("Unable to get the configuration dao."); + } - Map configs = _configDao.getConfiguration("AgentManager", params); + Map configs = _configDao.getConfiguration("AgentManager", params); - _instance = configs.get("instance.name"); - if (_instance == null) { - _instance = "DEFAULT"; - } + _instance = configs.get("instance.name"); + if (_instance == null) { + _instance = "DEFAULT"; + } - String workers = configs.get("expunge.workers"); - int wrks = NumbersUtil.parseInt(workers, 10); + String workers = configs.get("expunge.workers"); + int wrks = NumbersUtil.parseInt(workers, 10); - String time = configs.get("expunge.interval"); - _expungeInterval = NumbersUtil.parseInt(time, 86400); + String time = configs.get("expunge.interval"); + _expungeInterval = NumbersUtil.parseInt(time, 86400); - time = configs.get("expunge.delay"); - _expungeDelay = NumbersUtil.parseInt(time, _expungeInterval); + time = configs.get("expunge.delay"); + _expungeDelay = NumbersUtil.parseInt(time, _expungeInterval); - _executor = Executors.newScheduledThreadPool(wrks, new NamedThreadFactory("UserVm-Scavenger")); + _executor = Executors.newScheduledThreadPool(wrks, new NamedThreadFactory("UserVm-Scavenger")); - _itMgr.registerGuru(Type.UserBareMetal, this); - VirtualMachine.State.getStateMachine().registerListener(this); + _itMgr.registerGuru(Type.UserBareMetal, this); + VirtualMachine.State.getStateMachine().registerListener(this); - s_logger.info("User VM Manager is configured."); + s_logger.info("User VM Manager is configured."); - return true; - } - - @Override - public boolean finalizeVirtualMachineProfile(VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) { + return true; + } + + @Override + public boolean finalizeVirtualMachineProfile(VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) { UserVmVO vm = profile.getVirtualMachine(); - Account owner = _accountDao.findById(vm.getAccountId()); - - if (owner == null || owner.getState() == Account.State.disabled) { - throw new PermissionDeniedException("The owner of " + vm + " either does not exist or is disabled: " + vm.getAccountId()); - } - - PxeServerType pxeType = (PxeServerType) profile.getParameter(Param.PxeSeverType); - if (pxeType == null) { - s_logger.debug("This is a normal IPMI start, skip prepartion of PXE server"); - return true; - } - s_logger.debug("This is a PXE start, prepare PXE server first"); - - List servers = _resourceMgr.listAllUpAndEnabledHosts(Host.Type.PxeServer, null, dest.getPod().getId(), dest.getDataCenter().getId()); - if (servers.size() == 0) { - throw new CloudRuntimeException("Cannot find PXE server, please make sure there is one PXE server per zone"); - } - if (servers.size() > 1) { - throw new CloudRuntimeException("Find more than one PXE server, please make sure there is only one PXE server per zone in pod " + dest.getPod().getId() + " zone " + dest.getDataCenter().getId()); - } - HostVO pxeServer = servers.get(0); - - if (!_pxeMgr.prepare(pxeType, profile, dest, context, pxeServer.getId())) { - throw new CloudRuntimeException("Pepare PXE server failed"); - } - - profile.addBootArgs("PxeBoot"); - - return true; - } - - @Override - public boolean finalizeDeployment(Commands cmds, VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) { - UserVmVO userVm = profile.getVirtualMachine(); - List nics = _nicDao.listByVmId(userVm.getId()); - for (NicVO nic : nics) { - NetworkVO network = _networkDao.findById(nic.getNetworkId()); - if (network.getTrafficType() == TrafficType.Guest) { - userVm.setPrivateIpAddress(nic.getIp4Address()); - userVm.setPrivateMacAddress(nic.getMacAddress()); - } - } - _vmDao.update(userVm.getId(), userVm); - return true; - } + Account owner = _accountDao.findById(vm.getAccountId()); - @Override - public void finalizeStop(VirtualMachineProfile profile, StopAnswer answer) { - super.finalizeStop(profile, answer); - } + if (owner == null || owner.getState() == Account.State.disabled) { + throw new PermissionDeniedException("The owner of " + vm + " either does not exist or is disabled: " + vm.getAccountId()); + } - @Override - public UserVm destroyVm(long vmId) throws ResourceUnavailableException, ConcurrentOperationException { - return super.destroyVm(vmId); - } + PxeServerType pxeType = (PxeServerType) profile.getParameter(Param.PxeSeverType); + if (pxeType == null) { + s_logger.debug("This is a normal IPMI start, skip prepartion of PXE server"); + return true; + } + s_logger.debug("This is a PXE start, prepare PXE server first"); - @Override - public boolean preStateTransitionEvent(State oldState, Event event, State newState, VirtualMachine vo, boolean status, Object opaque) { - return true; - } + List servers = _resourceMgr.listAllUpAndEnabledHosts(Host.Type.PxeServer, null, dest.getPod().getId(), dest.getDataCenter().getId()); + if (servers.size() == 0) { + throw new CloudRuntimeException("Cannot find PXE server, please make sure there is one PXE server per zone"); + } + if (servers.size() > 1) { + throw new CloudRuntimeException("Find more than one PXE server, please make sure there is only one PXE server per zone in pod " + dest.getPod().getId() + " zone " + dest.getDataCenter().getId()); + } + HostVO pxeServer = servers.get(0); - @Override - public boolean postStateTransitionEvent(State oldState, Event event, State newState, VirtualMachine vo, boolean status, Object opaque) { - if (newState != State.Starting && newState != State.Error && newState != State.Expunging) { - return true; - } - - if (vo.getHypervisorType() != HypervisorType.BareMetal) { - return true; - } - - HostVO host = _hostDao.findById(vo.getHostId()); - if (host == null) { - s_logger.debug("Skip oldState " + oldState + " to " + "newState " + newState + " transimtion"); - return true; - } - _hostDao.loadDetails(host); - - if (newState == State.Starting) { - host.setDetail("vmName", vo.getInstanceName()); - s_logger.debug("Add vmName " + host.getDetail("vmName") + " to host " + host.getId() + " details"); - } else { - if (host.getDetail("vmName") != null && host.getDetail("vmName").equalsIgnoreCase(vo.getInstanceName())) { - s_logger.debug("Remove vmName " + host.getDetail("vmName") + " from host " + host.getId() + " details"); - host.getDetails().remove("vmName"); - } - } - _hostDao.saveDetails(host); - - - return true; - } + if (!_pxeMgr.prepare(pxeType, profile, dest, context, pxeServer.getId())) { + throw new CloudRuntimeException("Pepare PXE server failed"); + } + + profile.addBootArgs("PxeBoot"); + + return true; + } + + @Override + public boolean finalizeDeployment(Commands cmds, VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) { + UserVmVO userVm = profile.getVirtualMachine(); + List nics = _nicDao.listByVmId(userVm.getId()); + for (NicVO nic : nics) { + NetworkVO network = _networkDao.findById(nic.getNetworkId()); + if (network.getTrafficType() == TrafficType.Guest) { + userVm.setPrivateIpAddress(nic.getIp4Address()); + userVm.setPrivateMacAddress(nic.getMacAddress()); + } + } + _vmDao.update(userVm.getId(), userVm); + return true; + } + + @Override + public void finalizeStop(VirtualMachineProfile profile, StopAnswer answer) { + super.finalizeStop(profile, answer); + } + + @Override + public UserVm destroyVm(long vmId) throws ResourceUnavailableException, ConcurrentOperationException { + return super.destroyVm(vmId); + } + + @Override + public boolean preStateTransitionEvent(State oldState, Event event, State newState, VirtualMachine vo, boolean status, Object opaque) { + return true; + } + + @Override + public boolean postStateTransitionEvent(State oldState, Event event, State newState, VirtualMachine vo, boolean status, Object opaque) { + if (newState != State.Starting && newState != State.Error && newState != State.Expunging) { + return true; + } + + if (vo.getHypervisorType() != HypervisorType.BareMetal) { + return true; + } + + HostVO host = _hostDao.findById(vo.getHostId()); + if (host == null) { + s_logger.debug("Skip oldState " + oldState + " to " + "newState " + newState + " transimtion"); + return true; + } + _hostDao.loadDetails(host); + + if (newState == State.Starting) { + host.setDetail("vmName", vo.getInstanceName()); + s_logger.debug("Add vmName " + host.getDetail("vmName") + " to host " + host.getId() + " details"); + } else { + if (host.getDetail("vmName") != null && host.getDetail("vmName").equalsIgnoreCase(vo.getInstanceName())) { + s_logger.debug("Remove vmName " + host.getDetail("vmName") + " from host " + host.getId() + " details"); + host.getDetails().remove("vmName"); + } + } + _hostDao.saveDetails(host); + + + return true; + } } diff --git a/server/src/com/cloud/network/element/VirtualRouterElement.java b/server/src/com/cloud/network/element/VirtualRouterElement.java index 82b66d9f151..db83767a2af 100755 --- a/server/src/com/cloud/network/element/VirtualRouterElement.java +++ b/server/src/com/cloud/network/element/VirtualRouterElement.java @@ -66,6 +66,7 @@ import com.cloud.offerings.NetworkOfferingVO; import com.cloud.offerings.dao.NetworkOfferingDao; import com.cloud.user.AccountManager; import com.cloud.uservm.UserVm; +import com.cloud.utils.IdentityProxy; import com.cloud.utils.Pair; import com.cloud.utils.component.AdapterBase; import com.cloud.utils.component.Inject; @@ -86,8 +87,8 @@ import com.google.gson.Gson; @Local(value = NetworkElement.class) public class VirtualRouterElement extends AdapterBase implements VirtualRouterElementService, DhcpServiceProvider, - UserDataServiceProvider, SourceNatServiceProvider, StaticNatServiceProvider, FirewallServiceProvider, - LoadBalancingServiceProvider, PortForwardingServiceProvider, RemoteAccessVPNServiceProvider, IpDeployer { +UserDataServiceProvider, SourceNatServiceProvider, StaticNatServiceProvider, FirewallServiceProvider, +LoadBalancingServiceProvider, PortForwardingServiceProvider, RemoteAccessVPNServiceProvider, IpDeployer { private static final Logger s_logger = Logger.getLogger(VirtualRouterElement.class); protected static final Map> capabilities = setCapabilities(); @@ -128,7 +129,7 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl if (physicalNetworkId == null) { return false; } - + if (network.getVpcId() != null) { return false; } @@ -157,7 +158,7 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl public boolean implement(Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context) throws ResourceUnavailableException, ConcurrentOperationException, InsufficientCapacityException { - + if (offering.isSystemOnly()) { return false; } @@ -172,14 +173,14 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl throw new ResourceUnavailableException("Can't find at least one running router!", DataCenter.class, network.getDataCenterId()); } - + return true; } @Override public boolean prepare(Network network, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) - throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException { + throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException { if (vm.getType() != VirtualMachine.Type.User || vm.getHypervisorType() == HypervisorType.BareMetal) { return false; } @@ -205,7 +206,7 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl throw new ResourceUnavailableException("Can't find at least one running router!", DataCenter.class, network.getDataCenterId()); } - + return true; } @@ -215,7 +216,7 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl List routers = _routerDao.listByNetworkAndRole(config.getId(), Role.VIRTUAL_ROUTER); if (routers == null || routers.isEmpty()) { s_logger.debug("Virtual router elemnt doesn't need to apply firewall rules on the backend; virtual " + - "router doesn't exist in the network " + config.getId()); + "router doesn't exist in the network " + config.getId()); return true; } @@ -243,7 +244,7 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl boolean matchedEndChar = false; if (str.length() < 2) return false; // atleast one numeric and one char. example: - // 3h + // 3h char strEnd = str.toCharArray()[str.length() - 1]; for (char c : endChar.toCharArray()) { if (strEnd == c) { @@ -285,12 +286,16 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl expire = value; } if ((expire != null) && !containsOnlyNumbers(expire, timeEndChar)) { - throw new InvalidParameterValueException("Failed LB in validation rule id: " + rule.getId() + - " Cause: expire is not in timeformat: " + expire); + List idList = new ArrayList(); + idList.add(new IdentityProxy(rule, rule.getId(), "ruleId")); + throw new InvalidParameterValueException("Failed LB in validation rule with specified id." + + " Cause: expire is not in timeformat: " + expire, idList); } if ((tablesize != null) && !containsOnlyNumbers(tablesize, "kmg")) { - throw new InvalidParameterValueException("Failed LB in validation rule id: " + rule.getId() + - " Cause: tablesize is not in size format: " + tablesize); + List idList = new ArrayList(); + idList.add(new IdentityProxy(rule, rule.getId(), "ruleId")); + throw new InvalidParameterValueException("Failed LB in validation rule with specified id." + + " Cause: tablesize is not in size format: " + tablesize, idList); } } else if (StickinessMethodType.AppCookieBased.getName().equalsIgnoreCase(stickinessPolicy.getMethodName())) { @@ -316,12 +321,16 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl } if ((length != null) && (!containsOnlyNumbers(length, null))) { - throw new InvalidParameterValueException("Failed LB in validation rule id: " + rule.getId() + - " Cause: length is not a number: " + length); + List idList = new ArrayList(); + idList.add(new IdentityProxy(rule, rule.getId(), "ruleId")); + throw new InvalidParameterValueException("Failed LB in validation rule with specified id." + + " Cause: length is not a number: " + length, idList); } if ((holdTime != null) && (!containsOnlyNumbers(holdTime, timeEndChar) && !containsOnlyNumbers(holdTime, null))) { - throw new InvalidParameterValueException("Failed LB in validation rule id: " + rule.getId() + - " Cause: holdtime is not in timeformat: " + holdTime); + List idList = new ArrayList(); + idList.add(new IdentityProxy(rule, rule.getId(), "ruleId")); + throw new InvalidParameterValueException("Failed LB in validation rule with specified id." + + " Cause: holdtime is not in timeformat: " + holdTime, idList); } } } @@ -346,7 +355,7 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl List routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER); if (routers == null || routers.isEmpty()) { s_logger.debug("Virtual router elemnt doesn't need to apply firewall rules on the backend; virtual " + - "router doesn't exist in the network " + network.getId()); + "router doesn't exist in the network " + network.getId()); return true; } @@ -368,7 +377,7 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl List routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER); if (routers == null || routers.isEmpty()) { s_logger.debug("Virtual router elemnt doesn't need to apply vpn users on the backend; virtual router" + - " doesn't exist in the network " + network.getId()); + " doesn't exist in the network " + network.getId()); return null; } return _routerMgr.applyVpnUsers(network, users, routers); @@ -384,7 +393,7 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl List routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER); if (routers == null || routers.isEmpty()) { s_logger.debug("Virtual router elemnt doesn't need stop vpn on the backend; virtual router doesn't" + - " exist in the network " + network.getId()); + " exist in the network " + network.getId()); return true; } return _routerMgr.startRemoteAccessVpn(network, vpn, routers); @@ -400,7 +409,7 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl List routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER); if (routers == null || routers.isEmpty()) { s_logger.debug("Virtual router elemnt doesn't need stop vpn on the backend; virtual router doesn't " + - "exist in the network " + network.getId()); + "exist in the network " + network.getId()); return true; } return _routerMgr.deleteRemoteAccessVpn(network, vpn, routers); @@ -424,7 +433,7 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl List routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER); if (routers == null || routers.isEmpty()) { s_logger.debug("Virtual router elemnt doesn't need to associate ip addresses on the backend; virtual " + - "router doesn't exist in the network " + network.getId()); + "router doesn't exist in the network " + network.getId()); return true; } @@ -452,61 +461,61 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl method.addParam("cookie-name", false, "Cookie name passed in http header by the LB to the client.", false); method.addParam("mode", false, "Valid values: insert, rewrite, prefix. Default value: insert. In the insert mode cookie will be created" + - " by the LB. In other modes, cookie will be created by the server and LB modifies it.", false); + " by the LB. In other modes, cookie will be created by the server and LB modifies it.", false); method.addParam( "nocache", false, "This option is recommended in conjunction with the insert mode when there is a cache between the client" + - " and HAProxy, as it ensures that a cacheable response will be tagged non-cacheable if a cookie needs " + - "to be inserted. This is important because if all persistence cookies are added on a cacheable home page" + - " for instance, then all customers will then fetch the page from an outer cache and will all share the " + - "same persistence cookie, leading to one server receiving much more traffic than others. See also the " + - "insert and postonly options. ", - true); + " and HAProxy, as it ensures that a cacheable response will be tagged non-cacheable if a cookie needs " + + "to be inserted. This is important because if all persistence cookies are added on a cacheable home page" + + " for instance, then all customers will then fetch the page from an outer cache and will all share the " + + "same persistence cookie, leading to one server receiving much more traffic than others. See also the " + + "insert and postonly options. ", + true); method.addParam( "indirect", false, "When this option is specified in insert mode, cookies will only be added when the server was not reached" + - " after a direct access, which means that only when a server is elected after applying a load-balancing algorithm," + - " or after a redispatch, then the cookie will be inserted. If the client has all the required information" + - " to connect to the same server next time, no further cookie will be inserted. In all cases, when the " + - "indirect option is used in insert mode, the cookie is always removed from the requests transmitted to " + - "the server. The persistence mechanism then becomes totally transparent from the application point of view.", - true); + " after a direct access, which means that only when a server is elected after applying a load-balancing algorithm," + + " or after a redispatch, then the cookie will be inserted. If the client has all the required information" + + " to connect to the same server next time, no further cookie will be inserted. In all cases, when the " + + "indirect option is used in insert mode, the cookie is always removed from the requests transmitted to " + + "the server. The persistence mechanism then becomes totally transparent from the application point of view.", + true); method.addParam( "postonly", false, "This option ensures that cookie insertion will only be performed on responses to POST requests. It is an" + - " alternative to the nocache option, because POST responses are not cacheable, so this ensures that the " + - "persistence cookie will never get cached.Since most sites do not need any sort of persistence before the" + - " first POST which generally is a login request, this is a very efficient method to optimize caching " + - "without risking to find a persistence cookie in the cache. See also the insert and nocache options.", - true); + " alternative to the nocache option, because POST responses are not cacheable, so this ensures that the " + + "persistence cookie will never get cached.Since most sites do not need any sort of persistence before the" + + " first POST which generally is a login request, this is a very efficient method to optimize caching " + + "without risking to find a persistence cookie in the cache. See also the insert and nocache options.", + true); method.addParam( "domain", false, "This option allows to specify the domain at which a cookie is inserted. It requires exactly one parameter:" + - " a valid domain name. If the domain begins with a dot, the browser is allowed to use it for any host " + - "ending with that name. It is also possible to specify several domain names by invoking this option multiple" + - " times. Some browsers might have small limits on the number of domains, so be careful when doing that. " + - "For the record, sending 10 domains to MSIE 6 or Firefox 2 works as expected.", - false); + " a valid domain name. If the domain begins with a dot, the browser is allowed to use it for any host " + + "ending with that name. It is also possible to specify several domain names by invoking this option multiple" + + " times. Some browsers might have small limits on the number of domains, so be careful when doing that. " + + "For the record, sending 10 domains to MSIE 6 or Firefox 2 works as expected.", + false); methodList.add(method); method = new LbStickinessMethod(StickinessMethodType.AppCookieBased, "This is App session based sticky method. Define session stickiness on an existing application cookie. " + "It can be used only for a specific http traffic"); method.addParam("cookie-name", false, "This is the name of the cookie used by the application and which LB will " + - "have to learn for each new session. Default value: Auto geneared based on ip", false); + "have to learn for each new session. Default value: Auto geneared based on ip", false); method.addParam("length", false, "This is the max number of characters that will be memorized and checked in " + - "each cookie value. Default value:52", false); + "each cookie value. Default value:52", false); method.addParam( "holdtime", false, "This is the time after which the cookie will be removed from memory if unused. The value should be in " + - "the format Example : 20s or 30m or 4h or 5d . only seconds(s), minutes(m) hours(h) and days(d) are valid," + - " cannot use th combinations like 20h30m. Default value:3h ", - false); + "the format Example : 20s or 30m or 4h or 5d . only seconds(s), minutes(m) hours(h) and days(d) are valid," + + " cannot use th combinations like 20h30m. Default value:3h ", + false); method.addParam( "request-learn", false, @@ -516,24 +525,24 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl "prefix", false, "When this option is specified, haproxy will match on the cookie prefix (or URL parameter prefix). " + - "The appsession value is the data following this prefix. Example : appsession ASPSESSIONID len 64 timeout 3h prefix This will match the cookie ASPSESSIONIDXXXX=XXXXX, the appsession value will be XXXX=XXXXX.", - true); + "The appsession value is the data following this prefix. Example : appsession ASPSESSIONID len 64 timeout 3h prefix This will match the cookie ASPSESSIONIDXXXX=XXXXX, the appsession value will be XXXX=XXXXX.", + true); method.addParam( "mode", false, "This option allows to change the URL parser mode. 2 modes are currently supported : - path-parameters " + - ": The parser looks for the appsession in the path parameters part (each parameter is separated by a semi-colon), " + - "which is convenient for JSESSIONID for example.This is the default mode if the option is not set. - query-string :" + - " In this mode, the parser will look for the appsession in the query string.", - false); + ": The parser looks for the appsession in the path parameters part (each parameter is separated by a semi-colon), " + + "which is convenient for JSESSIONID for example.This is the default mode if the option is not set. - query-string :" + + " In this mode, the parser will look for the appsession in the query string.", + false); methodList.add(method); method = new LbStickinessMethod(StickinessMethodType.SourceBased, "This is source based Stickiness method, " + - "it can be used for any type of protocol."); + "it can be used for any type of protocol."); method.addParam("tablesize", false, "Size of table to store source ip addresses. example: tablesize=200k or 300m" + - " or 400g. Default value:200k", false); + " or 400g. Default value:200k", false); method.addParam("expire", false, "Entry in source ip table will expire after expire duration. units can be s,m,h,d ." + - " example: expire=30m 20s 50h 4d. Default value:3h", false); + " example: expire=30m 20s 50h 4d. Default value:3h", false); methodList.add(method); Gson gson = new Gson(); @@ -593,7 +602,7 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl List routers = _routerDao.listByNetworkAndRole(config.getId(), Role.VIRTUAL_ROUTER); if (routers == null || routers.isEmpty()) { s_logger.debug("Virtual router elemnt doesn't need to apply static nat on the backend; virtual " + - "router doesn't exist in the network " + config.getId()); + "router doesn't exist in the network " + config.getId()); return true; } @@ -694,7 +703,7 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl List routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER); if (routers == null || routers.isEmpty()) { s_logger.debug("Virtual router elemnt doesn't need to apply firewall rules on the backend; virtual " + - "router doesn't exist in the network " + network.getId()); + "router doesn't exist in the network " + network.getId()); return true; } @@ -735,7 +744,7 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl result = result && (_routerMgr.destroyRouter(router.getId()) != null); } _vrProviderDao.remove(elementId); - + return result; } @@ -764,7 +773,7 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl @Override public boolean addDhcpEntry(Network network, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) - throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException { + throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException { if (canHandle(network, Service.Dhcp)) { if (vm.getType() != VirtualMachine.Type.User) { return false; @@ -787,7 +796,7 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl @Override public boolean addPasswordAndUserdata(Network network, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) - throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException { + throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException { if (canHandle(network, Service.UserData)) { if (vm.getType() != VirtualMachine.Type.User) { return false; diff --git a/server/src/com/cloud/network/firewall/FirewallManagerImpl.java b/server/src/com/cloud/network/firewall/FirewallManagerImpl.java index a2a13132716..3ea17832f93 100644 --- a/server/src/com/cloud/network/firewall/FirewallManagerImpl.java +++ b/server/src/com/cloud/network/firewall/FirewallManagerImpl.java @@ -61,6 +61,7 @@ import com.cloud.user.Account; import com.cloud.user.AccountManager; import com.cloud.user.DomainManager; import com.cloud.user.UserContext; +import com.cloud.utils.IdentityProxy; import com.cloud.utils.Ternary; import com.cloud.utils.component.Inject; import com.cloud.utils.component.Manager; @@ -148,25 +149,25 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma public FirewallRule createFirewallRule(long ipAddrId, Account caller, String xId, Integer portStart, Integer portEnd, String protocol, List sourceCidrList, Integer icmpCode, Integer icmpType, Long relatedRuleId, FirewallRule.FirewallRuleType type, long networkId) throws NetworkRuleConflictException { - + IPAddressVO ipAddress = _ipAddressDao.findById(ipAddrId); // Validate ip address if (ipAddress == null && type == FirewallRule.FirewallRuleType.User) { - throw new InvalidParameterValueException("Unable to create firewall rule; ip id=" + ipAddrId + - " doesn't exist in the system"); + throw new InvalidParameterValueException("Unable to create firewall rule; " + + "couldn't locate IP address by id in the system", null); } - + _networkMgr.checkIpForService(ipAddress, Service.Firewall); validateFirewallRule(caller, ipAddress, portStart, portEnd, protocol, Purpose.Firewall, type); // icmp code and icmp type can't be passed in for any other protocol rather than icmp if (!protocol.equalsIgnoreCase(NetUtils.ICMP_PROTO) && (icmpCode != null || icmpType != null)) { - throw new InvalidParameterValueException("Can specify icmpCode and icmpType for ICMP protocol only"); + throw new InvalidParameterValueException("Can specify icmpCode and icmpType for ICMP protocol only", null); } if (protocol.equalsIgnoreCase(NetUtils.ICMP_PROTO) && (portStart != null || portEnd != null)) { - throw new InvalidParameterValueException("Can't specify start/end port when protocol is ICMP"); + throw new InvalidParameterValueException("Can't specify start/end port when protocol is ICMP", null); } Long accountId = null; @@ -209,8 +210,13 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma if (ipId != null) { IPAddressVO ipAddressVO = _ipAddressDao.findById(ipId); - if (ipAddressVO == null || !ipAddressVO.readyToUse()) { - throw new InvalidParameterValueException("Ip address id=" + ipId + " not ready for firewall rules yet"); + if (ipAddressVO == null) { + throw new InvalidParameterValueException("Couldn't locate Ip address by id", null); + } + if (!ipAddressVO.readyToUse()) { + List idList = new ArrayList(); + idList.add(new IdentityProxy(ipAddressVO, ipId, "IpId")); + throw new InvalidParameterValueException("Ip address with specified id is not ready for firewall rules yet", idList); } _accountMgr.checkAccess(caller, null, true, ipAddressVO); } @@ -228,19 +234,19 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma sb.and("id", sb.entity().getId(), Op.EQ); sb.and("ip", sb.entity().getSourceIpAddressId(), Op.EQ); sb.and("purpose", sb.entity().getPurpose(), Op.EQ); - + if (tags != null && !tags.isEmpty()) { - SearchBuilder tagSearch = _resourceTagDao.createSearchBuilder(); - for (int count=0; count < tags.size(); count++) { - tagSearch.or().op("key" + String.valueOf(count), tagSearch.entity().getKey(), SearchCriteria.Op.EQ); - tagSearch.and("value" + String.valueOf(count), tagSearch.entity().getValue(), SearchCriteria.Op.EQ); - tagSearch.cp(); + SearchBuilder tagSearch = _resourceTagDao.createSearchBuilder(); + for (int count=0; count < tags.size(); count++) { + tagSearch.or().op("key" + String.valueOf(count), tagSearch.entity().getKey(), SearchCriteria.Op.EQ); + tagSearch.and("value" + String.valueOf(count), tagSearch.entity().getValue(), SearchCriteria.Op.EQ); + tagSearch.cp(); + } + tagSearch.and("resourceType", tagSearch.entity().getResourceType(), SearchCriteria.Op.EQ); + sb.groupBy(sb.entity().getId()); + sb.join("tagSearch", tagSearch, sb.entity().getId(), tagSearch.entity().getResourceId(), JoinBuilder.JoinType.INNER); } - tagSearch.and("resourceType", tagSearch.entity().getResourceType(), SearchCriteria.Op.EQ); - sb.groupBy(sb.entity().getId()); - sb.join("tagSearch", tagSearch, sb.entity().getId(), tagSearch.entity().getResourceId(), JoinBuilder.JoinType.INNER); - } SearchCriteria sc = sb.create(); _accountMgr.buildACLSearchCriteria(sc, domainId, isRecursive, permittedAccounts, listProjectResourcesCriteria); @@ -248,7 +254,7 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma if (id != null) { sc.setParameters("id", id); } - + if (tags != null && !tags.isEmpty()) { int count = 0; sc.setJoinParameters("tagSearch", "resourceType", TaggedResourceType.FirewallRule.toString()); @@ -273,7 +279,7 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma List rules = _firewallDao.listByIpAndPurposeAndNotRevoked(newRule.getSourceIpAddressId(), null); assert (rules.size() >= 1) : "For network rules, we now always first persist the rule and then check for " + - "network conflicts so we should at least have one rule at this point."; + "network conflicts so we should at least have one rule at this point."; for (FirewallRuleVO rule : rules) { if (rule.getId() == newRule.getId()) { @@ -282,7 +288,7 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma boolean oneOfRulesIsFirewall = ((rule.getPurpose() == Purpose.Firewall || newRule.getPurpose() == Purpose.Firewall) && ((newRule.getPurpose() != rule.getPurpose()) || (!newRule.getProtocol() - .equalsIgnoreCase(rule.getProtocol())))); + .equalsIgnoreCase(rule.getProtocol())))); // if both rules are firewall and their cidrs are different, we can skip port ranges verification boolean bothRulesFirewall = (rule.getPurpose() == newRule.getPurpose() && rule.getPurpose() == Purpose.Firewall); @@ -323,7 +329,9 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma if (newRule.getIcmpCode().longValue() == rule.getIcmpCode().longValue() && newRule.getIcmpType().longValue() == rule.getIcmpType().longValue() && newRule.getProtocol().equalsIgnoreCase(rule.getProtocol()) && duplicatedCidrs) { - throw new InvalidParameterValueException("New rule conflicts with existing rule id=" + rule.getId()); + List idList = new ArrayList(); + idList.add(new IdentityProxy(rule, rule.getId(), "ruleId")); + throw new InvalidParameterValueException("New rule conflicts with existing rule with specified id", idList); } } @@ -334,12 +342,12 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma } else if (!oneOfRulesIsFirewall && !(bothRulesFirewall && !duplicatedCidrs) && ((rule.getSourcePortStart().intValue() <= newRule.getSourcePortStart().intValue() && rule.getSourcePortEnd().intValue() >= newRule.getSourcePortStart().intValue()) - || (rule.getSourcePortStart().intValue() <= newRule.getSourcePortEnd().intValue() - && rule.getSourcePortEnd().intValue() >= newRule.getSourcePortEnd().intValue()) - || (newRule.getSourcePortStart().intValue() <= rule.getSourcePortStart().intValue() - && newRule.getSourcePortEnd().intValue() >= rule.getSourcePortStart().intValue()) - || (newRule.getSourcePortStart().intValue() <= rule.getSourcePortEnd().intValue() - && newRule.getSourcePortEnd().intValue() >= rule.getSourcePortEnd().intValue()))) { + || (rule.getSourcePortStart().intValue() <= newRule.getSourcePortEnd().intValue() + && rule.getSourcePortEnd().intValue() >= newRule.getSourcePortEnd().intValue()) + || (newRule.getSourcePortStart().intValue() <= rule.getSourcePortStart().intValue() + && newRule.getSourcePortEnd().intValue() >= rule.getSourcePortStart().intValue()) + || (newRule.getSourcePortStart().intValue() <= rule.getSourcePortEnd().intValue() + && newRule.getSourcePortEnd().intValue() >= rule.getSourcePortEnd().intValue()))) { // we allow port forwarding rules with the same parameters but different protocols boolean allowPf = (rule.getPurpose() == Purpose.PortForwarding && newRule.getPurpose() == Purpose.PortForwarding @@ -363,15 +371,15 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma public void validateFirewallRule(Account caller, IPAddressVO ipAddress, Integer portStart, Integer portEnd, String proto, Purpose purpose, FirewallRuleType type) { if (portStart != null && !NetUtils.isValidPort(portStart)) { - throw new InvalidParameterValueException("publicPort is an invalid value: " + portStart); + throw new InvalidParameterValueException("publicPort is an invalid value: " + portStart, null); } if (portEnd != null && !NetUtils.isValidPort(portEnd)) { - throw new InvalidParameterValueException("Public port range is an invalid value: " + portEnd); + throw new InvalidParameterValueException("Public port range is an invalid value: " + portEnd, null); } // start port can't be bigger than end port if (portStart != null && portEnd != null && portStart > portEnd) { - throw new InvalidParameterValueException("Start port can't be bigger than end port"); + throw new InvalidParameterValueException("Start port can't be bigger than end port", null); } if (ipAddress == null && type == FirewallRuleType.System) { @@ -384,8 +392,9 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma Long networkId = null; if (ipAddress.getAssociatedWithNetworkId() == null) { - throw new InvalidParameterValueException("Unable to create firewall rule ; ip id=" + - ipAddress.getId() + " is not associated with any network"); + List idList = new ArrayList(); + idList.add(new IdentityProxy(ipAddress, ipAddress.getId(), "IpId")); + throw new InvalidParameterValueException("Unable to create firewall rule ; ip with specified id is not associated with any network", idList); } else { networkId = ipAddress.getAssociatedWithNetworkId(); } @@ -407,9 +416,11 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma if (caps != null) { String supportedProtocols = caps.get(Capability.SupportedProtocols).toLowerCase(); if (!supportedProtocols.contains(proto.toLowerCase())) { - throw new InvalidParameterValueException("Protocol " + proto + " is not supported in zone " + network.getDataCenterId()); + List idList = new ArrayList(); + idList.add(new IdentityProxy(network, network.getDataCenterId(), "dcId")); + throw new InvalidParameterValueException("Protocol " + proto + " is not supported in zone with specified id", idList); } else if (proto.equalsIgnoreCase(NetUtils.ICMP_PROTO) && purpose != Purpose.Firewall) { - throw new InvalidParameterValueException("Protocol " + proto + " is currently supported only for rules with purpose " + Purpose.Firewall); + throw new InvalidParameterValueException("Protocol " + proto + " is currently supported only for rules with purpose " + Purpose.Firewall, null); } } } @@ -448,18 +459,18 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma @DB @Override public void removeRule(FirewallRule rule) { - + Transaction txn = Transaction.currentTxn(); txn.start(); //remove the rule _firewallDao.remove(rule.getId()); - + //if the rule is the last one for the ip address assigned to VPC, unassign it from the network IpAddress ip = _ipAddressDao.findById(rule.getSourceIpAddressId()); if (ip != null && ip.getVpcId() != null && _firewallDao.listByIp(ip.getId()).isEmpty()) { _networkMgr.unassignIPFromVpcNetwork(ip.getId()); } - + txn.commit(); } @@ -504,11 +515,11 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma FirewallRuleVO rule = _firewallDao.findById(ruleId); if (rule == null || rule.getPurpose() != Purpose.Firewall) { - throw new InvalidParameterValueException("Unable to find " + ruleId + " having purpose " + Purpose.Firewall); + throw new InvalidParameterValueException("Unable to find rule having purpose " + Purpose.Firewall, null); } if (rule.getType() == FirewallRuleType.System && caller.getType() != Account.ACCOUNT_TYPE_ADMIN) { - throw new InvalidParameterValueException("Only root admin can delete the system wide firewall rule"); + throw new InvalidParameterValueException("Only root admin can delete the system wide firewall rule", null); } _accountMgr.checkAccess(caller, null, true, rule); @@ -602,7 +613,7 @@ public class FirewallManagerImpl implements FirewallService, FirewallManager, Ma @Override public FirewallRule createRuleForAllCidrs(long ipAddrId, Account caller, Integer startPort, Integer endPort, String protocol, Integer icmpCode, Integer icmpType, Long relatedRuleId, long networkId) - throws NetworkRuleConflictException { + throws NetworkRuleConflictException { // If firwallRule for this port range already exists, return it List rules = _firewallDao.listByIpPurposeAndProtocolAndNotRevoked(ipAddrId, startPort, endPort, diff --git a/server/src/com/cloud/network/guru/DirectNetworkGuru.java b/server/src/com/cloud/network/guru/DirectNetworkGuru.java index 7ff89b03fe7..1fed8caacdc 100755 --- a/server/src/com/cloud/network/guru/DirectNetworkGuru.java +++ b/server/src/com/cloud/network/guru/DirectNetworkGuru.java @@ -65,24 +65,24 @@ public class DirectNetworkGuru extends AdapterBase implements NetworkGuru { IPAddressDao _ipAddressDao; @Inject NetworkOfferingDao _networkOfferingDao; - + private static final TrafficType[] _trafficTypes = {TrafficType.Guest}; - + @Override public boolean isMyTrafficType(TrafficType type) { - for (TrafficType t : _trafficTypes) { - if (t == type) { - return true; - } - } - return false; + for (TrafficType t : _trafficTypes) { + if (t == type) { + return true; + } + } + return false; } @Override public TrafficType[] getSupportedTrafficType() { - return _trafficTypes; + return _trafficTypes; } - + protected boolean canHandle(NetworkOffering offering, DataCenter dc) { // this guru handles only Guest networks in Advance zone with source nat service disabled if (dc.getNetworkType() == NetworkType.Advanced && isMyTrafficType(offering.getTrafficType()) && offering.getGuestType() == GuestType.Shared) { @@ -110,7 +110,7 @@ public class DirectNetworkGuru extends AdapterBase implements NetworkGuru { if (userSpecified != null) { if ((userSpecified.getCidr() == null && userSpecified.getGateway() != null) || (userSpecified.getCidr() != null && userSpecified.getGateway() == null)) { - throw new InvalidParameterValueException("cidr and gateway must be specified together."); + throw new InvalidParameterValueException("cidr and gateway must be specified together.", null); } if (userSpecified.getCidr() != null) { @@ -152,7 +152,7 @@ public class DirectNetworkGuru extends AdapterBase implements NetworkGuru { @Override public NicProfile allocate(Network network, NicProfile nic, VirtualMachineProfile vm) throws InsufficientVirtualNetworkCapcityException, - InsufficientAddressCapacityException, ConcurrentOperationException { + InsufficientAddressCapacityException, ConcurrentOperationException { DataCenter dc = _dcDao.findById(network.getDataCenterId()); @@ -191,10 +191,10 @@ public class DirectNetworkGuru extends AdapterBase implements NetworkGuru { @Override @DB public void deallocate(Network network, NicProfile nic, VirtualMachineProfile vm) { - if (s_logger.isDebugEnabled()) { + if (s_logger.isDebugEnabled()) { s_logger.debug("Deallocate network: networkId: " + nic.getNetworkId() + ", ip: " + nic.getIp4Address()); } - + IPAddressVO ip = _ipAddressDao.findByIpAndSourceNetworkId(nic.getNetworkId(), nic.getIp4Address()); if (ip != null) { Transaction txn = Transaction.currentTxn(); diff --git a/server/src/com/cloud/network/guru/GuestNetworkGuru.java b/server/src/com/cloud/network/guru/GuestNetworkGuru.java index cb6f045bc68..360cea128d4 100755 --- a/server/src/com/cloud/network/guru/GuestNetworkGuru.java +++ b/server/src/com/cloud/network/guru/GuestNetworkGuru.java @@ -136,7 +136,7 @@ public class GuestNetworkGuru extends AdapterBase implements NetworkGuru { if (userSpecified != null) { if ((userSpecified.getCidr() == null && userSpecified.getGateway() != null) || (userSpecified.getCidr() != null && userSpecified.getGateway() == null)) { - throw new InvalidParameterValueException("cidr and gateway must be specified together."); + throw new InvalidParameterValueException("cidr and gateway must be specified together.", null); } if (userSpecified.getCidr() != null) { @@ -255,12 +255,12 @@ public class GuestNetworkGuru extends AdapterBase implements NetworkGuru { } protected void allocateVnet(Network network, NetworkVO implemented, long dcId, - long physicalNetworkId, String reservationId) throws InsufficientVirtualNetworkCapcityException { + long physicalNetworkId, String reservationId) throws InsufficientVirtualNetworkCapcityException { if (network.getBroadcastUri() == null) { String vnet = _dcDao.allocateVnet(dcId, physicalNetworkId, network.getAccountId(), reservationId); if (vnet == null) { throw new InsufficientVirtualNetworkCapcityException("Unable to allocate vnet as a " + - "part of network " + network + " implement ", DataCenter.class, dcId); + "part of network " + network + " implement ", DataCenter.class, dcId); } implemented.setBroadcastUri(BroadcastDomainType.Vlan.toUri(vnet)); EventUtils.saveEvent(UserContext.current().getCallerUserId(), network.getAccountId(), @@ -269,7 +269,7 @@ public class GuestNetworkGuru extends AdapterBase implements NetworkGuru { implemented.setBroadcastUri(network.getBroadcastUri()); } } - + @Override public Network implement(Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context) throws InsufficientVirtualNetworkCapcityException { @@ -299,10 +299,10 @@ public class GuestNetworkGuru extends AdapterBase implements NetworkGuru { @Override public NicProfile allocate(Network network, NicProfile nic, VirtualMachineProfile vm) throws InsufficientVirtualNetworkCapcityException, - InsufficientAddressCapacityException { + InsufficientAddressCapacityException { assert (network.getTrafficType() == TrafficType.Guest) : "Look at my name! Why are you calling" + - " me when the traffic type is : " + network.getTrafficType(); + " me when the traffic type is : " + network.getTrafficType(); if (nic == null) { nic = new NicProfile(ReservationStrategy.Start, null, null, null, null); @@ -363,7 +363,7 @@ public class GuestNetworkGuru extends AdapterBase implements NetworkGuru { @Override public void reserve(NicProfile nic, Network network, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) - throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException { + throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException { assert (nic.getReservationStrategy() == ReservationStrategy.Start) : "What can I do for nics that are not allocated at start? "; nic.setBroadcastUri(network.getBroadcastUri()); @@ -385,7 +385,7 @@ public class GuestNetworkGuru extends AdapterBase implements NetworkGuru { profile.getPhysicalNetworkId(), profile.getAccountId(), profile.getReservationId()); EventUtils.saveEvent(UserContext.current().getCallerUserId(), profile.getAccountId(), EventVO.LEVEL_INFO, EventTypes.EVENT_ZONE_VLAN_RELEASE, "Released Zone Vlan: " - +profile.getBroadcastUri().getHost()+" for Network: "+profile.getId(), 0); + +profile.getBroadcastUri().getHost()+" for Network: "+profile.getId(), 0); profile.setBroadcastUri(null); } } diff --git a/server/src/com/cloud/network/guru/PrivateNetworkGuru.java b/server/src/com/cloud/network/guru/PrivateNetworkGuru.java index 0546f23e848..799e9bcdaa7 100644 --- a/server/src/com/cloud/network/guru/PrivateNetworkGuru.java +++ b/server/src/com/cloud/network/guru/PrivateNetworkGuru.java @@ -21,7 +21,6 @@ import com.cloud.dc.DataCenter; import com.cloud.dc.DataCenter.NetworkType; import com.cloud.deploy.DeployDestination; import com.cloud.deploy.DeploymentPlan; -import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientAddressCapacityException; import com.cloud.exception.InsufficientVirtualNetworkCapcityException; import com.cloud.exception.InvalidParameterValueException; @@ -60,7 +59,7 @@ public class PrivateNetworkGuru extends AdapterBase implements NetworkGuru { protected PrivateIpDao _privateIpDao; @Inject protected NetworkManager _networkMgr; - + private static final TrafficType[] _trafficTypes = {TrafficType.Guest}; protected PrivateNetworkGuru() { @@ -106,14 +105,14 @@ public class PrivateNetworkGuru extends AdapterBase implements NetworkGuru { if (userSpecified != null) { if ((userSpecified.getCidr() == null && userSpecified.getGateway() != null) || (userSpecified.getCidr() != null && userSpecified.getGateway() == null)) { - throw new InvalidParameterValueException("cidr and gateway must be specified together."); + throw new InvalidParameterValueException("cidr and gateway must be specified together.", null); } if (userSpecified.getCidr() != null) { network.setCidr(userSpecified.getCidr()); network.setGateway(userSpecified.getGateway()); } else { - throw new InvalidParameterValueException("Can't design network " + network + "; netmask/gateway must be passed in"); + throw new InvalidParameterValueException("Can't design network " + network + "; netmask/gateway must be passed in", null); } if (offering.getSpecifyVlan()) { @@ -122,7 +121,7 @@ public class PrivateNetworkGuru extends AdapterBase implements NetworkGuru { } } else { throw new CloudRuntimeException("Can't design network " + network + "; netmask/gateway must be passed in"); - + } return network; @@ -133,19 +132,19 @@ public class PrivateNetworkGuru extends AdapterBase implements NetworkGuru { if (s_logger.isDebugEnabled()) { s_logger.debug("Deallocate network: networkId: " + nic.getNetworkId() + ", ip: " + nic.getIp4Address()); } - + PrivateIpVO ip = _privateIpDao.findByIpAndSourceNetworkId(nic.getNetworkId(), nic.getIp4Address()); if (ip != null) { _privateIpDao.releaseIpAddress(nic.getIp4Address(), nic.getNetworkId()); } nic.deallocate(); } - - + + @Override public Network implement(Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context) throws InsufficientVirtualNetworkCapcityException { - + return network; } @@ -157,11 +156,11 @@ public class PrivateNetworkGuru extends AdapterBase implements NetworkGuru { if (!canHandle(offering, dc)) { return null; } - + if (nic == null) { nic = new NicProfile(ReservationStrategy.Create, null, null, null, null); } - + getIp(nic, dc, network); if (nic.getIp4Address() == null) { @@ -172,8 +171,8 @@ public class PrivateNetworkGuru extends AdapterBase implements NetworkGuru { return nic; } - - + + protected void getIp(NicProfile nic, DataCenter dc, Network network) throws InsufficientVirtualNetworkCapcityException,InsufficientAddressCapacityException { if (nic.getIp4Address() == null) { @@ -196,7 +195,7 @@ public class PrivateNetworkGuru extends AdapterBase implements NetworkGuru { nic.setDns1(dc.getDns1()); nic.setDns2(dc.getDns2()); } - + @Override public void updateNicProfile(NicProfile profile, Network network) { @@ -210,7 +209,7 @@ public class PrivateNetworkGuru extends AdapterBase implements NetworkGuru { @Override public void reserve(NicProfile nic, Network network, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) - throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException { + throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException { if (nic.getIp4Address() == null) { getIp(nic, _configMgr.getZone(network.getDataCenterId()), network); nic.setStrategy(ReservationStrategy.Create); @@ -224,7 +223,7 @@ public class PrivateNetworkGuru extends AdapterBase implements NetworkGuru { @Override public void shutdown(NetworkProfile profile, NetworkOffering offering) { - + } @Override