/** * Abiquo community edition * cloud management application for hybrid clouds * Copyright (C) 2008-2010 - Abiquo Holdings S.L. * * This application is free software; you can redistribute it and/or * modify it under the terms of the GNU LESSER GENERAL PUBLIC * LICENSE as published by the Free Software Foundation under * version 3 of the License * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * LESSER GENERAL PUBLIC LICENSE v.3 for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */ package com.abiquo.api.services; import java.net.Inet4Address; import java.net.InetAddress; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import java.util.UUID; import javax.persistence.EntityManager; import org.hibernate.Hibernate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import com.abiquo.api.config.ConfigService; import com.abiquo.api.exceptions.APIError; import com.abiquo.api.services.cloud.VirtualMachineService; import com.abiquo.api.tracer.TracerLogger; import com.abiquo.model.enumerator.NetworkType; import com.abiquo.model.transport.LinksDto; import com.abiquo.model.transport.error.CommonError; import com.abiquo.server.core.cloud.VirtualAppliance; import com.abiquo.server.core.cloud.VirtualDatacenter; import com.abiquo.server.core.cloud.VirtualDatacenterRep; import com.abiquo.server.core.cloud.VirtualMachine; import com.abiquo.server.core.cloud.VirtualMachineState; import com.abiquo.server.core.enterprise.DatacenterLimits; import com.abiquo.server.core.enterprise.EnterpriseRep; import com.abiquo.server.core.infrastructure.Datacenter; import com.abiquo.server.core.infrastructure.InfrastructureRep; import com.abiquo.server.core.infrastructure.Machine; import com.abiquo.server.core.infrastructure.management.Rasd; import com.abiquo.server.core.infrastructure.network.DhcpOption; import com.abiquo.server.core.infrastructure.network.DhcpOptionDto; import com.abiquo.server.core.infrastructure.network.IpPoolManagement; import com.abiquo.server.core.infrastructure.network.NetworkConfiguration; import com.abiquo.server.core.infrastructure.network.VLANNetwork; import com.abiquo.server.core.infrastructure.network.VMNetworkConfiguration; import com.abiquo.server.core.util.network.IPAddress; import com.abiquo.server.core.util.network.IPNetworkRang; import com.abiquo.server.core.util.network.NetworkResolver; import com.abiquo.tracer.ComponentType; import com.abiquo.tracer.EventType; import com.abiquo.tracer.SeverityType; @Service public class NetworkService extends DefaultApiService { /** Static literal for 'FENCE_MODE' values. */ public static final String FENCE_MODE = "bridge"; /** Logger. */ private static final Logger LOGGER = LoggerFactory.getLogger(NetworkService.class); /** * Prepares the {@link Rasd} entity regarding on the virtual machine and the ip we are * assigning. It's up to the method that calls this entity either save the Rasd or not. * * @param vm {@link VirtualMachine} entity where the IP will belong to. * @param ip {@link IpPoolManagement} entity that will store this rasd. * @return the created Rasd entity. */ public static Rasd createRasdEntity(final VirtualMachine vm, final IpPoolManagement ip) { // create the Rasd object. Rasd rasd = new Rasd(UUID.randomUUID().toString(), IpPoolManagement.DEFAULT_RESOURCE_NAME, Integer.valueOf(IpPoolManagement.DISCRIMINATOR)); rasd.setDescription(IpPoolManagement.DEFAULT_RESOURCE_DESCRIPTION); rasd.setConnection(""); rasd.setAllocationUnits("0"); rasd.setAutomaticAllocation(0); rasd.setAutomaticDeallocation(0); rasd.setAddress(ip.getMac()); rasd.setParent(ip.getNetworkName()); rasd.setResourceSubType(String.valueOf(defineIpType(ip.getVlanNetwork()).ordinal())); return rasd; } private static IpPoolManagement.Type defineIpType(final VLANNetwork vlan) { switch (vlan.getType()) { case INTERNAL: return IpPoolManagement.Type.PRIVATE; case PUBLIC: return IpPoolManagement.Type.PUBLIC; case EXTERNAL: return IpPoolManagement.Type.EXTERNAL; default: return IpPoolManagement.Type.UNMANAGED; } } /** Autowired infrastructure DAO repository. */ @Autowired protected InfrastructureRep datacenterRepo; @Autowired protected EnterpriseRep entRep; /** Autowired Virtual Infrastructure DAO repository. */ @Autowired protected VirtualDatacenterRep repo; /** Autowired tracer logger. */ @Autowired protected TracerLogger tracer; /** User service for user-specific privileges */ @Autowired protected UserService userService; @Autowired protected VirtualMachineService vmService; /** * Default constructor. Needed by @Autowired injections */ public NetworkService() { } /** * Auxiliar constructor for test purposes. Haters gonna hate 'bzengine'. And his creator as * well... * * @param em {@link EntityManager} instance with active transaction. */ public NetworkService(final EntityManager em) { repo = new VirtualDatacenterRep(em); datacenterRepo = new InfrastructureRep(em); userService = new UserService(em); // TODO initialize the tracer } @Transactional(readOnly = false, propagation = Propagation.REQUIRED) public DhcpOption addDhcpOption(final DhcpOptionDto dto) { DhcpOption opt = new DhcpOption(dto.getOption(), dto.getGateway(), dto.getNetworkAddress(), dto.getMask(), dto.getNetmask()); if (!opt.isValid()) { addValidationErrors(opt.getValidationErrors()); flushErrors(); } datacenterRepo.insertDhcpOption(opt); return opt; } /** * Assign the default NIC to a Virtual Machine. Depending on which vlan type is, we should do an * action, or another one. This method will be only called from another services, so we * understand we don't have to check the NotFound case. * * @param vmId identifier of the Virtual Machine. */ public void assignDefaultNICToVirtualMachine(final Integer vmId) { // Get the needed objects. VirtualMachine vm = repo.findVirtualMachineById(vmId); VirtualAppliance vapp = repo.findVirtualApplianceByVirtualMachine(vm); VirtualDatacenter vdc = vapp.getVirtualDatacenter(); VLANNetwork vlan = vdc.getDefaultVlan(); IpPoolManagement ip = null; switch (vlan.getType()) { case INTERNAL: // find next available IP to use. ip = repo.findNextIpAvailable(vlan.getId(), vlan.getConfiguration().getGateway()); break; case UNMANAGED: ip = new IpPoolManagement(vlan, "?", "?", "?", vlan.getName()); ip.setVirtualDatacenter(vdc); ip.setMac(IPNetworkRang.requestRandomMacAddress(vdc.getHypervisorType())); ip.setName(ip.getMac() + "_host"); repo.insertIpManagement(ip); break; default: ip = repo.findNextExternalIpAvailable(vlan.getId(), vlan.getConfiguration() .getGateway()); ip.setVirtualDatacenter(vdc); ip.setMac(IPNetworkRang.requestRandomMacAddress(vdc.getHypervisorType())); ip.setName(ip.getMac() + "_host"); } Rasd rasd = createRasdEntity(vm, ip); repo.insertRasd(rasd); ip.setRasd(rasd); ip.attach(0, vm, vapp); repo.updateIpManagement(ip); vm.setNetworkConfiguration(vlan.getConfiguration()); repo.updateVirtualMachine(vm); return; } /** * Attach a list of NICs to a virtual machine. * <p> * If the virtual machine is not deployed, the method simply returns <code>null</code>. If the * virtual machine is deployed, the attachment will run a reconfigure operation and this method * will return the identifier of the task object associated to the reconfigure operation. * * @param vdcId identifier of the virtual datacenter. * @param vappId identifier of the virtual appliance * @param vmId identifier of the virtual machine * @param nicRefs list of links to disks to attach. * @return The id of the Tarantino task if the virtual machine is deployed, <code>null</code> * otherwise. */ @Transactional(readOnly = false, propagation = Propagation.REQUIRED) public Object attachNICs(final Integer vdcId, final Integer vappId, final Integer vmId, final LinksDto nicRefs, final VirtualMachineState originalState) { VirtualDatacenter vdc = getVirtualDatacenter(vdcId); VirtualAppliance vapp = getVirtualAppliance(vdc, vappId); VirtualMachine oldvm = getVirtualMachine(vapp, vmId); VirtualMachine newvm = vmService.duplicateVirtualMachineObject(oldvm); List<IpPoolManagement> ips = vmService.getNICsFromDto(vdc, nicRefs); if (0 == ips.size()) { addValidationErrors(APIError.VIRTUAL_MACHINE_AT_LEAST_ONE_NIC_SHOULD_BE_LINKED); flushErrors(); } checkIps(ips); newvm.getIps().addAll(ips); return vmService.reconfigureVirtualMachine(vdc, vapp, oldvm, newvm, originalState); } private void checkIps(final List<IpPoolManagement> ips) { for (IpPoolManagement ip : ips) { if (ip.getQuarantine()) { LOGGER.debug("Cannot attach ip " + ip.toString() + " to a virtual machine because the ip is in quarantine"); addConflictErrors(new CommonError(APIError.VLANS_IP_IS_IN_QUARANTINE.getCode(), String.format(APIError.VLANS_IP_IS_IN_QUARANTINE.getMessage(), ip.getIp()))); flushErrors(); } } } /** * Change the default network configuration of a virtual machine. * <p> * If the virtual machine is not deployed, the method simply returns <code>null</code>. If the * virtual machine is deployed, the attachment will run a reconfigure operation and this method * will return the identifier of the task object associated to the reconfigure operation. If the @param * configurationRef is an empty list, we will set no network configuration to this machine. * Stupid behavior, but we allow it. * * @param vdcId identifier of the virtual datacenter. * @param vappId identifier of the virtual appliance * @param vmId identifier of the virtual machine * @param configurationRef the link to the available configuration. * @return The id of the Tarantino task if the virtual machine is deployed, <code>null</code> * otherwise. */ @Transactional(readOnly = false, propagation = Propagation.REQUIRED) public Object changeNetworkConfiguration(final Integer vdcId, final Integer vappId, final Integer vmId, final LinksDto configurationRef, final VirtualMachineState originalState) { VirtualDatacenter vdc = getVirtualDatacenter(vdcId); VirtualAppliance vapp = getVirtualAppliance(vdc, vappId); VirtualMachine oldvm = getVirtualMachine(vapp, vmId); VirtualMachine newvm = vmService.duplicateVirtualMachineObject(oldvm); NetworkConfiguration netconf = vmService.getNetworkConfigurationFromDto(vapp, newvm, configurationRef); newvm.setNetworkConfiguration(netconf); return vmService.reconfigureVirtualMachine(vdc, vapp, oldvm, newvm, originalState); } /** * Change the list of NICs to a virtual machine. * <p> * If the virtual machine is not deployed, the method simply returns <code>null</code>. If the * virtual machine is deployed, the attachment will run a reconfigure operation and this method * will return the identifier of the task object associated to the reconfigure operation. * * @param vdcId identifier of the virtual datacenter. * @param vappId identifier of the virtual appliance * @param vmId identifier of the virtual machine * @param nicRefs list of links to disks to attach. * @return The id of the Tarantino task if the virtual machine is deployed, <code>null</code> * otherwise. */ @Transactional(readOnly = false, propagation = Propagation.REQUIRED) public Object changeNICs(final Integer vdcId, final Integer vappId, final Integer vmId, final LinksDto nicRefs, final VirtualMachineState originalState) { VirtualDatacenter vdc = getVirtualDatacenter(vdcId); VirtualAppliance vapp = getVirtualAppliance(vdc, vappId); VirtualMachine oldvm = getVirtualMachine(vapp, vmId); VirtualMachine newvm = vmService.duplicateVirtualMachineObject(oldvm); List<IpPoolManagement> ips = vmService.getNICsFromDto(vdc, nicRefs); if (0 == ips.size()) { addValidationErrors(APIError.VIRTUAL_MACHINE_AT_LEAST_ONE_NIC_SHOULD_BE_LINKED); flushErrors(); } newvm.setIps(ips); return vmService.reconfigureVirtualMachine(vdc, vapp, oldvm, newvm, originalState); } /** * Creates a new Private Network. * * @param virtualDatacenterId Identifier of the Virtual Datacenter * @param newVlan {@link VLANNetwork} object with the new parameters to create. * @return the created {@link VLANNetwork} object. */ @Transactional(readOnly = false, propagation = Propagation.REQUIRED) public VLANNetwork createPrivateNetwork(final Integer vdcId, final VLANNetwork newVlan, final Boolean defaultVlan) { VirtualDatacenter virtualDatacenter = getVirtualDatacenter(vdcId); newVlan.setNetwork(virtualDatacenter.getNetwork()); newVlan.setType(NetworkType.INTERNAL); validate(newVlan); validate(newVlan.getConfiguration()); // The user has the role for manage This. But... is the user from the same enterprise // than Virtual Datacenter? userService.checkCurrentEnterpriseForPostMethods(virtualDatacenter.getEnterprise()); // check if we have reached the maximum number of VLANs for this virtualdatacenter checkNumberOfCurrentVLANs(virtualDatacenter); // check if we have a vlan with the same name in the VirtualDatacenter if (repo.existAnyVlanWithName(virtualDatacenter.getNetwork(), newVlan.getName())) { addConflictErrors(APIError.VLANS_DUPLICATED_VLAN_NAME_VDC); flushErrors(); } // once we have validated we have IPs in all IP parameters (isValid() method), we should // ensure they are // actually PRIVATE IPs. Also check if the gateway is in the range, and checkAddressAndMaskCoherency( IPAddress.newIPAddress(newVlan.getConfiguration().getAddress()), newVlan .getConfiguration().getMask()); List<DhcpOption> opts = new ArrayList<DhcpOption>(newVlan.getDhcpOption()); for (DhcpOption dhcpOption : newVlan.getDhcpOption()) { dhcpOption.setOption(121); dhcpOption.setMask(getMaskbyNetMask(dhcpOption.getNetmask())); if (dhcpOption.getMask() != 0) { datacenterRepo.insertDhcpOption(dhcpOption); DhcpOption dhcpOption2 = new DhcpOption(249, dhcpOption.getGateway(), dhcpOption.getNetworkAddress(), dhcpOption.getMask(), dhcpOption.getNetmask()); datacenterRepo.insertDhcpOption(dhcpOption2); opts.add(dhcpOption2); } else { opts.remove(dhcpOption); } } newVlan.setDhcpOption(opts); // Before to insert the new VLAN, check if we want the vlan as the default one. If it is, // put the previous default one as non-default. repo.insertNetworkConfig(newVlan.getConfiguration()); repo.insertVlan(newVlan); // Calculate all the IPs of the VLAN and generate the DHCP entity that stores these IPs Collection<IPAddress> range = IPNetworkRang.calculateWholeRange(IPAddress.newIPAddress(newVlan.getConfiguration() .getAddress()), newVlan.getConfiguration().getMask()); if (!IPAddress.isIntoRange(range, newVlan.getConfiguration().getGateway())) { addValidationErrors(APIError.VLANS_GATEWAY_OUT_OF_RANGE); flushErrors(); } // store the dhcp and all the ips. storeIPs(virtualDatacenter.getDatacenter(), virtualDatacenter, newVlan, range); // Trace if (tracer != null) { tracer.log(SeverityType.INFO, ComponentType.NETWORK, EventType.VLAN_CREATED, "privateVlan.created", newVlan.getName(), virtualDatacenter.getName()); } if (defaultVlan != null && defaultVlan == true) { setInternalNetworkAsDefaultInVirtualDatacenter(vdcId, newVlan.getId()); } return newVlan; } /** * Delete a VLAN identified by its Virtual Datacenter id and its VLAN id * * @param vdcId identifier of the virtual datacenter. * @param vlanId identifier of the VLAN. */ @Transactional(readOnly = false, propagation = Propagation.REQUIRED) public void deletePrivateNetwork(final Integer vdcId, final Integer vlanId) { VLANNetwork vlanToDelete = getPrivateNetwork(vdcId, vlanId); VirtualDatacenter vdc = getVirtualDatacenter(vdcId); // Check input parameters existence if (repo.findVlansByVirtualDatacener(vdc).size() == 1) { addConflictErrors(APIError.VIRTUAL_DATACENTER_MUST_HAVE_NETWORK); flushErrors(); } if (vdc.getDefaultVlan().getId().equals(vlanToDelete.getId())) { addConflictErrors(APIError.VLANS_DEFAULT_NETWORK_CAN_NOT_BE_DELETED); flushErrors(); } if (repo.findUsedIpsByPrivateVLAN(vdcId, vlanId).size() != 0) { addConflictErrors(APIError.VLANS_WITH_USED_IPS_CAN_NOT_BE_DELETED); flushErrors(); } if (repo.isDefaultNetworkofanyVDC(vlanId)) { addConflictErrors(APIError.VLANS_CANNOT_DELETE_DEFAULT); flushErrors(); } // The user has the role for manage This. But... is the user from the same enterprise // than Virtual Datacenter? userService.checkCurrentEnterpriseForPostMethods(vdc.getEnterprise()); repo.deleteVLAN(vlanToDelete); datacenterRepo.deleteAllDhcpOption(vlanToDelete.getDhcpOption()); if (tracer != null) { tracer.log(SeverityType.INFO, ComponentType.NETWORK, EventType.VLAN_DELETED, "privateVlan.deleted", vlanToDelete.getName()); } } /** * Detach all the list of NICs from a Virtual Machine. * <p> * If the virtual machine is not deployed, the method simply returns <code>null</code>. If the * virtual machine is deployed, the detachment will run a reconfigure operation and this method * will return the identifier of the task object associated to the reconfigure operation. * * @param vdcId identifier of the virtual datacenter. * @param vappId identifier of the virtual appliance * @param vmId identifier of the virtual machine * @return The id of the Tarantino task if the virtual machine is deployed, <code>null</code> * otherwise. */ @Transactional(readOnly = false, propagation = Propagation.REQUIRED) public Object detachNIC(final Integer vdcId, final Integer vappId, final Integer vmId, final Integer nicId, final VirtualMachineState originalState) { VirtualDatacenter vdc = getVirtualDatacenter(vdcId); VirtualAppliance vapp = getVirtualAppliance(vdc, vappId); VirtualMachine vm = getVirtualMachine(vapp, vmId); List<IpPoolManagement> ips = repo.findIpsByVirtualMachine(vm); if (ips.size() == 1) { addConflictErrors(APIError.VLANS_CAN_NOT_DETACH_LAST_NIC); flushErrors(); } IpPoolManagement ipToDetach = repo.findIpByVirtualMachine(vm, nicId); if (ipToDetach == null) { addNotFoundErrors(APIError.NON_EXISTENT_IP); flushErrors(); } VirtualMachine newVm = vmService.duplicateVirtualMachineObject(vm); Iterator<IpPoolManagement> ipIterator = newVm.getIps().iterator(); while (ipIterator.hasNext()) { IpPoolManagement currentIp = ipIterator.next(); if (currentIp.getRasd().equals(ipToDetach.getRasd())) { ipIterator.remove(); return vmService.reconfigureVirtualMachine(vdc, vapp, vm, newVm, originalState); } } addUnexpectedErrors(APIError.NON_EXISTENT_IP); flushErrors(); return null; } public Collection<DhcpOption> findAllDhcpOptions() { return datacenterRepo.findAllDhcp(); } /** * Get the default network for virtual datacenter. * * @param id identifier of the virtual datacenter * @return the requested {@link VLANNetwork} */ @Transactional(readOnly = true, propagation = Propagation.REQUIRED) public VLANNetwork getDefaultNetworkForVirtualDatacenter(final Integer vdcId) { VirtualDatacenter vdc = getVirtualDatacenter(vdcId); if (vdc.getDefaultVlan() == null) { addUnexpectedErrors(APIError.VLANS_VIRTUAL_DATACENTER_SHOULD_HAVE_A_DEFAULT_VLAN); flushErrors(); } LOGGER.debug("Returning the default network used by Virtual Datacenter '" + vdc.getName() + "'."); return vdc.getDefaultVlan(); } public DhcpOption getDhcpOption(final Integer id) { DhcpOption option = datacenterRepo.findDhcpOptionById(id); if (option == null) { addNotFoundErrors(APIError.NON_EXISTENT_DHCP_OPTION); flushErrors(); } return option; } /** * Asks for an IP managed by a Virtual Virtual Machine. * * @param vdcId identifier of the Virtual Datacenter. * @param vappId identifier of the Virtual Appliance. * @param vmId identifier of the Virtual Machine. * @param nicId identifier of the IP to return * @return the list of matching elements. */ @Transactional(readOnly = true, propagation = Propagation.REQUIRED) public IpPoolManagement getIpPoolManagementByVirtualMachine(final Integer vdcId, final Integer vappId, final Integer vmId, final Integer nicId) { VirtualDatacenter vdc = getVirtualDatacenter(vdcId); VirtualAppliance vapp = getVirtualAppliance(vdc, vappId); VirtualMachine vm = getVirtualMachine(vapp, vmId); IpPoolManagement ip = repo.findIpByVirtualMachine(vm, nicId); if (ip == null) { addNotFoundErrors(APIError.NON_EXISTENT_IP); flushErrors(); } if (ip.getVlanNetwork().getEnterprise() != null) { // needed for REST links. DatacenterLimits dl = datacenterRepo.findDatacenterLimits(ip.getVlanNetwork().getEnterprise(), vdc.getDatacenter()); ip.getVlanNetwork().setLimitId(dl.getId()); } LOGGER.debug("Returning the list of IPs used by Virtual Machine '" + vm.getName() + "'."); return ip; } /** * Retrieve a private IP object. * * @param vdcId identifier of the {@link VirtualDatacenter} * @param vlanId identifier of the {@link VLANNetwork} * @param ipId identifier of the {@link IpPoolManagement} object to retrieve. * @return the found object. */ public IpPoolManagement getIpPoolManagementByVlan(final Integer vdcId, final Integer vlanId, final Integer ipId) { VirtualDatacenter vdc = getVirtualDatacenter(vdcId); VLANNetwork vlan = getPrivateVlan(vdc, vlanId); IpPoolManagement ip = repo.findIp(vlan, ipId); if (ip == null) { addNotFoundErrors(APIError.NON_EXISTENT_IP); flushErrors(); } LOGGER.debug("Returning the private Ip Address with id '" + ip.getId() + "'."); return ip; } /** * Asks for all the Private IPs managed by an Enterprise. * * @param entId identifier of the Enterprise. * @param firstElem first element to retrieve. * @param numElem number of elements to retrieve. * @param has filter by name. * @param orderBy oderBy filter. * @param asc if the 'orderBy' should be ascendant or descendant. * @return the list of matching elements. */ @Transactional(readOnly = true, propagation = Propagation.REQUIRED) public List<IpPoolManagement> getListIpPoolManagementByEnterprise(final Integer entId, final Integer firstElem, final Integer numElem, final String has, final String orderBy, final Boolean asc) { // Check if the orderBy element is actually one of the available ones IpPoolManagement.OrderByEnum orderByEnum = IpPoolManagement.OrderByEnum.fromValue(orderBy); if (orderByEnum == null) { LOGGER.info("Bad parameter 'by' in request to get the private ips by enterprise."); addValidationErrors(APIError.QUERY_INVALID_PARAMETER); flushErrors(); } List<IpPoolManagement> ips = repo.findIpsByEnterprise(entId, firstElem, numElem, has, orderByEnum, asc); LOGGER.debug("Returning the list of IPs used by Enterprise '" + entId + "'."); return ips; } /** * Asks for all the Private IPs managed by a Virtual Datacenter. * * @param vdcId identifier of the Virtual Datacenter. * @param firstElem first element to retrieve. * @param numElem number of elements to retrieve. * @param has filter by name. * @param orderBy oderBy filter. * @param asc if the 'orderBy' should be ascendant or descendant. * @return the list of matching elements. */ @Transactional(readOnly = true, propagation = Propagation.REQUIRED) public List<IpPoolManagement> getListIpPoolManagementByVdc(final Integer vdcId, final Integer firstElem, final Integer numElem, final String has, final String orderBy, final Boolean asc, final String type, final Boolean all) { // Check if the orderBy element is actually one of the available ones IpPoolManagement.OrderByEnum orderByEnum = IpPoolManagement.OrderByEnum.fromValue(orderBy); if (orderByEnum == null) { LOGGER .info("Bad parameter 'by' in request to get the private ips by virtualdatacenter."); addValidationErrors(APIError.QUERY_INVALID_PARAMETER); flushErrors(); } // Acquire the Virtual Datacenter VirtualDatacenter vdc = repo.findById(vdcId); if (vdc == null) { addNotFoundErrors(APIError.NON_EXISTENT_VIRTUAL_DATACENTER); flushErrors(); } NetworkType netType = NetworkType.INTERNAL; if (type != null && !type.equals("false") && !type.equals("INTERNAL")) { netType = NetworkType.fromValue(type); if (netType == null || netType.equals(NetworkType.INTERNAL)) { LOGGER .info("Bad parameter 'type' in request to get the public networks by a datacenter."); addValidationErrors(APIError.QUERY_NETWORK_TYPE_INVALID_PARAMETER); flushErrors(); } } // Query the list to database. if (netType.equals(NetworkType.EXTERNAL_UNMANAGED)) { // get the enterprise and datacenter and get the external and unmanaged ips List<IpPoolManagement> ips = repo.findPublicIpsByEnterprise(vdc.getDatacenter().getId(), vdc.getEnterprise() .getId(), firstElem, numElem, has, orderByEnum, asc, netType, all); LOGGER .debug("Returning the list of external and unmanaged IPs used by VirtualDatacenter '" + vdc.getName() + "'."); return ips; } else { List<IpPoolManagement> ips = repo.findIpsByVdc(vdcId, firstElem, numElem, has, orderByEnum, asc, netType); LOGGER.debug("Returning the list of private IPs used by VirtualDatacenter '" + vdc.getName() + "'."); return ips; } } /** * Asks for all the Private IPs managed by a Virtual Appliance. * * @param vapp Virtual Appliance object. * @return the list of matching elements. */ @Transactional(readOnly = true, propagation = Propagation.REQUIRED) public List<IpPoolManagement> getListIpPoolManagementByVirtualApp(final VirtualAppliance vapp) { List<IpPoolManagement> ips = repo.findIpsByVirtualAppliance(vapp); LOGGER .debug("Returning the list of IPs used by VirtualAppliance '" + vapp.getName() + "'."); return ips; } /** * Asks for all the Private IPs managed by a Virtual Virtual Machine. * * @param vdcId identifier of the Virtual Datacenter. * @param vappId identifier of the Virtual Appliance. * @param vmId identifier of the Virtual Machine. * @return the list of matching elements. */ @Transactional(readOnly = true, propagation = Propagation.REQUIRED) public List<IpPoolManagement> getListIpPoolManagementByVirtualMachine(final Integer vdcId, final Integer vappId, final Integer vmId) { VirtualDatacenter vdc = getVirtualDatacenter(vdcId); VirtualAppliance vapp = getVirtualAppliance(vdc, vappId); VirtualMachine vm = getVirtualMachine(vapp, vmId); List<IpPoolManagement> ips = repo.findIpsByVirtualMachine(vm); for (IpPoolManagement ip : ips) { Hibernate.initialize(ip.getVlanNetwork().getEnterprise()); if (ip.getVlanNetwork().getEnterprise() != null) { // needed for REST links. DatacenterLimits dl = datacenterRepo.findDatacenterLimits(ip.getVlanNetwork().getEnterprise(), vdc.getDatacenter()); ip.getVlanNetwork().setLimitId(dl.getId()); } } LOGGER.debug("Returning the list of IPs used by Virtual Machine '" + vm.getName() + "'."); return ips; } public List<IpPoolManagement> getListIpPoolManagementByInfrastructureVirtualMachine( final Integer datacenterId, final Integer rackId, final Integer machineId, final Integer vmId) { Machine pm = datacenterRepo.findMachineByIds(datacenterId, rackId, machineId); if (pm == null) { addNotFoundErrors(APIError.NON_EXISTENT_MACHINE); flushErrors(); } VirtualMachine vm = vmService.getVirtualMachineByHypervisor(pm.getHypervisor(), vmId); VirtualAppliance vapp = repo.findVirtualApplianceByVirtualMachine(vm); if (vapp == null) { // If vapp is 'null' it means the virtual machine does not belong // to any virtual appliance and hence, is an imported virtual machine. // since we don't manage NICs in imported Virtual Machines, return an empty lise return new ArrayList<IpPoolManagement>(); } VirtualDatacenter vdc = vapp.getVirtualDatacenter(); List<IpPoolManagement> ips = repo.findIpsByVirtualMachine(vm); for (IpPoolManagement ip : ips) { Hibernate.initialize(ip.getVlanNetwork().getEnterprise()); if (ip.getVlanNetwork().getEnterprise() != null) { // needed for REST links. DatacenterLimits dl = datacenterRepo.findDatacenterLimits(ip.getVlanNetwork().getEnterprise(), vdc.getDatacenter()); ip.getVlanNetwork().setLimitId(dl.getId()); } } LOGGER.debug("Returning the list of IPs used by Virtual Machine '" + vm.getName() + "'."); return ips; } /** * Asks for all the Private IPs managed by a VLAN. * * @param vdcId Identifier of the Virtual Datacenter. * @param vlanId Identifier of the VLAN. * @param startwith First element to retrieve. * @param limit Number of elements to retrieve. * @param filter Filter by name. * @param orderBy OrderBy filter. * @param descOrAsc If the 'orderBy' should be ascendant or descendant. * @return The list of matching elements. */ @Transactional(readOnly = true, propagation = Propagation.REQUIRED) public List<IpPoolManagement> getListIpPoolManagementByVlan(final Integer vdcId, final Integer vlanId, final Integer startwith, final String orderBy, final String filter, final Integer limit, final Boolean descOrAsc, final Boolean freeIps) { // Check if the orderBy element is actually one of the available ones IpPoolManagement.OrderByEnum orderByEnum = IpPoolManagement.OrderByEnum.fromValue(orderBy); if (orderByEnum == null) { LOGGER .info("Bad parameter 'by' in request to get the private ips by virtualdatacenter."); addValidationErrors(APIError.QUERY_INVALID_PARAMETER); flushErrors(); } List<IpPoolManagement> ips = repo.findIpsByPrivateVLANFiltered(vdcId, vlanId, startwith, limit, filter, orderByEnum, descOrAsc, freeIps); LOGGER.debug("Returning the list of IPs used by private VLAN with id '" + vlanId + "'."); return ips; } /** * Retrieve a Private Network. * * @param virtualdatacenterId identifier of the virtual datacenter. * @param vlanId identifier of the vlan. * @return an instance of the requested {@link VLANNetwork} */ @Transactional(readOnly = true, propagation = Propagation.REQUIRED) public VLANNetwork getPrivateNetwork(final Integer vdcId, final Integer vlanId) { VirtualDatacenter vdc = getVirtualDatacenter(vdcId); VLANNetwork vlan = getPrivateVlan(vdc, vlanId); LOGGER.debug("Returning the private VLAN entity with name '" + vlan.getName() + "'."); return vlan; } /** * Return the private networks defined in a Virtual Datacenter. * * @param virtualDatacenterId identifier of the virtual datacenter. * @return a Collection of {@link VLANNetwork} defined inside the Virtual Datacenter. */ @Transactional(readOnly = true, propagation = Propagation.REQUIRED) public Collection<VLANNetwork> getPrivateNetworks(final Integer vdcId) { VirtualDatacenter vdc = getVirtualDatacenter(vdcId); Collection<VLANNetwork> networks = null; networks = repo.findVlansByVirtualDatacener(vdc); LOGGER.debug("Returning the list of private VLANs for VirtualDatacenter '" + vdc.getName() + "'."); return networks; } /** * Get a single {@link VMNetworkConfiguration} for a given Virtual Machine configuration id. * * @param vdcId Identifier of the VirtualDatacenter. * @param vappId Identifier of the Virtual Appliance. * @param vmId Identifier of the Virtual Machine. * @param vmConfigId Identifier of the configuration value. * @return */ @Transactional(readOnly = true, propagation = Propagation.REQUIRED) public VMNetworkConfiguration getVirtualMachineConfiguration(final Integer vdcId, final Integer vappId, final Integer vmId, final Integer vmConfigId) { VirtualDatacenter vdc = getVirtualDatacenter(vdcId); VirtualAppliance vapp = getVirtualAppliance(vdc, vappId); VirtualMachine vm = getVirtualMachine(vapp, vmId); // Generally there is only one IP, but we avoid problemes and // we return IPs List<IpPoolManagement> ips = repo.findIpsWithConfigurationIdInVirtualMachine(vm); if (ips == null || ips.isEmpty()) { addNotFoundErrors(APIError.VLANS_NON_EXISTENT_CONFIGURATION); flushErrors(); } // The configuration is the same for all the Ips found. Check if there is any with // configureGateway == true -> that means the configuration is the used. IpPoolManagement resultIp = ips.get(0); for (IpPoolManagement ip : ips) { if (ip.getVlanNetwork().getConfiguration().getId() .equals(vm.getNetworkConfiguration().getId())) { resultIp = ip; break; } } VMNetworkConfiguration vmconfig = new VMNetworkConfiguration(); VLANNetwork vlan = resultIp.getVlanNetwork(); vmconfig.setGateway(vlan.getConfiguration().getGateway()); vmconfig.setPrimaryDNS(vlan.getConfiguration().getPrimaryDNS()); vmconfig.setSecondaryDNS(vlan.getConfiguration().getSecondaryDNS()); vmconfig.setSuffixDNS(vlan.getConfiguration().getSufixDNS()); vmconfig.setUsed(vlan.getConfiguration().getId() .equals(vm.getNetworkConfiguration().getId())); vmconfig.setId(vlan.getConfiguration().getId()); LOGGER .debug("Returning one of the Virtual Machine Configurations available by Virtual Machine '" + vm.getName() + "'."); return vmconfig; } /** * Return the list of NetworkConfiguration objects for a given virtual machine. * * @param vdcId Identifier of the Virtual Datacenter. * @param vappId Identifier of the Virtual Appliance. * @param vmId Identifier of the Virtual Machine. * @return the found list of {@link VMNetworkConfiguration}. */ @Transactional(readOnly = true, propagation = Propagation.REQUIRED) public List<VMNetworkConfiguration> getVirtualMachineConfigurations(final Integer vdcId, final Integer vappId, final Integer vmId) { // Check the parameter's correctness VirtualDatacenter vdc = getVirtualDatacenter(vdcId); VirtualAppliance vapp = getVirtualAppliance(vdc, vappId); VirtualMachine vm = getVirtualMachine(vapp, vmId); // Find all the IPs for the physical machine List<IpPoolManagement> ips = repo.findIpsByVirtualMachine(vm); List<VMNetworkConfiguration> configs = new ArrayList<VMNetworkConfiguration>(); for (IpPoolManagement ip : ips) { VMNetworkConfiguration vmconfig = new VMNetworkConfiguration(); VLANNetwork vlan = ip.getVlanNetwork(); vmconfig.setGateway(vlan.getConfiguration().getGateway()); vmconfig.setPrimaryDNS(vlan.getConfiguration().getPrimaryDNS()); vmconfig.setSecondaryDNS(vlan.getConfiguration().getSecondaryDNS()); vmconfig.setSuffixDNS(vlan.getConfiguration().getSufixDNS()); vmconfig.setUsed(ip.itHasTheDefaultConfiguration(vm)); vmconfig.setId(vlan.getConfiguration().getId()); // if its the same configuration fails in the case when you have set used true in one // and in the other its false if (!configs.contains(vmconfig)) { configs.add(vmconfig); } else { if (vmconfig.getUsed()) { configs.remove(vmconfig); configs.add(vmconfig); } } } LOGGER.debug("Returning the list of Virtual Machine Configurations for machine '" + vm.getName() + "'."); return configs; } /** * Reorder a NIC from 'linkOldOrder' to 'nicOrder'. Reorder the rest of affected NICs. * * @param vdcId Identifier of the Virtual Datacenter. * @param vappId Identifier of the Virtual Appliance. * @param vmId Identifier of the Virtual Machine. * @param linkOldOrder old 'order' value of the NIC. * @param nicOrder new 'order' value of the NIC. */ @Transactional(readOnly = false, propagation = Propagation.REQUIRED) public void reorderVirtualMachineNic(final Integer vdcId, final Integer vappId, final Integer vmId, final Integer linkOldOrder, final Integer nicOrder) { // Find if the parameters exist. VirtualDatacenter vdc = getVirtualDatacenter(vdcId); VirtualAppliance vapp = getVirtualAppliance(vdc, vappId); VirtualMachine vm = getVirtualMachine(vapp, vmId); // The user has the role for manage this. But... is the user from the same enterprise // than Virtual Datacenter? userService.checkCurrentEnterpriseForPostMethods(vdc.getEnterprise()); // Check if the machine is in the correct state to perform the action. if (!vm.getState().equals(VirtualMachineState.NOT_ALLOCATED)) { addConflictErrors(APIError.VIRTUAL_MACHINE_INCOHERENT_STATE); flushErrors(); } List<IpPoolManagement> ips = repo.findIpsByVirtualMachine(vm); // If the order is bigger or equal than the size, then // the resource does not exist. Ex: size = 2 -> nicOrder = 2 -> (ERROR! the order begins // with 0 and if the size is 2, the available values are 0,1. if (nicOrder >= ips.size() || linkOldOrder >= ips.size() || linkOldOrder < 0) { addNotFoundErrors(APIError.VLANS_NIC_NOT_FOUND); flushErrors(); } if (nicOrder == linkOldOrder) { // do nothing return; } // Update the rest of ethernet values. The goal of this bucle is shift all // the ethernet values between the new order and the previous one. Depending // on the new order is bigger or smaller than the previous one, the shift // will be right to left or left to right. // The shift of the new values are leftToRight or rightToLeft? Boolean leftToRight = Boolean.TRUE; if (nicOrder > linkOldOrder) { leftToRight = Boolean.FALSE; } // move backwards or forwards the ip order in the loop. for (IpPoolManagement ip : ips) { Integer eth = Integer.valueOf(ip.getRasd().getConfigurationName()); if (eth.equals(linkOldOrder)) { // if its the value to modify, do it :) // Set the new order to the NIC ip.getRasd().setConfigurationName(String.valueOf(nicOrder)); } if (leftToRight && eth >= nicOrder && eth < linkOldOrder) { ip.getRasd().setConfigurationName(String.valueOf(eth + 1)); } else if (!leftToRight && eth <= nicOrder && eth > linkOldOrder) { ip.getRasd().setConfigurationName(String.valueOf(eth - 1)); } repo.updateRasd(ip.getRasd()); } if (tracer != null) { tracer.log(SeverityType.INFO, ComponentType.VIRTUAL_MACHINE, EventType.NIC_REORDER_VIRTUAL_MACHINE, "nic.reordered", vm.getName()); } } /** * Set one of the internal networks of the Virtual Datacenter as the default one. * * @param vdcId identifier of the virtual datacenter. * @param vlanId identifier of the vlan to be the default one. */ @Transactional(readOnly = false, propagation = Propagation.REQUIRED) public void setInternalNetworkAsDefaultInVirtualDatacenter(final Integer vdcId, final Integer vlanId) { VirtualDatacenter vdc = getVirtualDatacenter(vdcId); VLANNetwork vlan = getPrivateVlan(vdc, vlanId); if (vlan == null) { addNotFoundErrors(APIError.VLANS_NON_EXISTENT_VIRTUAL_NETWORK); } vdc.setDefaultVlan(vlan); repo.update(vdc); if (tracer != null) { tracer.log(SeverityType.INFO, ComponentType.VIRTUAL_DATACENTER, EventType.VLAN_DEFAULT, "vlan.default", vlan.getName(), vdc.getName()); } } /** * Edit an existing VLAN. * * @param vdcId identifier of the virtual datacenter the VLAN belongs to. * @param vlanId identifier of the VLAN * @param newNetwork new object to edit. * @return an instance of the modified {@link VLANNetwork} */ @Transactional(readOnly = false, propagation = Propagation.REQUIRED) public VLANNetwork updatePrivateNetwork(final Integer vdcId, final Integer vlanId, final VLANNetwork newNetwork) { VirtualDatacenter vdc = getVirtualDatacenter(vdcId); VLANNetwork oldNetwork = getPrivateVlan(vdc, vlanId); newNetwork.setNetwork(vdc.getNetwork()); newNetwork.setType(oldNetwork.getType()); validate(newNetwork); if (!vlanId.equals(newNetwork.getId())) { addValidationErrors(APIError.INCOHERENT_IDS); flushErrors(); } validate(newNetwork.getConfiguration()); // The user has the role for manage This. But... is the user from the same enterprise // than Virtual Datacenter? userService.checkCurrentEnterpriseForPostMethods(vdc.getEnterprise()); // Values 'address', 'mask', and 'tag' can not be changed by the edit process if (!oldNetwork.getConfiguration().getAddress() .equalsIgnoreCase(newNetwork.getConfiguration().getAddress()) || !oldNetwork.getConfiguration().getMask() .equals(newNetwork.getConfiguration().getMask()) || oldNetwork.getTag() == null && newNetwork.getTag() != null || oldNetwork.getTag() != null && newNetwork.getTag() == null || oldNetwork.getTag() != null && newNetwork.getTag() != null && !oldNetwork.getTag().equals(newNetwork.getTag())) { addConflictErrors(APIError.VLANS_EDIT_INVALID_VALUES); flushErrors(); } // Check the new gateway is inside the range of IPs. if (!newNetwork.getConfiguration().getGateway() .equalsIgnoreCase(oldNetwork.getConfiguration().getGateway())) { IPAddress networkIP = IPAddress.newIPAddress(newNetwork.getConfiguration().getAddress()); String newGateway = newNetwork.getConfiguration().getGateway(); Integer mask = newNetwork.getConfiguration().getMask(); if (!IPAddress.isIntoRange(IPNetworkRang.calculateWholeRange(networkIP, mask), newGateway)) { addConflictErrors(APIError.VLANS_GATEWAY_OUT_OF_RANGE); flushErrors(); } } // Check if the network name has changed. If it has: // 1 - Check there is not another VLAN in the same VDC with the same name. // 2 - Change all the IpPoolManagement entities with the new network name if (!newNetwork.getName().equalsIgnoreCase(oldNetwork.getName())) { VLANNetwork duplicatedVLAN = repo.findVlanByNameInNetwork(vdc.getNetwork(), newNetwork.getName()); if (duplicatedVLAN != null) { addConflictErrors(APIError.VLANS_DUPLICATED_VLAN_NAME_VDC); flushErrors(); } // update the ips with the new values. List<IpPoolManagement> ips = repo.findIpsByPrivateVLAN(vdcId, vlanId); for (IpPoolManagement ip : ips) { ip.setNetworkName(newNetwork.getName()); } // the updates flushes the session. Due we have so many IPs to update, // better wait until it finishes. repo.updateIpManagement(null); } // set the dhcp option datacenterRepo.deleteAllDhcpOption(oldNetwork.getDhcpOption()); List<DhcpOption> opts = new ArrayList<DhcpOption>(newNetwork.getDhcpOption()); for (DhcpOption dhcpOption : newNetwork.getDhcpOption()) { dhcpOption.setOption(121); dhcpOption.setMask(getMaskbyNetMask(dhcpOption.getNetmask())); if (dhcpOption.getMask() != 0) { datacenterRepo.insertDhcpOption(dhcpOption); DhcpOption dhcpOption2 = new DhcpOption(249, dhcpOption.getGateway(), dhcpOption.getNetworkAddress(), dhcpOption.getMask(), dhcpOption.getNetmask()); datacenterRepo.insertDhcpOption(dhcpOption2); opts.add(dhcpOption2); } else { opts.remove(dhcpOption); } } oldNetwork.setDhcpOption(opts); // Set the new values and update the VLAN oldNetwork.getConfiguration().setGateway(newNetwork.getConfiguration().getGateway()); oldNetwork.getConfiguration().setPrimaryDNS(newNetwork.getConfiguration().getPrimaryDNS()); oldNetwork.getConfiguration().setSecondaryDNS( newNetwork.getConfiguration().getSecondaryDNS()); oldNetwork.getConfiguration().setSufixDNS(newNetwork.getConfiguration().getSufixDNS()); oldNetwork.setName(newNetwork.getName()); repo.updateVlan(oldNetwork); if (tracer != null) { // Trace and log message. tracer.log(SeverityType.INFO, ComponentType.NETWORK, EventType.VLAN_EDITED, "privateVlan.updated", oldNetwork.getName(), vdc.getName()); } return oldNetwork; } /** * Check if the VLANs used have reached the maximum. * * @param vdc each virtualdatacenter has a maximum of VLANs. */ protected void checkNumberOfCurrentVLANs(final VirtualDatacenter vdc) { Integer maxVLANs = Integer.valueOf(ConfigService.getVlanPerVdc()); Integer currentVLANs = repo.findVlansByVirtualDatacener(vdc).size(); if (currentVLANs >= maxVLANs) { addConflictErrors(APIError.VLANS_PRIVATE_MAXIMUM_REACHED); flushErrors(); } } /** * Check if the informed IP address and mask are correct for to be private IPs. Check also if * the netmask and the address are coherent. * * @param networkAddress network address * @param netmask mask of the network * @throws NetworkCommandException if the values are not coherent into a public or private * network environment. */ protected void checkAddressAndMaskCoherency(final IPAddress netAddress, final Integer netmask) { // Parse the correct IP. (avoid 127.00.00.01), for instance IPAddress networkAddress = IPAddress.newIPAddress(netAddress.toString()); // First of all, check if the networkAddress is correct. // if the value is a private network. if (netmask < 22) { addConflictErrors(APIError.VLANS_TOO_BIG_NETWORK); flushErrors(); } if (!NetworkResolver.isValidNetworkMask(networkAddress, netmask)) { addValidationErrors(APIError.VLANS_INVALID_NETWORK_AND_MASK); flushErrors(); } } /** * Gets a private Vlan. Raises a NOT_FOUND exception if it does not exist. * * @param vdc {@link VirtualDatacenter} instance where the Vlan should be. * @param vlanId identifier of the {@link VLANNetwork} instance. * @return the found {@link VLANNetwork} instance. */ protected VLANNetwork getPrivateVlan(final VirtualDatacenter vdc, final Integer vlanId) { VLANNetwork vlan = repo.findVlanByVirtualDatacenterId(vdc, vlanId); if (vlan == null) { addNotFoundErrors(APIError.VLANS_NON_EXISTENT_VIRTUAL_NETWORK); flushErrors(); } return vlan; } /** * Gets a Virtual Appliance. Raises a NOT_FOUND exception if it does not exist. * * @param vdc {@link VirtualDatacenter} instance where the vapp should be. * @param vappId identifier of the {@link VirtualAppliance} instance. * @return the found {@link VirtualAppliance} instance. */ protected VirtualAppliance getVirtualAppliance(final VirtualDatacenter vdc, final Integer vappId) { VirtualAppliance vapp = repo.findVirtualApplianceById(vdc, vappId); if (vapp == null) { addNotFoundErrors(APIError.NON_EXISTENT_VIRTUALAPPLIANCE); flushErrors(); } return vapp; } /** * Gets a VirtualDatacenter. Raises an exception if it does not exist. * * @param vdcId identifier of the virtual datacenter. * @return the found {@link VirtualDatacenter} instance. */ protected VirtualDatacenter getVirtualDatacenter(final Integer vdcId) { VirtualDatacenter vdc = repo.findById(vdcId); if (vdc == null) { addNotFoundErrors(APIError.NON_EXISTENT_VIRTUAL_DATACENTER); flushErrors(); } return vdc; } /** * Gets a Virtual Machine. Raises a NOT_FOUND exception if it does not exist. * * @param vapp {@link VirtualAppliance} instance where the VirtualMachine should be. * @param vmId identifier of the {@link VirtualMachine} instance. * @return the found {@link VirtualMachine} instance. */ protected VirtualMachine getVirtualMachine(final VirtualAppliance vapp, final Integer vmId) { VirtualMachine vm = repo.findVirtualMachineById(vapp, vmId); if (vm == null) { addNotFoundErrors(APIError.NON_EXISTENT_VIRTUALMACHINE); flushErrors(); } return vm; } /** * Store all the IPs of the network in database. * * @param datacenter Datacenter where the network is created. * @param vdc Virtual Dataceneter where the network are assigned. Can be null for public * networks. * @param vlan VLAN to assign its ips. * @param range List of ips to create inside the DHCP * @return */ protected void storeIPs(final Datacenter datacenter, final VirtualDatacenter vdc, final VLANNetwork vlan, final Collection<IPAddress> range) { Collection<String> allMacAddresses = repo.getAllMacs(); for (IPAddress address : range) { String macAddress = null; String name = null; if (vdc != null) { do { macAddress = IPNetworkRang.requestRandomMacAddress(vdc.getHypervisorType()); } while (allMacAddresses.contains(macAddress)); allMacAddresses.add(macAddress); // Replacing the ':' char into an empty char (it seems the dhcp.leases fails when // reload // leases with the ':' char in the lease name) name = macAddress.replace(":", "") + "_host"; } IpPoolManagement ipManagement = new IpPoolManagement(vlan, macAddress, name, address.toString(), vlan.getName()); if (vdc != null) { // public network does not have VDC by default. ipManagement.setVirtualDatacenter(vdc); } repo.insertIpManagement(ipManagement); } } private Integer getMaskbyNetMask(final String netmask) { Inet4Address address; try { address = (Inet4Address) InetAddress.getByName(netmask); byte[] values = address.getAddress(); int hex = values[0] << 24 | values[1] << 16 | values[2] << 8 | values[3] << 0; Integer mask = Integer.bitCount(hex); if (mask < 32) { return mask; } } catch (UnknownHostException e) { // invalid netmask } return 0; } }