diff --git a/api/src/com/cloud/network/NetworkService.java b/api/src/com/cloud/network/NetworkService.java index 4785b9c6feb..8f235617393 100755 --- a/api/src/com/cloud/network/NetworkService.java +++ b/api/src/com/cloud/network/NetworkService.java @@ -52,7 +52,7 @@ public interface NetworkService { IpAddress allocateIP(Account ipOwner, long zoneId, Long networkId) throws ResourceAllocationException, InsufficientAddressCapacityException, ConcurrentOperationException; - IpAddress allocatePortableIP(Account ipOwner, int regionId, Long zoneId, Long networkId) throws ResourceAllocationException, + IpAddress allocatePortableIP(Account ipOwner, int regionId, Long zoneId, Long networkId, Long vpcId) throws ResourceAllocationException, InsufficientAddressCapacityException, ConcurrentOperationException; boolean releaseIpAddress(long ipAddressId) throws InsufficientAddressCapacityException; diff --git a/api/src/org/apache/cloudstack/api/command/user/address/AssociateIPAddrCmd.java b/api/src/org/apache/cloudstack/api/command/user/address/AssociateIPAddrCmd.java index 3aa3c4b5611..f37e82060fb 100644 --- a/api/src/org/apache/cloudstack/api/command/user/address/AssociateIPAddrCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/address/AssociateIPAddrCmd.java @@ -216,7 +216,13 @@ public class AssociateIPAddrCmd extends BaseAsyncCreateCmd { @Override public void create() throws ResourceAllocationException{ try { - IpAddress ip = _networkService.allocateIP(_accountService.getAccount(getEntityOwnerId()), getZoneId(), getNetworkId()); + IpAddress ip = null; + + if (!isPortable()) { + ip = _networkService.allocateIP(_accountService.getAccount(getEntityOwnerId()), getZoneId(), getNetworkId()); + } else { + ip = _networkService.allocatePortableIP(_accountService.getAccount(getEntityOwnerId()), 1, getZoneId(), getNetworkId(), getVpcId()); + } if (ip != null) { this.setEntityId(ip.getId()); diff --git a/engine/schema/src/com/cloud/network/dao/IPAddressVO.java b/engine/schema/src/com/cloud/network/dao/IPAddressVO.java index a7dcf6ae39e..5eb2500e0a6 100644 --- a/engine/schema/src/com/cloud/network/dao/IPAddressVO.java +++ b/engine/schema/src/com/cloud/network/dao/IPAddressVO.java @@ -112,7 +112,7 @@ public class IPAddressVO implements IpAddress { private String vmIp; @Column(name="is_portable") - private boolean portable; + private boolean portable = false; protected IPAddressVO() { this.uuid = UUID.randomUUID().toString(); @@ -136,6 +136,19 @@ public class IPAddressVO implements IpAddress { this.uuid = UUID.randomUUID().toString(); } + public IPAddressVO(Ip address, long dataCenterId, Long networkId, Long vpcId, long physicalNetworkId, long sourceNetworkId, + long vlanDbId, boolean portable) { + this.address = address; + this.dataCenterId = dataCenterId; + this.associatedWithNetworkId = networkId; + this.vpcId = vpcId; + this.physicalNetworkId = physicalNetworkId; + this.sourceNetworkId = sourceNetworkId; + this.vlanId = vlanDbId; + this.portable = portable; + this.uuid = UUID.randomUUID().toString(); + } + public long getMacAddress() { return macAddress; } diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java index bc7583d00f3..5a4fad08f38 100755 --- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java @@ -44,6 +44,7 @@ import com.cloud.dc.*; import com.cloud.dc.dao.*; import com.cloud.user.*; import com.cloud.event.UsageEventUtils; +import com.cloud.utils.db.*; import org.apache.cloudstack.acl.SecurityChecker; import org.apache.cloudstack.api.ApiConstants.LDAPParams; import org.apache.cloudstack.api.command.admin.config.UpdateCfgCmd; @@ -164,10 +165,6 @@ import com.cloud.utils.NumbersUtil; import com.cloud.utils.StringUtils; import com.cloud.utils.component.ManagerBase; import com.cloud.utils.crypt.DBEncryptionUtil; -import com.cloud.utils.db.DB; -import com.cloud.utils.db.Filter; -import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.NetUtils; import com.cloud.vm.VirtualMachine; @@ -4523,6 +4520,8 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati throw new InvalidParameterValueException("Invalid vlan id " + vlanId); } } + GlobalLock portableIpLock = GlobalLock.getInternLock("PortablePublicIpRange"); + portableIpLock.lock(5); Transaction txn = Transaction.currentTxn(); txn.start(); @@ -4539,7 +4538,7 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati } txn.commit(); - + portableIpLock.unlock(); return portableIpRange; } diff --git a/server/src/com/cloud/network/NetworkManager.java b/server/src/com/cloud/network/NetworkManager.java index 34a092a465a..15bb450f7bd 100755 --- a/server/src/com/cloud/network/NetworkManager.java +++ b/server/src/com/cloud/network/NetworkManager.java @@ -58,6 +58,7 @@ import com.cloud.vm.VMInstanceVO; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachine.Type; import com.cloud.vm.VirtualMachineProfile; +import org.apache.cloudstack.region.PortableIp; /** * NetworkManager manages the network for the different end users. @@ -323,6 +324,9 @@ public interface NetworkManager { DataCenter zone) throws ConcurrentOperationException, ResourceAllocationException, InsufficientAddressCapacityException; + IpAddress allocatePortableIp(Account ipOwner, Account caller, long dcId, Long networkId, Long vpcID) + throws ConcurrentOperationException, ResourceAllocationException, InsufficientAddressCapacityException; + Map finalizeServicesAndProvidersForNetwork(NetworkOffering offering, Long physicalNetworkId); diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index c91243095da..44a60f09d5d 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -105,6 +105,10 @@ import com.cloud.vm.VirtualMachine.Type; import com.cloud.vm.dao.*; import org.apache.cloudstack.acl.ControlledEntity.ACLType; import org.apache.cloudstack.acl.SecurityChecker.AccessType; +import org.apache.cloudstack.region.PortableIp; +import org.apache.cloudstack.region.PortableIpDao; +import org.apache.cloudstack.region.PortableIpVO; +import org.apache.cloudstack.region.Region; import org.apache.log4j.Logger; import org.springframework.stereotype.Component; @@ -251,6 +255,8 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L UserIpv6AddressDao _ipv6Dao; @Inject Ipv6AddressManager _ipv6Mgr; + @Inject + PortableIpDao _portableIpDao; protected StateMachine2 _stateMachine; private final HashMap _systemNetworks = new HashMap(5); @@ -696,6 +702,62 @@ public class NetworkManagerImpl extends ManagerBase implements NetworkManager, L return ip; } + @Override + @DB + public IpAddress allocatePortableIp(Account ipOwner, Account caller, long dcId, Long networkId, Long vpcID) + throws ConcurrentOperationException, ResourceAllocationException, InsufficientAddressCapacityException { + + Transaction txn = Transaction.currentTxn(); + GlobalLock portableIpLock = GlobalLock.getInternLock("PortablePublicIpRange"); + PortableIpVO allocatedPortableIp; + IPAddressVO ipaddr; + + try { + portableIpLock.lock(5); + + txn.start(); + //TODO: get the region ID corresponding to running management server + List portableIpVOs = _portableIpDao.listByRegionIdAndState(1, PortableIp.State.Free); + if (portableIpVOs == null || portableIpVOs.isEmpty()) { + InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException + ("Unable to find available portable IP addresses", Region.class, new Long(1)); + throw ex; + } + + // allocate first portable IP to the user + allocatedPortableIp = portableIpVOs.get(0); + allocatedPortableIp.setAllocatedTime(new Date()); + allocatedPortableIp.setAllocatedToAccountId(ipOwner.getAccountId()); + allocatedPortableIp.setAllocatedInDomainId(ipOwner.getDomainId()); + allocatedPortableIp.setState(PortableIp.State.Allocated); + _portableIpDao.update(allocatedPortableIp.getId(), allocatedPortableIp); + + // provision portable IP range VLAN + long physicalNetworkId = _networkModel.getDefaultPhysicalNetworkByZoneAndTrafficType(dcId, TrafficType.Public).getId(); + Network network = _networkModel.getNetwork(physicalNetworkId); + String range = allocatedPortableIp.getAddress() + "-" + allocatedPortableIp.getAddress(); + VlanVO vlan = new VlanVO(VlanType.VirtualNetwork, allocatedPortableIp.getVlan(), allocatedPortableIp.getGateway(), + allocatedPortableIp.getNetmask(), dcId, range, network.getId(), network.getId(), null, null, null); + vlan = _vlanDao.persist(vlan); + + // provision the portable IP in to user_ip_address table + ipaddr = new IPAddressVO(new Ip(allocatedPortableIp.getAddress()), dcId, networkId, vpcID, network.getId(), + network.getId(), vlan.getId(), true); + ipaddr.setState(State.Allocated); + ipaddr.setAllocatedTime(new Date()); + ipaddr.setAllocatedInDomainId(ipOwner.getDomainId()); + ipaddr.setAllocatedToAccountId(ipOwner.getId()); + ipaddr= _ipAddressDao.persist(ipaddr); + + txn.commit(); + + } finally { + portableIpLock.unlock(); + } + + return ipaddr; + } + protected IPAddressVO getExistingSourceNatInNetwork(long ownerId, Long networkId) { List addrs = _networkModel.listPublicIpsAssignedToGuestNtwk(ownerId, networkId, true); diff --git a/server/src/com/cloud/network/NetworkServiceImpl.java b/server/src/com/cloud/network/NetworkServiceImpl.java index 14b94a4f0eb..1e6aca43baa 100755 --- a/server/src/com/cloud/network/NetworkServiceImpl.java +++ b/server/src/com/cloud/network/NetworkServiceImpl.java @@ -37,6 +37,7 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; +import com.cloud.network.vpc.dao.VpcDao; import org.apache.cloudstack.acl.ControlledEntity.ACLType; import org.apache.cloudstack.acl.SecurityChecker; import org.apache.cloudstack.acl.SecurityChecker.AccessType; @@ -171,32 +172,6 @@ import com.cloud.vm.dao.NicSecondaryIpDao; import com.cloud.vm.dao.NicSecondaryIpVO; import com.cloud.vm.dao.UserVmDao; import com.cloud.vm.dao.VMInstanceDao; -import com.cloud.vm.*; -import com.cloud.vm.dao.*; -import org.apache.cloudstack.acl.ControlledEntity.ACLType; -import org.apache.cloudstack.acl.SecurityChecker; -import org.apache.cloudstack.acl.SecurityChecker.AccessType; -import org.apache.cloudstack.api.command.admin.network.DedicateGuestVlanRangeCmd; -import org.apache.cloudstack.api.command.admin.network.ListDedicatedGuestVlanRangesCmd; -import org.apache.cloudstack.api.command.admin.usage.ListTrafficTypeImplementorsCmd; -import org.apache.cloudstack.api.command.user.network.CreateNetworkCmd; -import org.apache.cloudstack.api.command.user.network.ListNetworksCmd; -import org.apache.cloudstack.api.command.user.network.RestartNetworkCmd; -import org.apache.cloudstack.api.command.user.vm.ListNicsCmd; -import org.apache.log4j.Logger; -import org.springframework.stereotype.Component; - -import javax.ejb.Local; -import javax.inject.Inject; -import javax.naming.ConfigurationException; -import java.net.Inet6Address; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.security.InvalidParameterException; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.*; /** @@ -301,6 +276,8 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { DataCenterVnetDao _datacneter_vnet; @Inject AccountGuestVlanMapDao _accountGuestVlanMapDao; + @Inject + VpcDao _vpcDao; int _cidrLimit; boolean _allowSubdomainNetworkAccess; @@ -512,22 +489,23 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { public IpAddress allocateIP(Account ipOwner, long zoneId, Long networkId) throws ResourceAllocationException, InsufficientAddressCapacityException, ConcurrentOperationException { + Account caller = UserContext.current().getCaller(); + long callerUserId = UserContext.current().getCallerUserId(); + DataCenter zone = _configMgr.getZone(zoneId); + if (networkId != null) { Network network = _networksDao.findById(networkId); if (network == null) { throw new InvalidParameterValueException("Invalid network id is given"); } + if (network.getGuestType() == Network.GuestType.Shared) { - DataCenter zone = _configMgr.getZone(zoneId); if (zone == null) { throw new InvalidParameterValueException("Invalid zone Id is given"); } - // if shared network in the advanced zone, then check the caller against the network for 'AccessType.UseNetwork' if (zone.getNetworkType() == NetworkType.Advanced) { if (isSharedNetworkOfferingWithServices(network.getNetworkOfferingId())) { - Account caller = UserContext.current().getCaller(); - long callerUserId = UserContext.current().getCallerUserId(); _accountMgr.checkAccess(caller, AccessType.UseNetwork, false, network); if (s_logger.isDebugEnabled()) { s_logger.debug("Associate IP address called by the user " + callerUserId + " account " + ipOwner.getId()); @@ -539,27 +517,57 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { } } } + } else { + _accountMgr.checkAccess(caller, null, false, ipOwner); } - return allocateIP(ipOwner, false, zoneId); + return _networkMgr.allocateIp(ipOwner, false, caller, callerUserId, zone); } @Override @ActionEvent(eventType = EventTypes.EVENT_PORTABLE_IP_ASSIGN, eventDescription = "allocating portable public Ip", create = true) - public IpAddress allocatePortableIP(Account ipOwner, int regionId, Long zoneId, Long networkId) - throws ResourceAllocationException, InsufficientAddressCapacityException, ConcurrentOperationException { - return null; - } - - public IpAddress allocateIP(Account ipOwner, boolean isSystem, long zoneId) + public IpAddress allocatePortableIP(Account ipOwner, int regionId, Long zoneId, Long networkId, Long vpcId) throws ResourceAllocationException, InsufficientAddressCapacityException, ConcurrentOperationException { Account caller = UserContext.current().getCaller(); - // check permissions - _accountMgr.checkAccess(caller, null, false, ipOwner); long callerUserId = UserContext.current().getCallerUserId(); DataCenter zone = _configMgr.getZone(zoneId); - return _networkMgr.allocateIp(ipOwner, isSystem, caller, callerUserId, zone); + if (networkId != null) { + Network network = _networksDao.findById(networkId); + if (network == null) { + throw new InvalidParameterValueException("Invalid network id is given"); + } + + if (network.getGuestType() == Network.GuestType.Shared) { + if (zone == null) { + throw new InvalidParameterValueException("Invalid zone Id is given"); + } + // if shared network in the advanced zone, then check the caller against the network for 'AccessType.UseNetwork' + if (zone.getNetworkType() == NetworkType.Advanced) { + if (isSharedNetworkOfferingWithServices(network.getNetworkOfferingId())) { + _accountMgr.checkAccess(caller, AccessType.UseNetwork, false, network); + if (s_logger.isDebugEnabled()) { + s_logger.debug("Associate IP address called by the user " + callerUserId + " account " + ipOwner.getId()); + } + return _networkMgr.allocatePortableIp(ipOwner, caller, zoneId, networkId, null); + } else { + throw new InvalidParameterValueException("Associate IP address can only be called on the shared networks in the advanced zone" + + " with Firewall/Source Nat/Static Nat/Port Forwarding/Load balancing services enabled"); + } + } + } + } + + if (vpcId != null) { + Vpc vpc = _vpcDao.findById(vpcId); + if (vpc != null) { + throw new InvalidParameterValueException("Invalid vpc id is given"); + } + } + + _accountMgr.checkAccess(caller, null, false, ipOwner); + + return _networkMgr.allocatePortableIp(ipOwner, caller, zoneId, null, null); } @Override diff --git a/server/src/org/apache/cloudstack/region/PortableIpDao.java b/server/src/org/apache/cloudstack/region/PortableIpDao.java index 3512075656a..ca6ca14767e 100755 --- a/server/src/org/apache/cloudstack/region/PortableIpDao.java +++ b/server/src/org/apache/cloudstack/region/PortableIpDao.java @@ -31,4 +31,5 @@ public interface PortableIpDao extends GenericDao { List listByRangeIdAndState(long rangeId, PortableIp.State state); + List listByRegionIdAndState(int regionId, PortableIp.State state); } diff --git a/server/src/org/apache/cloudstack/region/PortableIpDaoImpl.java b/server/src/org/apache/cloudstack/region/PortableIpDaoImpl.java index 8989e828573..fb813a9fc6f 100755 --- a/server/src/org/apache/cloudstack/region/PortableIpDaoImpl.java +++ b/server/src/org/apache/cloudstack/region/PortableIpDaoImpl.java @@ -51,6 +51,7 @@ public class PortableIpDaoImpl extends GenericDaoBase implem private final SearchBuilder listByRegionIDSearch; private final SearchBuilder listByRangeIDSearch; private final SearchBuilder listByRangeIDAndStateSearch; + private final SearchBuilder listByRegionIDAndStateSearch; public PortableIpDaoImpl() { listByRegionIDSearch = createSearchBuilder(); @@ -65,6 +66,11 @@ public class PortableIpDaoImpl extends GenericDaoBase implem listByRangeIDAndStateSearch.and("rangeId", listByRangeIDAndStateSearch.entity().getRangeId(), SearchCriteria.Op.EQ); listByRangeIDAndStateSearch.and("state", listByRangeIDAndStateSearch.entity().getState(), SearchCriteria.Op.EQ); listByRangeIDAndStateSearch.done(); + + listByRegionIDAndStateSearch = createSearchBuilder(); + listByRegionIDAndStateSearch.and("regionId", listByRegionIDAndStateSearch.entity().getRangeId(), SearchCriteria.Op.EQ); + listByRegionIDAndStateSearch.and("state", listByRegionIDAndStateSearch.entity().getState(), SearchCriteria.Op.EQ); + listByRegionIDAndStateSearch.done(); } @Override @@ -88,4 +94,12 @@ public class PortableIpDaoImpl extends GenericDaoBase implem sc.setParameters("state", state); return listBy(sc); } + + @Override + public List listByRegionIdAndState(int regionId, PortableIp.State state) { + SearchCriteria sc = listByRegionIDAndStateSearch.create(); + sc.setParameters("regionId", regionId); + sc.setParameters("state", state); + return listBy(sc); + } } diff --git a/server/test/com/cloud/network/MockNetworkManagerImpl.java b/server/test/com/cloud/network/MockNetworkManagerImpl.java index 752dffbbeaa..f2d1fd404d0 100755 --- a/server/test/com/cloud/network/MockNetworkManagerImpl.java +++ b/server/test/com/cloud/network/MockNetworkManagerImpl.java @@ -49,7 +49,6 @@ import com.cloud.network.Networks.TrafficType; import com.cloud.network.addr.PublicIp; import com.cloud.network.dao.IPAddressVO; import com.cloud.network.dao.NetworkVO; -import com.cloud.network.GuestVlan; import com.cloud.network.element.LoadBalancingServiceProvider; import com.cloud.network.element.StaticNatServiceProvider; import com.cloud.network.element.UserDataServiceProvider; @@ -68,21 +67,8 @@ import com.cloud.utils.component.ManagerBase; import com.cloud.vm.*; import com.cloud.vm.VirtualMachine.Type; import com.cloud.vm.VirtualMachineProfile; -import org.apache.cloudstack.acl.ControlledEntity.ACLType; import org.apache.cloudstack.api.command.admin.network.DedicateGuestVlanRangeCmd; import org.apache.cloudstack.api.command.admin.network.ListDedicatedGuestVlanRangesCmd; -import org.apache.cloudstack.api.command.admin.usage.ListTrafficTypeImplementorsCmd; -import org.apache.cloudstack.api.command.user.network.CreateNetworkCmd; -import org.apache.cloudstack.api.command.user.network.ListNetworksCmd; -import org.apache.cloudstack.api.command.user.network.RestartNetworkCmd; -import org.apache.cloudstack.api.command.user.vm.ListNicsCmd; -import org.springframework.stereotype.Component; - -import javax.ejb.Local; -import javax.naming.ConfigurationException; -import java.util.List; -import java.util.Map; -import java.util.Set; @Component @@ -859,10 +845,17 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkManage } @Override - public IpAddress allocatePortableIP(Account ipOwner, int regionId, Long zoneId, Long networkId) throws ResourceAllocationException, InsufficientAddressCapacityException, ConcurrentOperationException { + public IpAddress allocatePortableIp(Account ipOwner, Account caller, long dcId, Long networkId, Long vpcID) + throws ConcurrentOperationException, ResourceAllocationException, InsufficientAddressCapacityException { return null;// TODO Auto-generated method stub } + @Override + public IpAddress allocatePortableIP(Account ipOwner, int regionId, Long zoneId, Long networkId, Long vpcId) throws ResourceAllocationException, + InsufficientAddressCapacityException, ConcurrentOperationException { + return null; + } + @Override public boolean isSecondaryIpSetForNic(long nicId) { // TODO Auto-generated method stub diff --git a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java index 88769632a2d..e6e92573918 100644 --- a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java +++ b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java @@ -62,7 +62,6 @@ import com.cloud.network.PhysicalNetworkServiceProvider; import com.cloud.network.PhysicalNetworkTrafficType; import com.cloud.network.PublicIpAddress; import com.cloud.network.addr.PublicIp; -import com.cloud.network.dao.AccountGuestVlanMapVO; import com.cloud.network.dao.IPAddressVO; import com.cloud.network.dao.NetworkServiceMapDao; import com.cloud.network.dao.NetworkVO; @@ -92,16 +91,6 @@ import com.cloud.vm.VMInstanceVO; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachine.Type; import com.cloud.vm.VirtualMachineProfile; -import org.apache.cloudstack.acl.ControlledEntity.ACLType; -import org.apache.cloudstack.api.command.admin.network.DedicateGuestVlanRangeCmd; -import org.apache.cloudstack.api.command.admin.network.ListDedicatedGuestVlanRangesCmd; -import org.apache.cloudstack.api.command.admin.usage.ListTrafficTypeImplementorsCmd; -import org.apache.cloudstack.api.command.user.network.CreateNetworkCmd; -import org.apache.cloudstack.api.command.user.network.ListNetworksCmd; -import org.apache.cloudstack.api.command.user.network.RestartNetworkCmd; -import org.apache.cloudstack.api.command.user.vm.ListNicsCmd; -import org.apache.log4j.Logger; -import org.springframework.stereotype.Component; @Component @@ -208,10 +197,16 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkManage } @Override - public IpAddress allocatePortableIP(Account ipOwner, int regionId, Long zoneId, Long networkId) throws ResourceAllocationException, InsufficientAddressCapacityException, ConcurrentOperationException { + public IpAddress allocatePortableIp(Account ipOwner, Account caller, long dcId, Long networkId, Long vpcID) + throws ConcurrentOperationException, ResourceAllocationException, InsufficientAddressCapacityException { return null;// TODO Auto-generated method stub } + @Override + public IpAddress allocatePortableIP(Account ipOwner, int regionId, Long zoneId, Long networkId, Long vpcId) throws ResourceAllocationException, + InsufficientAddressCapacityException, ConcurrentOperationException { + return null; + } /* (non-Javadoc) * @see com.cloud.network.NetworkService#releaseIpAddress(long)