diff --git a/api/src/com/cloud/event/EventTypes.java b/api/src/com/cloud/event/EventTypes.java index 9407a35c186..e2886a3ea6c 100755 --- a/api/src/com/cloud/event/EventTypes.java +++ b/api/src/com/cloud/event/EventTypes.java @@ -90,6 +90,8 @@ public class EventTypes { // Network Events public static final String EVENT_NET_IP_ASSIGN = "NET.IPASSIGN"; public static final String EVENT_NET_IP_RELEASE = "NET.IPRELEASE"; + public static final String EVENT_PORTABLE_IP_ASSIGN = "PORTABLE.IPASSIGN"; + public static final String EVENT_PORTABLE_RELEASE = "PORTABLEIPRELEASE"; public static final String EVENT_NET_RULE_ADD = "NET.RULEADD"; public static final String EVENT_NET_RULE_DELETE = "NET.RULEDELETE"; public static final String EVENT_NET_RULE_MODIFY = "NET.RULEMODIFY"; diff --git a/api/src/com/cloud/network/IpAddress.java b/api/src/com/cloud/network/IpAddress.java index 71c9b4e0bf3..835fa548236 100644 --- a/api/src/com/cloud/network/IpAddress.java +++ b/api/src/com/cloud/network/IpAddress.java @@ -81,4 +81,6 @@ public interface IpAddress extends ControlledEntity, Identity, InternalIdentity Long getVpcId(); String getVmIp(); + + boolean isPortable(); } diff --git a/api/src/com/cloud/network/NetworkService.java b/api/src/com/cloud/network/NetworkService.java index 6c9bebc1c15..0e9a5a76485 100755 --- a/api/src/com/cloud/network/NetworkService.java +++ b/api/src/com/cloud/network/NetworkService.java @@ -49,6 +49,9 @@ 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, + InsufficientAddressCapacityException, ConcurrentOperationException; + boolean releaseIpAddress(long ipAddressId) throws InsufficientAddressCapacityException; Network createGuestNetwork(CreateNetworkCmd cmd) throws InsufficientCapacityException, ConcurrentOperationException, diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java index e2a76e3c1b1..7e040ca9d91 100755 --- a/api/src/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/org/apache/cloudstack/api/ApiConstants.java @@ -108,6 +108,7 @@ public class ApiConstants { public static final String IS_CLEANUP_REQUIRED = "iscleanuprequired"; public static final String IS_EXTRACTABLE = "isextractable"; public static final String IS_FEATURED = "isfeatured"; + public static final String IS_PORTABLE = "isportable"; public static final String IS_PUBLIC = "ispublic"; public static final String IS_PERSISTENT = "ispersistent"; public static final String IS_READY = "isready"; 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 28fbae4437a..3aa3c4b5611 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 @@ -66,6 +66,14 @@ public class AssociateIPAddrCmd extends BaseAsyncCreateCmd { "be associated with") private Long vpcId; + @Parameter(name=ApiConstants.IS_PORTABLE, type = BaseCmd.CommandType.BOOLEAN, description = "should be set to true " + + "if public IP is required to be transferable across zones, if not specified defaults to false") + private Boolean isPortable; + + @Parameter(name=ApiConstants.REGION_ID, type=CommandType.INTEGER, entityType = RegionResponse.class, + required=false, description="region ID from where portable ip is to be associated.") + private Integer regionId; + ///////////////////////////////////////////////////// /////////////////// Accessors /////////////////////// ///////////////////////////////////////////////////// @@ -107,6 +115,18 @@ public class AssociateIPAddrCmd extends BaseAsyncCreateCmd { return vpcId; } + public boolean isPortable() { + if (isPortable == null) { + return false; + } else { + return isPortable; + } + } + + public Integer getRegionId() { + return regionId; + } + public Long getNetworkId() { if (vpcId != null) { return null; diff --git a/api/src/org/apache/cloudstack/api/response/IPAddressResponse.java b/api/src/org/apache/cloudstack/api/response/IPAddressResponse.java index cede84f931e..e3d5cc6a101 100644 --- a/api/src/org/apache/cloudstack/api/response/IPAddressResponse.java +++ b/api/src/org/apache/cloudstack/api/response/IPAddressResponse.java @@ -115,6 +115,9 @@ public class IPAddressResponse extends BaseResponse implements ControlledEntityR @SerializedName(ApiConstants.TAGS) @Param(description="the list of resource tags associated with ip address", responseObject = ResourceTagResponse.class) private List tags; + @SerializedName(ApiConstants.IS_PORTABLE) @Param(description = "is public IP portable across the zones") + private Boolean isPortable; + /* @SerializedName(ApiConstants.JOB_ID) @Param(description="shows the current pending asynchronous job ID. This tag is not returned if no current pending jobs are acting on the volume") private IdentityProxy jobId = new IdentityProxy("async_job"); @@ -247,4 +250,8 @@ public class IPAddressResponse extends BaseResponse implements ControlledEntityR public void setAssociatedNetworkName(String associatedNetworkName) { this.associatedNetworkName = associatedNetworkName; } + + public void setPortable(Boolean portable) { + this.isPortable = portable; + } } diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index 53506f3bf50..2820825aa45 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -727,6 +727,8 @@ public class ApiResponseHelper implements ResponseGenerator { } } + ipResponse.setPortable(ipAddr.isPortable()); + //set tag information List tags = ApiDBUtils.listByResourceTypeAndId(TaggedResourceType.PublicIpAddress, ipAddr.getId()); List tagResponses = new ArrayList(); diff --git a/server/src/com/cloud/network/NetworkServiceImpl.java b/server/src/com/cloud/network/NetworkServiceImpl.java index 2dcb47d0cd8..594ff7ee95c 100755 --- a/server/src/com/cloud/network/NetworkServiceImpl.java +++ b/server/src/com/cloud/network/NetworkServiceImpl.java @@ -444,6 +444,13 @@ public class NetworkServiceImpl extends ManagerBase implements NetworkService { return allocateIP(ipOwner, false, zoneId); } + @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) throws ResourceAllocationException, InsufficientAddressCapacityException, ConcurrentOperationException { Account caller = UserContext.current().getCaller(); diff --git a/server/src/com/cloud/network/addr/PublicIp.java b/server/src/com/cloud/network/addr/PublicIp.java index 25e9d308b14..c8f1d9d5cd9 100644 --- a/server/src/com/cloud/network/addr/PublicIp.java +++ b/server/src/com/cloud/network/addr/PublicIp.java @@ -219,4 +219,13 @@ public class PublicIp implements PublicIpAddress { public String getVmIp() { return _addr.getVmIp(); } + + @Override + public boolean isPortable() { + return _addr.isPortable(); + } + + public void setPortable(boolean portable) { + _addr.setPortable(portable); + } } diff --git a/server/src/com/cloud/network/dao/IPAddressVO.java b/server/src/com/cloud/network/dao/IPAddressVO.java index c5c78e557ae..1c8d749603b 100644 --- a/server/src/com/cloud/network/dao/IPAddressVO.java +++ b/server/src/com/cloud/network/dao/IPAddressVO.java @@ -115,6 +115,8 @@ public class IPAddressVO implements IpAddress { @Column(name="dnat_vmip") private String vmIp; + @Column(name="is_portable") + private boolean portable; protected IPAddressVO() { this.uuid = UUID.randomUUID().toString(); @@ -287,6 +289,15 @@ public class IPAddressVO implements IpAddress { this.system = isSystem; } + @Override + public boolean isPortable() { + return portable; + } + + public void setPortable(boolean portable) { + this.portable = portable; + } + @Override public Long getVpcId() { return vpcId; diff --git a/server/test/com/cloud/network/MockNetworkManagerImpl.java b/server/test/com/cloud/network/MockNetworkManagerImpl.java index e9987bd1b66..06be8b53b6e 100755 --- a/server/test/com/cloud/network/MockNetworkManagerImpl.java +++ b/server/test/com/cloud/network/MockNetworkManagerImpl.java @@ -822,6 +822,11 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkManage return null; } + @Override + public IpAddress allocatePortableIP(Account ipOwner, int regionId, Long zoneId, Long networkId) throws ResourceAllocationException, InsufficientAddressCapacityException, ConcurrentOperationException { + return null;// TODO Auto-generated method stub + } + @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 9b18358e258..82a80c1486a 100644 --- a/server/test/com/cloud/vpc/MockNetworkManagerImpl.java +++ b/server/test/com/cloud/vpc/MockNetworkManagerImpl.java @@ -176,13 +176,15 @@ public class MockNetworkManagerImpl extends ManagerBase implements NetworkManage return null; } - - + @Override + public IpAddress allocatePortableIP(Account ipOwner, int regionId, Long zoneId, Long networkId) throws ResourceAllocationException, InsufficientAddressCapacityException, ConcurrentOperationException { + return null;// TODO Auto-generated method stub + } /* (non-Javadoc) - * @see com.cloud.network.NetworkService#releaseIpAddress(long) - */ + * @see com.cloud.network.NetworkService#releaseIpAddress(long) + */ @Override public boolean releaseIpAddress(long ipAddressId) throws InsufficientAddressCapacityException { // TODO Auto-generated method stub diff --git a/setup/db/db/schema-410to420.sql b/setup/db/db/schema-410to420.sql index bda2c4c8c09..e89cf23bcf6 100644 --- a/setup/db/db/schema-410to420.sql +++ b/setup/db/db/schema-410to420.sql @@ -1144,3 +1144,5 @@ CREATE TABLE `cloud`.`portable_ip_address` ( CONSTRAINT `fk_portable_ip_address__portable_ip_range_id` FOREIGN KEY (`portable_ip_range_id`) REFERENCES `portable_ip_range`(`id`) ON DELETE CASCADE, CONSTRAINT `fk_portable_ip_address__region_id` FOREIGN KEY (`region_id`) REFERENCES `region`(`id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +ALTER TABLE `cloud`.`user_ip_address` ADD COLUMN is_portable int(1) unsigned NOT NULL default '0';