Introdcues notion of 'portable IP' pool at region level.

Introduces root admin only API's to provision portable ip to a region
   - createPortableIpRange
   - deletePortableIpRange
   - listPortableIpRanges
This commit is contained in:
Murali Reddy 2013-05-11 14:36:01 +05:30
parent 271f8759be
commit e7b2fb2255
27 changed files with 1464 additions and 11 deletions

View File

@ -35,6 +35,7 @@ public interface AsyncJob extends Identity, InternalIdentity {
Host,
StoragePool,
IpAddress,
PortableIpAddress,
SecurityGroup,
PhysicalNetwork,
TrafficType,

View File

@ -34,6 +34,9 @@ import org.apache.cloudstack.api.command.admin.offering.UpdateDiskOfferingCmd;
import org.apache.cloudstack.api.command.admin.offering.UpdateServiceOfferingCmd;
import org.apache.cloudstack.api.command.admin.pod.DeletePodCmd;
import org.apache.cloudstack.api.command.admin.pod.UpdatePodCmd;
import org.apache.cloudstack.api.command.admin.region.CreatePortableIpRangeCmd;
import org.apache.cloudstack.api.command.admin.region.DeletePortableIpRangeCmd;
import org.apache.cloudstack.api.command.admin.region.ListPortableIpRangesCmd;
import org.apache.cloudstack.api.command.admin.vlan.CreateVlanIpRangeCmd;
import org.apache.cloudstack.api.command.admin.vlan.DedicatePublicIpRangeCmd;
import org.apache.cloudstack.api.command.admin.vlan.DeleteVlanIpRangeCmd;
@ -55,6 +58,7 @@ import com.cloud.offering.DiskOffering;
import com.cloud.offering.NetworkOffering;
import com.cloud.offering.ServiceOffering;
import com.cloud.user.Account;
import org.apache.cloudstack.region.PortableIpRange;
public interface ConfigurationService {
@ -277,4 +281,10 @@ public interface ConfigurationService {
* @return
*/
boolean isOfferingForVpc(NetworkOffering offering);
PortableIpRange createPortableIpRange(CreatePortableIpRangeCmd cmd) throws ConcurrentOperationException;
boolean deletePortableIpRange(DeletePortableIpRangeCmd cmd);
List<? extends PortableIpRange> listPortableIpRanges(ListPortableIpRangesCmd cmd);
}

View File

@ -390,6 +390,9 @@ public class EventTypes {
public static final String EVENT_AFFINITY_GROUP_REMOVE = "AG.REMOVE";
public static final String EVENT_VM_AFFINITY_GROUP_UPDATE = "VM.AG.UPDATE";
public static final String EVENT_PORTABLE_IP_RANGE_CREATE = "PORTABLE.IP.RANGE.CREATE";
public static final String EVENT_PORTABLE_IP_RANGE_DELETE = "PORTABLE.IP.RANGE.DELETE";
static {
// TODO: need a way to force author adding event types to declare the entity details as well, with out braking

View File

@ -102,6 +102,7 @@ import org.apache.cloudstack.api.response.VpcOfferingResponse;
import org.apache.cloudstack.api.response.VpcResponse;
import org.apache.cloudstack.api.response.VpnUsersResponse;
import org.apache.cloudstack.api.response.ZoneResponse;
import org.apache.cloudstack.region.PortableIpRange;
import org.apache.cloudstack.region.Region;
import org.apache.cloudstack.usage.Usage;
@ -396,4 +397,6 @@ public interface ResponseGenerator {
AffinityGroupResponse createAffinityGroupResponse(AffinityGroup group);
Long getAffinityGroupId(String name, long entityOwnerId);
PortableIpRangeResponse createPortableIPRangeResponse(PortableIpRange range);
}

View File

@ -0,0 +1,156 @@
// 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 org.apache.cloudstack.api.command.admin.region;
import javax.inject.Inject;
import com.cloud.async.AsyncJob;
import com.cloud.dc.Vlan;
import com.cloud.event.EventTypes;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.ResourceAllocationException;
import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseAsyncCreateCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.PortableIpRangeResponse;
import org.apache.cloudstack.api.response.RegionResponse;
import org.apache.cloudstack.api.response.VlanIpRangeResponse;
import org.apache.cloudstack.region.PortableIpRange;
import org.apache.cloudstack.region.Region;
import org.apache.cloudstack.region.RegionService;
import org.apache.log4j.Logger;
import com.cloud.user.Account;
@APICommand(name = "createPortableIpRange", responseObject=PortableIpRangeResponse.class, description="adds a range of portable public IP's to a region", since="4.2.0")
public class CreatePortableIpRangeCmd extends BaseAsyncCreateCmd {
public static final Logger s_logger = Logger.getLogger(CreatePortableIpRangeCmd.class.getName());
private static final String s_name = "createportableiprangeresponse";
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name=ApiConstants.REGION_ID, type=CommandType.INTEGER, entityType = RegionResponse.class, required=true, description="Id of the Region")
private Integer regionId;
@Parameter(name=ApiConstants.START_IP, type=CommandType.STRING, required=true, description="the beginning IP address in the portable IP range")
private String startIp;
@Parameter(name=ApiConstants.END_IP, type=CommandType.STRING, required=true, description="the ending IP address in the portable IP range")
private String endIp;
@Parameter(name=ApiConstants.GATEWAY, type=CommandType.STRING, required=true, description="the gateway for the portable IP range")
private String gateway;
@Parameter(name=ApiConstants.NETMASK, type=CommandType.STRING, required=true, description="the netmask of the portable IP range")
private String netmask;
@Parameter(name=ApiConstants.VLAN, type=CommandType.STRING, description="VLAN id, if not specified defaulted to untagged")
private String vlan;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public Integer getRegionId() {
return regionId;
}
public String getStartIp() {
return startIp;
}
public String getEndIp() {
return endIp;
}
public String getVlan() {
return vlan;
}
public String getGateway() {
return gateway;
}
public String getNetmask() {
return netmask;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public String getCommandName() {
return s_name;
}
@Override
public long getEntityOwnerId() {
return Account.ACCOUNT_ID_SYSTEM;
}
@Override
public void execute(){
PortableIpRange portableIpRange = _entityMgr.findById(PortableIpRange.class, getEntityId());
PortableIpRangeResponse response = null;
if (portableIpRange != null) {
response = _responseGenerator.createPortableIPRangeResponse(portableIpRange);
}
response.setResponseName(getCommandName());
this.setResponseObject(response);
}
@Override
public void create() throws ResourceAllocationException {
try {
PortableIpRange portableIpRange = _configService.createPortableIpRange(this);
if (portableIpRange != null) {
this.setEntityId(portableIpRange.getId());
this.setEntityUuid(portableIpRange.getUuid());
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to create portable public IP range");
}
} catch (ConcurrentOperationException ex) {
s_logger.warn("Exception: ", ex);
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, ex.getMessage());
}
}
@Override
public String getEventType() {
return EventTypes.EVENT_PORTABLE_IP_RANGE_CREATE;
}
@Override
public String getEventDescription() {
return "creating a portable public ip range in region: " + getRegionId();
}
@Override
public AsyncJob.Type getInstanceType() {
return AsyncJob.Type.PortableIpAddress;
}
}

View File

@ -0,0 +1,93 @@
// 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 org.apache.cloudstack.api.command.admin.region;
import javax.inject.Inject;
import com.cloud.async.AsyncJob;
import com.cloud.event.EventTypes;
import org.apache.cloudstack.api.*;
import org.apache.cloudstack.api.response.PortableIpRangeResponse;
import org.apache.cloudstack.api.response.RegionResponse;
import org.apache.cloudstack.api.response.SuccessResponse;
import org.apache.cloudstack.region.Region;
import org.apache.cloudstack.region.RegionService;
import org.apache.log4j.Logger;
import com.cloud.user.Account;
@APICommand(name = "deletePortableIpRange", description="deletes a range of portable public IP's associated with a region", responseObject=SuccessResponse.class)
public class DeletePortableIpRangeCmd extends BaseAsyncCmd {
public static final Logger s_logger = Logger.getLogger(DeletePortableIpRangeCmd.class.getName());
private static final String s_name = "deleteportablepublicipresponse";
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name=ApiConstants.ID, type=CommandType.UUID, required=true, entityType = PortableIpRangeResponse.class, description="Id of the portable ip range")
private Long id;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public Long getId() {
return id;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public String getCommandName() {
return s_name;
}
@Override
public long getEntityOwnerId() {
return Account.ACCOUNT_ID_SYSTEM;
}
@Override
public void execute(){
boolean result = _configService.deletePortableIpRange(this);
if (result) {
SuccessResponse response = new SuccessResponse(getCommandName());
this.setResponseObject(response);
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to delete portable ip range");
}
}
@Override
public String getEventType() {
return EventTypes.EVENT_PORTABLE_IP_RANGE_DELETE;
}
@Override
public String getEventDescription() {
return "deleting a portable public ip range";
}
@Override
public AsyncJob.Type getInstanceType() {
return AsyncJob.Type.PortableIpAddress;
}
}

View File

@ -0,0 +1,96 @@
// 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 org.apache.cloudstack.api.command.admin.region;
import javax.inject.Inject;
import org.apache.cloudstack.api.*;
import org.apache.cloudstack.api.response.ListResponse;
import org.apache.cloudstack.api.response.PortableIpRangeResponse;
import org.apache.cloudstack.api.response.RegionResponse;
import org.apache.cloudstack.region.PortableIpRange;
import org.apache.cloudstack.region.Region;
import org.apache.cloudstack.region.RegionService;
import org.apache.log4j.Logger;
import com.cloud.user.Account;
import java.util.ArrayList;
import java.util.List;
@APICommand(name = "listPortableIpRanges", description="list portable IP ranges", responseObject=PortableIpRangeResponse.class)
public class ListPortableIpRangesCmd extends BaseListCmd {
public static final Logger s_logger = Logger.getLogger(ListPortableIpRangesCmd.class.getName());
private static final String s_name = "listportableipresponse";
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
/////////////////////////////////////////////////////
@Parameter(name=ApiConstants.REGION_ID, type=CommandType.INTEGER, required=false, description="Id of a Region")
private Integer regionId;
@Parameter(name=ApiConstants.ID, type=CommandType.UUID, required=false, entityType = PortableIpRangeResponse.class, description="Id of the portable ip range")
private Long id;
/////////////////////////////////////////////////////
/////////////////// Accessors ///////////////////////
/////////////////////////////////////////////////////
public Integer getRegionIdId() {
return regionId;
}
public Long getPortableIpRangeId() {
return id;
}
/////////////////////////////////////////////////////
/////////////// API Implementation///////////////////
/////////////////////////////////////////////////////
@Override
public String getCommandName() {
return s_name;
}
@Override
public long getEntityOwnerId() {
return Account.ACCOUNT_ID_SYSTEM;
}
@Override
public void execute(){
ListResponse<PortableIpRangeResponse> response = new ListResponse<PortableIpRangeResponse>();
List<PortableIpRangeResponse> responses = new ArrayList<PortableIpRangeResponse>();
List<? extends PortableIpRange> portableIpRanges = new ArrayList<PortableIpRange>();
portableIpRanges = _configService.listPortableIpRanges(this);
if (portableIpRanges != null && !portableIpRanges.isEmpty()) {
for (PortableIpRange range : portableIpRanges) {
PortableIpRangeResponse rangeResponse = _responseGenerator.createPortableIPRangeResponse(range);
rangeResponse.setObjectName("portableiprange");
responses.add(rangeResponse);
}
}
response.setResponses(responses, portableIpRanges.size());
response.setResponseName(getCommandName());
this.setResponseObject(response);
}
}

View File

@ -0,0 +1,86 @@
// 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 org.apache.cloudstack.api.response;
import java.util.Date;
import java.util.List;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseResponse;
import org.apache.cloudstack.api.EntityReference;
import com.cloud.network.IpAddress;
import com.cloud.serializer.Param;
import com.google.gson.annotations.SerializedName;
import org.apache.cloudstack.region.PortableIpRange;
@EntityReference(value=PortableIpRange.class)
public class PortableIpRangeResponse extends BaseResponse {
@SerializedName(ApiConstants.ID)
@Param(description = "portable IP range ID")
private String id;
@SerializedName(ApiConstants.REGION_ID)
@Param(description = "Region Id in which portable ip range is provisioned")
private Integer regionId;
@SerializedName(ApiConstants.GATEWAY) @Param(description="the gateway of the VLAN IP range")
private String gateway;
@SerializedName(ApiConstants.NETMASK) @Param(description="the netmask of the VLAN IP range")
private String netmask;
@SerializedName(ApiConstants.VLAN) @Param(description="the ID or VID of the VLAN.")
private String vlan;
@SerializedName(ApiConstants.START_IP) @Param(description="the start ip of the portable IP range")
private String startIp;
@SerializedName(ApiConstants.END_IP) @Param(description="the end ip of the portable IP range")
private String endIp;
public void setId(String id) {
this.id = id;
}
public void setRegionId(int regionId) {
this.regionId = regionId;
}
public void setStartIp(String startIp) {
this.startIp = startIp;
}
public void setEndIp(String endIp) {
this.endIp = endIp;
}
public void setNetmask(String netmask) {
this.netmask = netmask;
}
public void setGateway(String gateway) {
this.gateway = gateway;
}
public void setVlan(String vlan) {
this.vlan = vlan;
}
}

View File

@ -0,0 +1,106 @@
// 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 org.apache.cloudstack.api.response;
import java.util.Date;
import java.util.List;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.BaseResponse;
import org.apache.cloudstack.api.EntityReference;
import com.cloud.network.IpAddress;
import com.cloud.serializer.Param;
import com.google.gson.annotations.SerializedName;
import org.apache.cloudstack.region.PortableIp;
import org.apache.cloudstack.region.PortableIpRange;
@EntityReference(value=PortableIp.class)
public class PortableIpResponse extends BaseResponse {
@SerializedName(ApiConstants.REGION_ID)
@Param(description = "Region Id in which global load balancer is created")
private Integer regionId;
@SerializedName(ApiConstants.IP_ADDRESS) @Param(description="public IP address")
private String ipAddress;
@SerializedName(ApiConstants.ZONE_ID) @Param(description="the ID of the zone the public IP address belongs to")
private String zoneId;
@SerializedName(ApiConstants.NETWORK_ID) @Param(description="the ID of the Network where ip belongs to")
private String networkId;
@SerializedName(ApiConstants.VPC_ID) @Param(description="VPC the ip belongs to")
private String vpcId;
@SerializedName(ApiConstants.PHYSICAL_NETWORK_ID) @Param(description="the physical network this belongs to")
private String physicalNetworkId;
@SerializedName(ApiConstants.ACCOUNT_ID) @Param(description="the account ID the portable IP address is associated with")
private String accountId;
@SerializedName(ApiConstants.DOMAIN_ID) @Param(description="the domain ID the portable IP address is associated with")
private String domainId;
@SerializedName("allocated") @Param(description="date the portal IP address was acquired")
private Date allocated;
@SerializedName(ApiConstants.STATE) @Param(description="State of the ip address. Can be: Allocatin, Allocated and Releasing")
private String state;
public void setRegionId(Integer regionId) {
this.regionId = regionId;
}
public void setAddress(String ipAddress) {
this.ipAddress = ipAddress;
}
public void setAssociatedDataCenterId(String zoneId) {
this.zoneId = zoneId;
}
public void setAssociatedWithNetworkId(String networkId) {
this.networkId = networkId;
}
public void setAssociatedWithVpcId(String vpcId) {
this.vpcId = vpcId;
}
public void setPhysicalNetworkId(String physicalNetworkId) {
this.physicalNetworkId = physicalNetworkId;
}
public void setAllocatedToAccountId(String accountId) {
this.accountId = accountId;
}
public void setAllocatedInDomainId(String domainId) {
this.domainId = domainId;
}
public void setAllocatedTime(Date allocatedTimetime) {
this.allocated = allocatedTimetime;
}
public void setState(String state) {
this.state = state;
}
}

View File

@ -0,0 +1,58 @@
// 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 org.apache.cloudstack.region;
import java.util.Date;
import com.cloud.utils.net.Ip;
import org.apache.cloudstack.api.InternalIdentity;
public interface PortableIp extends InternalIdentity {
enum State {
Allocating, // The IP Address is being propagated to other network elements and is not ready for use yet.
Allocated, // The IP address is in used.
Releasing, // The IP address is being released for other network elements and is not ready for allocation.
Free // The IP address is ready to be allocated.
}
Long getAllocatedToAccountId();
Long getAllocatedInDomainId();
Date getAllocatedTime();
State getState();
int getRegionId();
Long getAssociatedDataCenterId();
Long getAssociatedWithNetworkId();
Long getAssociatedWithVpcId();
Long getPhysicalNetworkId();
String getAddress();
String getVlan();
String getNetmask();
String getGateway();
}

View File

@ -0,0 +1,38 @@
// 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 org.apache.cloudstack.region;
import org.apache.cloudstack.acl.InfrastructureEntity;
import org.apache.cloudstack.api.Identity;
import org.apache.cloudstack.api.InternalIdentity;
public interface PortableIpRange extends InfrastructureEntity, InternalIdentity, Identity {
public final static String UNTAGGED = "untagged";
public String getVlanTag();
public String getGateway();
public String getNetmask();
public int getRegionId();
public String getIpRange();
}

View File

@ -267,6 +267,8 @@
<bean id="physicalNetworkTrafficTypeDaoImpl" class="com.cloud.network.dao.PhysicalNetworkTrafficTypeDaoImpl" />
<bean id="podVlanDaoImpl" class="com.cloud.dc.dao.PodVlanDaoImpl" />
<bean id="podVlanMapDaoImpl" class="com.cloud.dc.dao.PodVlanMapDaoImpl" />
<bean id="PortableIpDaoImpl" class="org.apache.cloudstack.region.PortableIpDaoImpl" />
<bean id="PortableIpRangeDaoImpl" class="org.apache.cloudstack.region.PortableIpRangeDaoImpl" />
<bean id="portForwardingRulesDaoImpl" class="com.cloud.network.rules.dao.PortForwardingRulesDaoImpl" />
<bean id="portProfileDaoImpl" class="com.cloud.network.dao.PortProfileDaoImpl" />
<bean id="primaryDataStoreDaoImpl" class="org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDaoImpl" />

View File

@ -591,3 +591,7 @@ addCiscoAsa1000vResource=1
deleteCiscoAsa1000vResource=1
listCiscoAsa1000vResources=1
#### portable public IP commands
createPortableIpRange=1
deletePortableIpRange=1
listPortableIpRanges=1

View File

@ -127,6 +127,7 @@ import org.apache.cloudstack.api.response.VpcOfferingResponse;
import org.apache.cloudstack.api.response.VpcResponse;
import org.apache.cloudstack.api.response.VpnUsersResponse;
import org.apache.cloudstack.api.response.ZoneResponse;
import org.apache.cloudstack.region.PortableIpRange;
import org.apache.cloudstack.region.Region;
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
import org.apache.cloudstack.usage.Usage;
@ -3714,4 +3715,21 @@ public class ApiResponseHelper implements ResponseGenerator {
return ag.getId();
}
}
@Override
public PortableIpRangeResponse createPortableIPRangeResponse(PortableIpRange ipRange) {
PortableIpRangeResponse response = new PortableIpRangeResponse();
response.setId(ipRange.getUuid());
String ipRangeStr = ipRange.getIpRange();
if (ipRangeStr != null) {
String[] range = ipRangeStr.split("-");
response.setStartIp(range[0]);
response.setEndIp(range[1]);
}
response.setVlan(ipRange.getVlanTag());
response.setGateway(ipRange.getGateway());
response.setNetmask(ipRange.getNetmask());
response.setRegionId(ipRange.getRegionId());
return response;
}
}

View File

@ -56,6 +56,9 @@ import org.apache.cloudstack.api.command.admin.offering.UpdateDiskOfferingCmd;
import org.apache.cloudstack.api.command.admin.offering.UpdateServiceOfferingCmd;
import org.apache.cloudstack.api.command.admin.pod.DeletePodCmd;
import org.apache.cloudstack.api.command.admin.pod.UpdatePodCmd;
import org.apache.cloudstack.api.command.admin.region.CreatePortableIpRangeCmd;
import org.apache.cloudstack.api.command.admin.region.DeletePortableIpRangeCmd;
import org.apache.cloudstack.api.command.admin.region.ListPortableIpRangesCmd;
import org.apache.cloudstack.api.command.admin.vlan.CreateVlanIpRangeCmd;
import org.apache.cloudstack.api.command.admin.vlan.DedicatePublicIpRangeCmd;
import org.apache.cloudstack.api.command.admin.vlan.DeleteVlanIpRangeCmd;
@ -64,6 +67,8 @@ import org.apache.cloudstack.api.command.admin.zone.CreateZoneCmd;
import org.apache.cloudstack.api.command.admin.zone.DeleteZoneCmd;
import org.apache.cloudstack.api.command.admin.zone.UpdateZoneCmd;
import org.apache.cloudstack.api.command.user.network.ListNetworkOfferingsCmd;
import org.apache.cloudstack.region.*;
import org.apache.cloudstack.region.dao.RegionDao;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
@ -245,6 +250,12 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
FirewallRulesDao _firewallDao;
@Inject
VpcManager _vpcMgr;
@Inject
PortableIpRangeDao _portableIpRangeDao;
@Inject
RegionDao _regionDao;
@Inject
PortableIpDao _portableIpDao;
// FIXME - why don't we have interface for DataCenterLinkLocalIpAddressDao?
@Inject protected DataCenterLinkLocalIpAddressDao _LinkLocalIpAllocDao;
@ -4265,4 +4276,140 @@ public class ConfigurationManagerImpl extends ManagerBase implements Configurati
return null;
}
@Override
@DB
@ActionEvent(eventType = EventTypes.EVENT_PORTABLE_IP_RANGE_CREATE, eventDescription = "creating portable ip range", async = false)
public PortableIpRange createPortableIpRange(CreatePortableIpRangeCmd cmd) throws ConcurrentOperationException {
Integer regionId = cmd.getRegionId();
String startIP = cmd.getStartIp();
String endIP = cmd.getEndIp();
String gateway = cmd.getGateway();
String netmask = cmd.getNetmask();
Long userId = UserContext.current().getCallerUserId();
String vlanId = cmd.getVlan();
Region region = _regionDao.findById(regionId);
if (region == null) {
throw new InvalidParameterValueException("Invalid region ID: " + regionId);
}
if (!NetUtils.isValidIp(startIP) || !NetUtils.isValidIp(endIP) || !NetUtils.validIpRange(startIP, endIP)) {
throw new InvalidParameterValueException("Invalid portable ip range: " + startIP + "-" + endIP);
}
if (!NetUtils.sameSubnet(startIP, gateway, netmask)) {
throw new InvalidParameterValueException("Please ensure that your start IP is in the same subnet as " +
"your portable IP range's gateway and as per the IP range's netmask.");
}
if (!NetUtils.sameSubnet(endIP, gateway, netmask)) {
throw new InvalidParameterValueException("Please ensure that your end IP is in the same subnet as " +
"your portable IP range's gateway and as per the IP range's netmask.");
}
if (checkOverlapPortableIpRange(regionId, startIP, endIP)) {
throw new InvalidParameterValueException("Ip range: " + startIP + "-" + endIP + " overlaps with a portable" +
" IP range already configured in the region " + regionId);
}
if (vlanId == null) {
vlanId = Vlan.UNTAGGED;
} else {
if (!NetUtils.isValidVlan(vlanId)) {
throw new InvalidParameterValueException("Invalid vlan id " + vlanId);
}
}
Transaction txn = Transaction.currentTxn();
txn.start();
PortableIpRangeVO portableIpRange = new PortableIpRangeVO(regionId, vlanId, gateway, netmask, startIP, endIP);
portableIpRange = _portableIpRangeDao.persist(portableIpRange);
long startIpLong = NetUtils.ip2Long(startIP);
long endIpLong = NetUtils.ip2Long(endIP);
while(startIpLong <= endIpLong) {
PortableIpVO portableIP = new PortableIpVO(regionId, portableIpRange.getId(), vlanId,
gateway, netmask,NetUtils.long2Ip(startIpLong));
_portableIpDao.persist(portableIP);
startIpLong++;
}
txn.commit();
return portableIpRange;
}
@Override
@DB
@ActionEvent(eventType = EventTypes.EVENT_PORTABLE_IP_RANGE_DELETE, eventDescription = "deleting portable ip range", async = false)
public boolean deletePortableIpRange(DeletePortableIpRangeCmd cmd) {
long rangeId = cmd.getId();
PortableIpRangeVO portableIpRange = _portableIpRangeDao.findById(rangeId);
if (portableIpRange == null) {
throw new InvalidParameterValueException("Please specify a valid portable IP range id.");
}
List<PortableIpVO> fullIpRange = _portableIpDao.listByRangeId(portableIpRange.getId());
List<PortableIpVO> freeIpRange = _portableIpDao.listByRangeIdAndState(portableIpRange.getId(), PortableIp.State.Free);
if (fullIpRange != null && freeIpRange != null) {
if (fullIpRange.size() == freeIpRange.size()) {
_portableIpRangeDao.expunge(portableIpRange.getId());
return true;
} else {
throw new InvalidParameterValueException("Can't delete portable IP range as there are IP's assigned.");
}
}
return false;
}
@Override
public List<? extends PortableIpRange> listPortableIpRanges(ListPortableIpRangesCmd cmd) {
Integer regionId = cmd.getRegionIdId();
Long rangeId = cmd.getPortableIpRangeId();
List <PortableIpRangeVO> ranges = new ArrayList<PortableIpRangeVO>();
if (regionId != null) {
Region region = _regionDao.findById(regionId);
if (region == null) {
throw new InvalidParameterValueException("Invalid region ID: " + regionId);
}
return _portableIpRangeDao.listByRegionId(regionId);
}
if (rangeId != null) {
PortableIpRangeVO range = _portableIpRangeDao.findById(rangeId);
if (range == null) {
throw new InvalidParameterValueException("Invalid portable IP range ID: " + regionId);
}
ranges.add(range);
return ranges;
}
return _portableIpRangeDao.listAll();
}
private boolean checkOverlapPortableIpRange(int regionId, String newStartIpStr, String newEndIpStr) {
long newStartIp = NetUtils.ip2Long(newStartIpStr);
long newEndIp = NetUtils.ip2Long(newEndIpStr);
List<PortableIpRangeVO> existingPortableIPRanges = _portableIpRangeDao.listByRegionId(regionId);
for (PortableIpRangeVO portableIpRange : existingPortableIPRanges) {
String ipRangeStr = portableIpRange.getIpRange();
String[] range = ipRangeStr.split("-");
long startip = NetUtils.ip2Long(range[0]);
long endIp = NetUtils.ip2Long(range[1]);
if ((newStartIp >= startip && newStartIp <= endIp) || (newEndIp >= startip && newEndIp <= endIp)) {
return true;
}
if ((startip >= newStartIp && startip <= newEndIp) || (endIp >= newStartIp && endIp <= newEndIp)) {
return true;
}
}
return false;
}
}

View File

@ -34,7 +34,6 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
import java.util.UUID;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@ -56,6 +55,7 @@ import org.apache.cloudstack.api.command.admin.domain.*;
import org.apache.cloudstack.api.command.admin.host.*;
import org.apache.cloudstack.api.command.admin.network.*;
import org.apache.cloudstack.api.command.admin.offering.*;
import org.apache.cloudstack.api.command.admin.region.*;
import org.apache.cloudstack.api.command.admin.resource.*;
import org.apache.cloudstack.api.command.admin.router.*;
import org.apache.cloudstack.api.command.admin.storage.*;
@ -114,7 +114,6 @@ import com.cloud.dc.*;
import com.cloud.dc.Vlan.VlanType;
import com.cloud.dc.dao.*;
import com.cloud.deploy.DataCenterDeployment;
import com.cloud.deploy.DeploymentPlanner;
import com.cloud.deploy.DeploymentPlanner.ExcludeList;
import com.cloud.domain.DomainVO;
import com.cloud.domain.dao.DomainDao;
@ -148,7 +147,6 @@ import com.cloud.projects.ProjectManager;
import com.cloud.resource.ResourceManager;
import com.cloud.server.ResourceTag.TaggedResourceType;
import com.cloud.server.auth.UserAuthenticator;
import com.cloud.service.ServiceOfferingVO;
import com.cloud.service.dao.ServiceOfferingDao;
import com.cloud.storage.*;
import com.cloud.storage.Storage.ImageFormat;
@ -203,9 +201,7 @@ import org.apache.cloudstack.api.command.admin.pod.CreatePodCmd;
import org.apache.cloudstack.api.command.admin.pod.DeletePodCmd;
import org.apache.cloudstack.api.command.admin.pod.ListPodsByCmd;
import org.apache.cloudstack.api.command.admin.pod.UpdatePodCmd;
import org.apache.cloudstack.api.command.admin.region.AddRegionCmd;
import org.apache.cloudstack.api.command.admin.region.RemoveRegionCmd;
import org.apache.cloudstack.api.command.admin.region.UpdateRegionCmd;
import org.apache.cloudstack.api.command.admin.region.ListPortableIpRangesCmd;
import org.apache.cloudstack.api.command.admin.swift.AddSwiftCmd;
import org.apache.cloudstack.api.command.admin.swift.ListSwiftsCmd;
import org.apache.cloudstack.api.command.admin.template.PrepareTemplateCmd;
@ -2496,6 +2492,9 @@ public class ManagementServerImpl extends ManagerBase implements ManagementServe
cmdList.add(ListAffinityGroupsCmd.class);
cmdList.add(UpdateVMAffinityGroupCmd.class);
cmdList.add(ListAffinityGroupTypesCmd.class);
cmdList.add(CreatePortableIpRangeCmd.class);
cmdList.add(DeletePortableIpRangeCmd.class);
cmdList.add(ListPortableIpRangesCmd.class);
return cmdList;
}

View File

@ -0,0 +1,34 @@
// 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 org.apache.cloudstack.region;
import java.util.List;
import com.cloud.dc.Vlan;
import com.cloud.dc.Vlan.VlanType;
import com.cloud.dc.VlanVO;
import com.cloud.utils.db.GenericDao;
public interface PortableIpDao extends GenericDao<PortableIpVO, Long> {
List<PortableIpVO> listByRegionId(int regionId);
List<PortableIpVO> listByRangeId(long rangeId);
List<PortableIpVO> listByRangeIdAndState(long rangeId, PortableIp.State state);
}

View File

@ -0,0 +1,91 @@
// 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 org.apache.cloudstack.region;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.ejb.Local;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import org.springframework.stereotype.Component;
import com.cloud.dc.AccountVlanMapVO;
import com.cloud.dc.PodVlanMapVO;
import com.cloud.dc.Vlan;
import com.cloud.dc.Vlan.VlanType;
import com.cloud.dc.VlanVO;
import com.cloud.network.dao.IPAddressDao;
import com.cloud.utils.Pair;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.JoinBuilder;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.exception.CloudRuntimeException;
@Component
@Local(value={PortableIpDao.class})
public class PortableIpDaoImpl extends GenericDaoBase<PortableIpVO, Long> implements PortableIpDao {
private final SearchBuilder<PortableIpVO> listByRegionIDSearch;
private final SearchBuilder<PortableIpVO> listByRangeIDSearch;
private final SearchBuilder<PortableIpVO> listByRangeIDAndStateSearch;
public PortableIpDaoImpl() {
listByRegionIDSearch = createSearchBuilder();
listByRegionIDSearch.and("regionId", listByRegionIDSearch.entity().getRegionId(), SearchCriteria.Op.EQ);
listByRegionIDSearch.done();
listByRangeIDSearch = createSearchBuilder();
listByRangeIDSearch.and("rangeId", listByRangeIDSearch.entity().getRangeId(), SearchCriteria.Op.EQ);
listByRangeIDSearch.done();
listByRangeIDAndStateSearch = createSearchBuilder();
listByRangeIDAndStateSearch.and("rangeId", listByRangeIDAndStateSearch.entity().getRangeId(), SearchCriteria.Op.EQ);
listByRangeIDAndStateSearch.and("state", listByRangeIDAndStateSearch.entity().getState(), SearchCriteria.Op.EQ);
listByRangeIDAndStateSearch.done();
}
@Override
public List<PortableIpVO> listByRegionId(int regionIdId) {
SearchCriteria<PortableIpVO> sc = listByRegionIDSearch.create();
sc.setParameters("regionId", regionIdId);
return listBy(sc);
}
@Override
public List<PortableIpVO> listByRangeId(long rangeId) {
SearchCriteria<PortableIpVO> sc = listByRangeIDSearch.create();
sc.setParameters("rangeId", rangeId);
return listBy(sc);
}
@Override
public List<PortableIpVO> listByRangeIdAndState(long rangeId, PortableIp.State state) {
SearchCriteria<PortableIpVO> sc = listByRangeIDAndStateSearch.create();
sc.setParameters("rangeId", rangeId);
sc.setParameters("state", state);
return listBy(sc);
}
}

View File

@ -0,0 +1,30 @@
// 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 org.apache.cloudstack.region;
import java.util.List;
import com.cloud.dc.Vlan;
import com.cloud.dc.Vlan.VlanType;
import com.cloud.dc.VlanVO;
import com.cloud.utils.db.GenericDao;
public interface PortableIpRangeDao extends GenericDao<PortableIpRangeVO, Long> {
List<PortableIpRangeVO> listByRegionId(int regionId);
}

View File

@ -0,0 +1,65 @@
// 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 org.apache.cloudstack.region;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.ejb.Local;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import org.springframework.stereotype.Component;
import com.cloud.dc.AccountVlanMapVO;
import com.cloud.dc.PodVlanMapVO;
import com.cloud.dc.Vlan;
import com.cloud.dc.Vlan.VlanType;
import com.cloud.dc.VlanVO;
import com.cloud.network.dao.IPAddressDao;
import com.cloud.utils.Pair;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.JoinBuilder;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.exception.CloudRuntimeException;
@Component
@Local(value={PortableIpRangeDao.class})
public class PortableIpRangeDaoImpl extends GenericDaoBase<PortableIpRangeVO, Long> implements PortableIpRangeDao {
private final SearchBuilder<PortableIpRangeVO> listByRegionIDSearch;
public PortableIpRangeDaoImpl() {
listByRegionIDSearch = createSearchBuilder();
listByRegionIDSearch.and("regionId", listByRegionIDSearch.entity().getRegionId(), SearchCriteria.Op.EQ);
listByRegionIDSearch.done();
}
@Override
public List<PortableIpRangeVO> listByRegionId(int regionIdId) {
SearchCriteria<PortableIpRangeVO> sc = listByRegionIDSearch.create();
sc.setParameters("regionId", regionIdId);
return listBy(sc);
}
}

View File

@ -0,0 +1,119 @@
// 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 org.apache.cloudstack.region;
import java.util.UUID;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import org.apache.cloudstack.api.Identity;
import org.apache.cloudstack.api.InternalIdentity;
@Entity
@Table(name="portable_ip_range")
public class PortableIpRangeVO implements PortableIpRange {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="id")
Long id;
@Column(name="uuid")
String uuid;
@Column(name="region_id")
int regionId;
@Column(name="vlan_id")
String vlan;
@Column(name="gateway")
String gateway;
@Column(name="netmask")
String netmask;
@Column(name="start_ip")
String startIp;
@Column(name="end_ip")
String endIp;
public PortableIpRangeVO() {
this.uuid = UUID.randomUUID().toString();
}
public PortableIpRangeVO(int regionId, String vlan, String gateway, String netmask, String startIp, String endIp) {
this.uuid = UUID.randomUUID().toString();
this.regionId =regionId;
this.vlan = vlan;
this.gateway = gateway;
this.netmask = netmask;
this.startIp = startIp;
this.endIp = endIp;
}
@Override
public long getId() {
return id;
}
@Override
public String getUuid() {
return this.uuid;
}
public void setUuid(String uuid) {
this.uuid = uuid;
}
@Override
public String getVlanTag() {
return vlan;
}
public void setVlanTag(String vlan) {
this.vlan = vlan;
}
@Override
public String getGateway() {
return gateway;
}
@Override
public String getNetmask() {
return netmask;
}
@Override
public int getRegionId() {
return regionId;
}
@Override
public String getIpRange() {
return startIp + "-" + endIp;
}
}

View File

@ -0,0 +1,222 @@
// 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 org.apache.cloudstack.region;
import java.util.Date;
import java.util.UUID;
import javax.persistence.*;
import org.apache.cloudstack.api.Identity;
import org.apache.cloudstack.api.InternalIdentity;
@Entity
@Table(name="portable_ip_address")
public class PortableIpVO implements PortableIp {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="id")
Long id;
@Column(name="region_id")
int regionId;
@Column(name="allocated")
@Temporal(value=TemporalType.TIMESTAMP)
private Date allocatedTime;
@Column(name="account_id")
private Long allocatedToAccountId = null;
@Column(name="domain_id")
private Long allocatedInDomainId = null;
@Column(name="state")
private State state;
@Column(name="vlan")
String vlan;
@Column(name="gateway")
String gateway;
@Column(name="netmask")
String netmask;
@Column(name="portable_ip_address")
String address;
@Column(name="portable_ip_range_id")
private long rangeId;
@Column(name="physical_network_id")
private Long physicalNetworkId;
@Column(name="data_center_id")
private long dataCenterId;
@Column(name="network_id")
private Long networkId;
@Column(name="vpc_id")
private Long vpcId;
public PortableIpVO() {
}
public PortableIpVO(int regionId, Long rangeId, String vlan, String gateway, String netmask, String address) {
this.regionId =regionId;
this.vlan = vlan;
this.gateway = gateway;
this.netmask = netmask;
this.address = address;
state = State.Free;
this.rangeId = rangeId;
}
@Override
public long getId() {
return id;
}
@Override
public Long getAllocatedToAccountId() {
return allocatedToAccountId;
}
public void setAllocatedToAccountId(Long accountId) {
this.allocatedToAccountId = accountId;
}
@Override
public Long getAllocatedInDomainId() {
return allocatedInDomainId;
}
public void setAllocatedInDomainId(Long domainId) {
this.allocatedInDomainId = domainId;
}
@Override
public Date getAllocatedTime() {
return allocatedTime;
}
public void setAllocatedTime(Date date) {
this.allocatedTime = date;
}
@Override
public State getState() {
return state;
}
public void setState(State state) {
this.state = state;
}
@Override
public int getRegionId() {
return regionId;
}
public void setRegionId(int regionId) {
this.regionId = regionId;
}
@Override
public Long getAssociatedDataCenterId() {
return dataCenterId;
}
public void setAssociatedDataCenterId(Long datacenterId) {
this.dataCenterId = datacenterId;
}
@Override
public Long getAssociatedWithNetworkId() {
return networkId;
}
public void setAssociatedWithNetworkId(Long networkId) {
this.networkId = networkId;
}
@Override
public Long getAssociatedWithVpcId() {
return vpcId;
}
public void setAssociatedWithVpcId(Long vpcId) {
this.vpcId = vpcId;
}
@Override
public Long getPhysicalNetworkId() {
return physicalNetworkId;
}
public void setPhysicalNetworkId(Long physicalNetworkId) {
this.physicalNetworkId = physicalNetworkId;
}
@Override
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String getVlan() {
return vlan;
}
public void setVlan(String vlan) {
this.vlan = vlan;
}
@Override
public String getNetmask() {
return netmask;
}
public void setNetmask(String netmask) {
this.netmask = netmask;
}
@Override
public String getGateway() {
return gateway;
}
public void setGateay(String gateway) {
this.gateway = gateway;
}
Long getRangeId() {
return rangeId;
}
public void setRangeId(Long rangeId) {
this.rangeId = rangeId;
}
}

View File

@ -25,7 +25,6 @@ import javax.inject.Inject;
import javax.naming.ConfigurationException;
import javax.naming.NamingException;
import com.cloud.configuration.ConfigurationVO;
import org.apache.cloudstack.api.command.admin.config.UpdateCfgCmd;
import org.apache.cloudstack.api.command.admin.ldap.LDAPConfigCmd;
import org.apache.cloudstack.api.command.admin.ldap.LDAPRemoveCmd;
@ -40,6 +39,9 @@ import org.apache.cloudstack.api.command.admin.offering.UpdateDiskOfferingCmd;
import org.apache.cloudstack.api.command.admin.offering.UpdateServiceOfferingCmd;
import org.apache.cloudstack.api.command.admin.pod.DeletePodCmd;
import org.apache.cloudstack.api.command.admin.pod.UpdatePodCmd;
import org.apache.cloudstack.api.command.admin.region.CreatePortableIpRangeCmd;
import org.apache.cloudstack.api.command.admin.region.DeletePortableIpRangeCmd;
import org.apache.cloudstack.api.command.admin.region.ListPortableIpRangesCmd;
import org.apache.cloudstack.api.command.admin.vlan.CreateVlanIpRangeCmd;
import org.apache.cloudstack.api.command.admin.vlan.DedicatePublicIpRangeCmd;
import org.apache.cloudstack.api.command.admin.vlan.DeleteVlanIpRangeCmd;
@ -48,6 +50,7 @@ import org.apache.cloudstack.api.command.admin.zone.CreateZoneCmd;
import org.apache.cloudstack.api.command.admin.zone.DeleteZoneCmd;
import org.apache.cloudstack.api.command.admin.zone.UpdateZoneCmd;
import org.apache.cloudstack.api.command.user.network.ListNetworkOfferingsCmd;
import org.apache.cloudstack.region.PortableIpRange;
import org.springframework.stereotype.Component;
import com.cloud.configuration.Configuration;
@ -75,13 +78,11 @@ import com.cloud.offering.NetworkOffering;
import com.cloud.offering.NetworkOffering.Availability;
import com.cloud.offering.ServiceOffering;
import com.cloud.offerings.NetworkOfferingVO;
import com.cloud.offerings.dao.NetworkOfferingDao;
import com.cloud.offerings.dao.NetworkOfferingDaoImpl;
import com.cloud.org.Grouping.AllocationState;
import com.cloud.service.ServiceOfferingVO;
import com.cloud.storage.DiskOfferingVO;
import com.cloud.user.Account;
import com.cloud.utils.component.Manager;
import com.cloud.utils.component.ManagerBase;
import com.cloud.vm.VirtualMachine.Type;
@ -386,6 +387,21 @@ public class MockConfigurationManagerImpl extends ManagerBase implements Configu
return false;
}
@Override
public PortableIpRange createPortableIpRange(CreatePortableIpRangeCmd cmd) throws ConcurrentOperationException {
return null;// TODO Auto-generated method stub
}
@Override
public boolean deletePortableIpRange(DeletePortableIpRangeCmd cmd) {
return false;
}
@Override
public List<? extends PortableIpRange> listPortableIpRanges(ListPortableIpRangesCmd cmd) {
return null;// TODO Auto-generated method stub
}
/* (non-Javadoc)
* @see com.cloud.utils.component.Manager#configure(java.lang.String, java.util.Map)
*/

View File

@ -21,6 +21,9 @@ import java.io.IOException;
import org.apache.cloudstack.acl.SecurityChecker;
import org.apache.cloudstack.affinity.dao.AffinityGroupDao;
import org.apache.cloudstack.affinity.dao.AffinityGroupVMMapDao;
import org.apache.cloudstack.region.PortableIpDaoImpl;
import org.apache.cloudstack.region.PortableIpRangeDaoImpl;
import org.apache.cloudstack.region.dao.RegionDaoImpl;
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDaoImpl;
import org.mockito.Mockito;
import org.springframework.context.annotation.Bean;
@ -131,7 +134,8 @@ import com.cloud.vm.dao.VMInstanceDaoImpl;
FirewallRulesCidrsDaoImpl.class, PhysicalNetworkDaoImpl.class, PhysicalNetworkTrafficTypeDaoImpl.class,
PhysicalNetworkServiceProviderDaoImpl.class, LoadBalancerDaoImpl.class, NetworkServiceMapDaoImpl.class,
PrimaryDataStoreDaoImpl.class, StoragePoolDetailsDaoImpl.class, AffinityGroupServiceImpl.class,
ComponentContext.class, AffinityGroupProcessor.class, UserVmVO.class, EventUtils.class, UserVmVO.class
ComponentContext.class, AffinityGroupProcessor.class, UserVmVO.class, EventUtils.class, UserVmVO.class,
PortableIpRangeDaoImpl.class, RegionDaoImpl.class, PortableIpDaoImpl.class
}, includeFilters = { @Filter(value = AffinityApiTestConfiguration.Library.class, type = FilterType.CUSTOM) }, useDefaultFilters = false)
public class AffinityApiTestConfiguration {

View File

@ -20,6 +20,8 @@ package org.apache.cloudstack.networkoffering;
import java.io.IOException;
import org.apache.cloudstack.acl.SecurityChecker;
import org.apache.cloudstack.region.PortableIpDaoImpl;
import org.apache.cloudstack.region.dao.RegionDaoImpl;
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDaoImpl;
import org.mockito.Mockito;
import org.springframework.context.annotation.Bean;
@ -109,6 +111,7 @@ import com.cloud.vm.dao.NicDaoImpl;
import com.cloud.vm.dao.NicSecondaryIpDaoImpl;
import com.cloud.vm.dao.UserVmDao;
import com.cloud.vm.dao.VMInstanceDaoImpl;
import org.apache.cloudstack.region.PortableIpRangeDaoImpl;
@Configuration
@ComponentScan(basePackageClasses={
@ -156,7 +159,10 @@ import com.cloud.vm.dao.VMInstanceDaoImpl;
LoadBalancerDaoImpl.class,
NetworkServiceMapDaoImpl.class,
PrimaryDataStoreDaoImpl.class,
StoragePoolDetailsDaoImpl.class
StoragePoolDetailsDaoImpl.class,
PortableIpRangeDaoImpl.class,
RegionDaoImpl.class,
PortableIpDaoImpl.class
},
includeFilters={@Filter(value=ChildTestConfiguration.Library.class, type=FilterType.CUSTOM)},
useDefaultFilters=false

View File

@ -1110,3 +1110,37 @@ CREATE VIEW `cloud`.`account_view` AS
and async_job.job_status = 0;
alter table `cloud_usage`.`usage_network_offering` add column nic_id bigint(20) unsigned NOT NULL;
CREATE TABLE `cloud`.`portable_ip_range` (
`id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT,
`uuid` varchar(40),
`region_id` int unsigned NOT NULL,
`vlan_id` varchar(255),
`gateway` varchar(255),
`netmask` varchar(255),
`start_ip` varchar(255),
`end_ip` varchar(255),
PRIMARY KEY (`id`),
CONSTRAINT `fk_portableip__region_id` FOREIGN KEY (`region_id`) REFERENCES `region`(`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `cloud`.`portable_ip_address` (
`id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT,
`account_id` bigint unsigned NULL,
`domain_id` bigint unsigned NULL,
`allocated` datetime NULL COMMENT 'Date portable ip was allocated',
`state` char(32) NOT NULL default 'Free' COMMENT 'state of the portable ip address',
`region_id` int unsigned NOT NULL,
`vlan` varchar(255),
`gateway` varchar(255),
`netmask` varchar(255),
`portable_ip_address` varchar(255),
`portable_ip_range_id` bigint unsigned NOT NULL,
`data_center_id` bigint unsigned NULL COMMENT 'zone to which portable IP is associated',
`physical_network_id` bigint unsigned NULL COMMENT 'physical network id in the zone to which portable IP is associated',
`network_id` bigint unsigned NULL COMMENT 'guest network to which portable ip address is associated with',
`vpc_id` bigint unsigned COMMENT 'vpc to which portable ip address is associated with',
PRIMARY KEY (`id`),
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;

View File

@ -1290,4 +1290,16 @@ public class NetUtils {
}
return resultIp;
}
public static boolean isValidVlan(String vlan) {
try {
int vnet = Integer.parseInt(vlan);
if (vnet < 0 || vnet > 4096) {
return false;
}
return true;
} catch (NumberFormatException e) {
return false;
}
}
}