| //Licensed to the Apache Software Foundation (ASF) under one |
| //or more contributor license agreements. See the NOTICE file |
| //distributed with this work for additional information |
| //regarding copyright ownership. The ASF licenses this file |
| //to you under the Apache License, Version 2.0 (the |
| //"License"); you may not use this file except in compliance |
| //with the License. You may obtain a copy of the License at |
| // |
| //http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| //Unless required by applicable law or agreed to in writing, |
| //software distributed under the License is distributed on an |
| //"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| //KIND, either express or implied. See the License for the |
| //specific language governing permissions and limitations |
| //under the License. |
| package com.cloud.network.vm; |
| |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.HashMap; |
| import java.util.LinkedHashMap; |
| import java.util.List; |
| import java.util.Map; |
| |
| import javax.inject.Inject; |
| import javax.naming.ConfigurationException; |
| |
| import org.apache.cloudstack.context.CallContext; |
| import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService; |
| import org.apache.cloudstack.framework.config.dao.ConfigurationDao; |
| import org.apache.cloudstack.lb.dao.ApplicationLoadBalancerRuleDao; |
| import org.apache.log4j.Logger; |
| |
| import com.cloud.agent.AgentManager; |
| import com.cloud.agent.api.Answer; |
| import com.cloud.agent.manager.Commands; |
| import com.cloud.api.commands.DeployNetscalerVpxCmd; |
| import com.cloud.dc.DataCenter; |
| import com.cloud.dc.DataCenter.NetworkType; |
| import com.cloud.dc.DataCenterVO; |
| import com.cloud.dc.VlanVO; |
| import com.cloud.dc.dao.DataCenterDao; |
| import com.cloud.dc.dao.VlanDao; |
| import com.cloud.deploy.DataCenterDeployment; |
| import com.cloud.deploy.DeployDestination; |
| import com.cloud.deploy.DeploymentPlan; |
| import com.cloud.exception.ConcurrentOperationException; |
| import com.cloud.exception.InsufficientCapacityException; |
| import com.cloud.exception.InvalidParameterValueException; |
| import com.cloud.exception.OperationTimedoutException; |
| import com.cloud.exception.ResourceUnavailableException; |
| import com.cloud.exception.StorageUnavailableException; |
| import com.cloud.network.IpAddressManager; |
| import com.cloud.network.Network; |
| import com.cloud.network.Network.Provider; |
| import com.cloud.network.NetworkModel; |
| import com.cloud.network.Networks.TrafficType; |
| import com.cloud.network.PhysicalNetwork; |
| import com.cloud.network.PhysicalNetworkServiceProvider; |
| import com.cloud.network.VirtualRouterProvider; |
| import com.cloud.network.dao.NetworkDao; |
| import com.cloud.network.dao.NetworkVO; |
| import com.cloud.network.dao.PhysicalNetworkDao; |
| import com.cloud.network.dao.PhysicalNetworkServiceProviderDao; |
| import com.cloud.network.dao.VirtualRouterProviderDao; |
| import com.cloud.network.element.VirtualRouterProviderVO; |
| import com.cloud.network.lb.LoadBalancingRulesManager; |
| import com.cloud.network.router.VirtualRouter; |
| import com.cloud.network.router.VirtualRouter.RedundantState; |
| import com.cloud.network.router.VirtualRouter.Role; |
| import com.cloud.offering.NetworkOffering; |
| import com.cloud.offerings.dao.NetworkOfferingDao; |
| import com.cloud.resource.ResourceManager; |
| import com.cloud.service.ServiceOfferingVO; |
| import com.cloud.service.dao.ServiceOfferingDao; |
| import com.cloud.storage.VMTemplateVO; |
| import com.cloud.storage.dao.VMTemplateDao; |
| import com.cloud.user.Account; |
| import com.cloud.user.AccountManager; |
| import com.cloud.utils.component.ManagerBase; |
| import com.cloud.utils.exception.CloudRuntimeException; |
| import com.cloud.vm.DomainRouterVO; |
| import com.cloud.vm.NicProfile; |
| import com.cloud.vm.ReservationContext; |
| import com.cloud.vm.VMInstanceVO; |
| import com.cloud.vm.VirtualMachine; |
| import com.cloud.vm.VirtualMachineGuru; |
| import com.cloud.vm.VirtualMachineManager; |
| import com.cloud.vm.VirtualMachineName; |
| import com.cloud.vm.VirtualMachineProfile; |
| import com.cloud.vm.VirtualMachineProfile.Param; |
| import com.cloud.vm.dao.DomainRouterDao; |
| import com.cloud.vm.dao.NicDao; |
| import com.cloud.vm.dao.VMInstanceDao; |
| |
| public class NetScalerVMManagerImpl extends ManagerBase implements NetScalerVMManager, VirtualMachineGuru { |
| private static final Logger s_logger = Logger.getLogger(NetScalerVMManagerImpl.class); |
| static final private String NetScalerLbVmNamePrefix = "NS"; |
| |
| @Inject |
| IpAddressManager _ipAddrMgr; |
| @Inject |
| VirtualMachineManager _itMgr; |
| @Inject |
| DomainRouterDao _internalLbVmDao; |
| @Inject |
| ConfigurationDao _configDao; |
| @Inject |
| AgentManager _agentMgr; |
| @Inject |
| DataCenterDao _dcDao; |
| @Inject |
| VirtualRouterProviderDao _vrProviderDao; |
| @Inject |
| ApplicationLoadBalancerRuleDao _lbDao; |
| @Inject |
| NetworkModel _ntwkModel; |
| @Inject |
| LoadBalancingRulesManager _lbMgr; |
| @Inject |
| NicDao _nicDao; |
| @Inject |
| AccountManager _accountMgr; |
| @Inject |
| NetworkDao _networkDao; |
| @Inject |
| NetworkOrchestrationService _networkMgr; |
| @Inject |
| ServiceOfferingDao _serviceOfferingDao; |
| @Inject |
| PhysicalNetworkServiceProviderDao _physicalProviderDao; |
| @Inject |
| NetworkOfferingDao _networkOfferingDao; |
| @Inject |
| VMTemplateDao _templateDao; |
| @Inject |
| ResourceManager _resourceMgr; |
| @Inject |
| VMInstanceDao _vmDao; |
| @Inject |
| NetworkModel _networkModel; |
| @Inject |
| PhysicalNetworkDao _physicalNetworkDao; |
| @Inject |
| VlanDao _vlanDao; |
| @Inject |
| DomainRouterDao _routerDao; |
| |
| @Override |
| public boolean finalizeVirtualMachineProfile(VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) { |
| //NetScalerLB vm starts up with 3 Nics |
| //Nic #1 - NS IP |
| //Nic #2 - locallink(guest network) |
| //Nic #3 - public nic |
| |
| for (final NicProfile nic : profile.getNics()) { |
| if(nic.getTrafficType() == TrafficType.Control) { |
| nic.setTrafficType(TrafficType.Guest); |
| } |
| } |
| return true; |
| } |
| |
| @Override |
| public boolean finalizeDeployment(Commands cmds, VirtualMachineProfile profile, DeployDestination dest, ReservationContext context) throws ResourceUnavailableException { |
| return true; |
| } |
| |
| @Override |
| public boolean finalizeStart(VirtualMachineProfile profile, long hostId, Commands cmds, ReservationContext context) { |
| return true; |
| } |
| |
| @Override |
| public boolean finalizeCommandsOnStart(Commands cmds, VirtualMachineProfile profile) { |
| return true; |
| } |
| |
| @Override |
| public void finalizeStop(VirtualMachineProfile profile, Answer answer) { |
| } |
| |
| @Override |
| public void finalizeExpunge(VirtualMachine vm) { |
| } |
| |
| @Override |
| public void prepareStop(VirtualMachineProfile profile) { |
| } |
| |
| @Override |
| public boolean configure(String name, Map<String, Object> params) throws ConfigurationException { |
| _itMgr.registerGuru(VirtualMachine.Type.NetScalerVm, this); |
| if (s_logger.isInfoEnabled()) { |
| s_logger.info(getName() + " has been configured"); |
| } |
| return true; |
| } |
| |
| @Override |
| public String getName() { |
| return _name; |
| } |
| |
| protected VirtualRouter stopInternalLbVm(DomainRouterVO internalLbVm, boolean forced, Account caller, long callerUserId) throws ResourceUnavailableException, ConcurrentOperationException { |
| s_logger.debug("Stopping internal lb vm " + internalLbVm); |
| try { |
| _itMgr.advanceStop(internalLbVm.getUuid(), forced); |
| return _internalLbVmDao.findById(internalLbVm.getId()); |
| } catch (OperationTimedoutException e) { |
| throw new CloudRuntimeException("Unable to stop " + internalLbVm, e); |
| } |
| } |
| |
| public VirtualRouterProvider addNetScalerLoadBalancerElement(long ntwkSvcProviderId) { |
| VirtualRouterProviderVO element = _vrProviderDao.findByNspIdAndType(ntwkSvcProviderId, com.cloud.network.VirtualRouterProvider.Type.NetScalerVm); |
| if (element != null) { |
| s_logger.debug("There is already an " + getName() + " with service provider id " + ntwkSvcProviderId); |
| return element; |
| } |
| |
| PhysicalNetworkServiceProvider provider = _physicalProviderDao.findById(ntwkSvcProviderId); |
| if (provider == null || !provider.getProviderName().equalsIgnoreCase(getName())) { |
| throw new InvalidParameterValueException("Invalid network service provider is specified"); |
| } |
| |
| element = new VirtualRouterProviderVO(ntwkSvcProviderId, com.cloud.network.VirtualRouterProvider.Type.NetScalerVm); |
| element.setEnabled(true); |
| element = _vrProviderDao.persist(element); |
| return element; |
| } |
| |
| protected long getNetScalerLbProviderId(long physicalNetworkId) { |
| //final long physicalNetworkId = _ntwkModel.getPhysicalNetworkId(guestNetwork); |
| |
| final PhysicalNetworkServiceProvider provider = _physicalProviderDao.findByServiceProvider(physicalNetworkId, "Netscaler"); |
| if (provider == null) { |
| throw new CloudRuntimeException("Cannot find service provider " + Provider.Netscaler.toString() + " in physical network " + physicalNetworkId); |
| } |
| |
| //TODO: get from type |
| VirtualRouterProvider netScalerLbProvider = _vrProviderDao.findByNspIdAndType(provider.getId(), com.cloud.network.VirtualRouterProvider.Type.NetScalerVm); |
| if (netScalerLbProvider == null) { |
| //create the vrp for netscalerVM. |
| netScalerLbProvider = addNetScalerLoadBalancerElement(provider.getId()); |
| } |
| |
| return netScalerLbProvider.getId(); |
| } |
| |
| @Override |
| public Map<String, Object> deployNsVpx(Account owner, DeployDestination dest, DeploymentPlan plan, long svcOffId, long templateId) throws InsufficientCapacityException { |
| |
| VMTemplateVO template = _templateDao.findById(templateId) ; |
| long id = _vmDao.getNextInSequence(Long.class, "id"); |
| Account systemAcct = _accountMgr.getSystemAccount(); |
| |
| if (template == null) { |
| s_logger.error(" Unable to find the NS VPX template"); |
| throw new CloudRuntimeException("Unable to find the Template" + templateId); |
| } |
| long dataCenterId = dest.getDataCenter().getId(); |
| DataCenterVO dc = _dcDao.findById(dest.getDataCenter().getId()); |
| |
| String nxVpxName = VirtualMachineName.getSystemVmName(id, "Vpx", NetScalerLbVmNamePrefix); |
| |
| ServiceOfferingVO vpxOffering = _serviceOfferingDao.findById(svcOffId); //using 2GB and 2CPU offering |
| if(vpxOffering.getRamSize() < 2048 && vpxOffering.getCpu() <2 ) { |
| throw new InvalidParameterValueException("Specified Service Offering :" + vpxOffering.getUuid() + " NS Vpx cannot be deployed. Min 2GB Ram and 2 CPU are required"); |
| } |
| |
| long userId = CallContext.current().getCallingUserId(); |
| //TODO change the os bits from 142 103 to the actual guest of bits |
| if(template.getGuestOSId() != 103 ) { |
| throw new InvalidParameterValueException("Specified Template " + template.getUuid()+ " not suitable for NS VPX Deployment. Please register the template with guest os type as unknow(64-bit)"); |
| } |
| |
| NetworkVO defaultNetwork = null; |
| NetworkVO defaultPublicNetwork = null; |
| if (dc.getNetworkType() == NetworkType.Advanced && dc.isSecurityGroupEnabled()) { |
| List<NetworkVO> networks = _networkDao.listByZoneSecurityGroup(dataCenterId); |
| if (networks == null || networks.size() == 0) { |
| throw new CloudRuntimeException("Can not found security enabled network in SG Zone " + dc); |
| } |
| defaultNetwork = networks.get(0); |
| } else { |
| TrafficType defaultTrafficType = TrafficType.Management; |
| List<NetworkVO> defaultNetworks = _networkDao.listByZoneAndTrafficType(dataCenterId, defaultTrafficType); |
| |
| TrafficType publicTrafficType = TrafficType.Public; |
| List<NetworkVO> publicNetworks = _networkDao.listByZoneAndTrafficType(dataCenterId, publicTrafficType); |
| |
| // api should never allow this situation to happen |
| if (defaultNetworks.size() != 1) { |
| throw new CloudRuntimeException("Found " + defaultNetworks.size() + " networks of type " + defaultTrafficType + " when expect to find 1"); |
| } |
| |
| if (publicNetworks.size() != 1) { |
| throw new CloudRuntimeException("Found " + defaultNetworks.size() + " networks of type " + defaultTrafficType + " when expect to find 1"); |
| } |
| defaultPublicNetwork = publicNetworks.get(0); |
| defaultNetwork = defaultNetworks.get(0); |
| } |
| |
| LinkedHashMap<Network, List<? extends NicProfile>> networks = new LinkedHashMap<Network, List<? extends NicProfile>>(4); |
| NicProfile defaultNic = new NicProfile(); |
| defaultNic.setDefaultNic(true); |
| defaultNic.setDeviceId(0); |
| |
| networks.put(_networkMgr.setupNetwork(_accountMgr.getSystemAccount() , _networkOfferingDao.findById(defaultNetwork.getNetworkOfferingId()), plan, null, null, false).get(0), new ArrayList<NicProfile>()); |
| |
| NicProfile defaultNic1 = new NicProfile(); |
| defaultNic1.setDefaultNic(false); |
| defaultNic1.setDeviceId(1); |
| |
| NicProfile defaultNic2 = new NicProfile(); |
| defaultNic2.setDefaultNic(false); |
| defaultNic2.setDeviceId(2); |
| defaultNic2.setIPv4Address(""); |
| defaultNic2.setIPv4Gateway(""); |
| defaultNic2.setIPv4Netmask(""); |
| String macAddress = _networkDao.getNextAvailableMacAddress(defaultPublicNetwork.getId(), null); |
| defaultNic2.setMacAddress(macAddress); |
| |
| networks.put(_networkMgr.setupNetwork(_accountMgr.getSystemAccount(), _networkOfferingDao.findByUniqueName(NetworkOffering.SystemPublicNetwork), plan, null, null, false).get(0), |
| new ArrayList<NicProfile>(Arrays.asList(defaultNic2))); |
| |
| networks.put(_networkMgr.setupNetwork(_accountMgr.getSystemAccount(), _networkOfferingDao.findByUniqueName(NetworkOffering.SystemControlNetwork), plan, null, null, false).get(0), |
| new ArrayList<NicProfile>()); |
| |
| long physicalNetworkId = _networkModel.findPhysicalNetworkId(dataCenterId, _networkOfferingDao.findById(defaultPublicNetwork.getNetworkOfferingId()).getTags(), TrafficType.Public); |
| // Validate physical network |
| PhysicalNetwork physicalNetwork = _physicalNetworkDao.findById(physicalNetworkId); |
| if (physicalNetwork == null) { |
| throw new InvalidParameterValueException("Unable to find physical network with id: " + physicalNetworkId + " and tag: " |
| + _networkOfferingDao.findById(defaultPublicNetwork.getNetworkOfferingId()).getTags()); |
| } |
| String guestvnet = physicalNetwork.getVnetString(); |
| |
| final List<VlanVO> vlans = _vlanDao.listByZone(dataCenterId); |
| List<String> pvlan = new ArrayList<String>(); |
| for (final VlanVO vlan : vlans) { |
| pvlan.add(vlan.getVlanTag()); |
| } |
| |
| long netScalerProvider = getNetScalerLbProviderId(physicalNetworkId); |
| DomainRouterVO nsVpx = new DomainRouterVO(id, vpxOffering.getId(), netScalerProvider, nxVpxName, |
| template.getId(), template.getHypervisorType(), template.getGuestOSId(), owner.getDomainId(), owner.getId(), userId, false, RedundantState.UNKNOWN, false, |
| false, VirtualMachine.Type.NetScalerVm, null); |
| |
| nsVpx.setRole(Role.NETSCALER_VM); |
| |
| nsVpx = _routerDao.persist(nsVpx); |
| |
| VMInstanceVO vmVO= _vmDao.findVMByHostName(nxVpxName); |
| _itMgr.allocate(nxVpxName, template, vpxOffering, networks, plan, template.getHypervisorType()); |
| Map<Param, Object> params = new HashMap<VirtualMachineProfile.Param, Object>(1); |
| try { |
| if (vmVO != null) { |
| startNsVpx(vmVO, params); |
| } else { |
| throw new NullPointerException(); |
| } |
| } catch (StorageUnavailableException e) { |
| e.printStackTrace(); |
| } catch (ConcurrentOperationException e) { |
| e.printStackTrace(); |
| } catch (ResourceUnavailableException e) { |
| e.printStackTrace(); |
| } |
| vmVO= _vmDao.findByUuid(nsVpx.getUuid()); |
| Map<String, Object> deployResponse = new HashMap<String, Object>(); |
| deployResponse.put("vm", vmVO); |
| deployResponse.put("guestvlan", guestvnet); |
| deployResponse.put("publicvlan", pvlan); |
| |
| return deployResponse; |
| } |
| |
| protected void startNsVpx(VMInstanceVO nsVpx, Map<Param, Object> params) throws StorageUnavailableException, |
| InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException { |
| s_logger.debug("Starting NS Vpx " + nsVpx); |
| _itMgr.start(nsVpx.getUuid(), params, null, null); |
| } |
| |
| @Override |
| public Map<String,Object> deployNetscalerServiceVm(DeployNetscalerVpxCmd cmd) { |
| DataCenter zone = _dcDao.findById(cmd.getZoneId()); |
| DeployDestination dest = new DeployDestination(zone, null, null, null); |
| VMInstanceVO vmvo = null; |
| Map<String,Object> resp = new HashMap<String, Object>(); |
| Long templateId = cmd.getTemplateId(); |
| Long serviceOfferingId = cmd.getServiceOfferingId(); |
| DeploymentPlan plan = new DataCenterDeployment(dest.getDataCenter().getId()); |
| |
| try { |
| resp = deployNsVpx(cmd.getAccount(), dest, plan, serviceOfferingId, templateId); |
| } catch (InsufficientCapacityException e) { |
| e.printStackTrace(); |
| } |
| |
| return resp; |
| } |
| |
| protected VirtualRouter stopNetScalerVm(final long vmId, final boolean forced, final Account caller, final long callerUserId) throws ResourceUnavailableException, ConcurrentOperationException { |
| final DomainRouterVO netscalerVm = _routerDao.findById(vmId); |
| s_logger.debug("Stopping NetScaler vm " + netscalerVm); |
| |
| if (netscalerVm == null || netscalerVm.getRole() != Role.NETSCALER_VM) { |
| throw new InvalidParameterValueException("Can't find NetScaler vm by id specified"); |
| } |
| |
| _accountMgr.checkAccess(caller, null, true, netscalerVm); |
| |
| try { |
| _itMgr.expunge(netscalerVm.getUuid()); |
| return _routerDao.findById(netscalerVm.getId()); |
| } catch (final Exception e) { |
| throw new CloudRuntimeException("Unable to stop " + netscalerVm, e); |
| } |
| } |
| |
| @Override |
| public VirtualRouter stopNetscalerServiceVm(Long id, boolean forced, Account callingAccount, long callingUserId) throws ConcurrentOperationException, ResourceUnavailableException { |
| return stopNetScalerVm(id, forced, callingAccount, callingUserId); |
| } |
| |
| @Override |
| public VirtualRouter stopNetScalerVm(Long vmId, boolean forced, Account caller, long callingUserId) { |
| final DomainRouterVO netscalerVm = _routerDao.findById(vmId); |
| s_logger.debug("Stopping NetScaler vm " + netscalerVm); |
| |
| if (netscalerVm == null || netscalerVm.getRole() != Role.NETSCALER_VM) { |
| throw new InvalidParameterValueException("Can't find NetScaler vm by id specified"); |
| } |
| _accountMgr.checkAccess(caller, null, true, netscalerVm); |
| try { |
| _itMgr.expunge(netscalerVm.getUuid()); |
| return _routerDao.findById(netscalerVm.getId()); |
| } catch (final Exception e) { |
| throw new CloudRuntimeException("Unable to stop " + netscalerVm, e); |
| } |
| } |
| } |