mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Bug 12777 - Add storage network configuration into CloudStack
create APIs
This commit is contained in:
parent
aa8bf6c135
commit
0b01c5dc1a
@ -39,6 +39,7 @@ import com.cloud.exception.PermissionDeniedException;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.network.NetworkService;
|
||||
import com.cloud.network.StorageNetworkService;
|
||||
import com.cloud.network.VirtualNetworkApplianceService;
|
||||
import com.cloud.network.firewall.FirewallService;
|
||||
import com.cloud.network.lb.LoadBalancingRulesService;
|
||||
@ -126,6 +127,7 @@ public abstract class BaseCmd {
|
||||
public static DomainService _domainService;
|
||||
public static ResourceLimitService _resourceLimitService;
|
||||
public static IdentityService _identityService;
|
||||
public static StorageNetworkService _storageNetworkService;
|
||||
|
||||
static void setComponents(ResponseGenerator generator) {
|
||||
ComponentLocator locator = ComponentLocator.getLocator(ManagementService.Name);
|
||||
@ -152,6 +154,7 @@ public abstract class BaseCmd {
|
||||
_domainService = locator.getManager(DomainService.class);
|
||||
_resourceLimitService = locator.getManager(ResourceLimitService.class);
|
||||
_identityService = locator.getManager(IdentityService.class);
|
||||
_storageNetworkService = locator.getManager(StorageNetworkService.class);
|
||||
}
|
||||
|
||||
public abstract void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException;
|
||||
|
||||
@ -64,6 +64,7 @@ import com.cloud.api.response.ServiceOfferingResponse;
|
||||
import com.cloud.api.response.ServiceResponse;
|
||||
import com.cloud.api.response.SnapshotPolicyResponse;
|
||||
import com.cloud.api.response.SnapshotResponse;
|
||||
import com.cloud.api.response.StorageNetworkIpRangeResponse;
|
||||
import com.cloud.api.response.StoragePoolResponse;
|
||||
import com.cloud.api.response.SwiftResponse;
|
||||
import com.cloud.api.response.SystemVmInstanceResponse;
|
||||
@ -85,6 +86,7 @@ import com.cloud.configuration.ResourceCount;
|
||||
import com.cloud.configuration.ResourceLimit;
|
||||
import com.cloud.dc.DataCenter;
|
||||
import com.cloud.dc.Pod;
|
||||
import com.cloud.dc.StorageNetworkIpRange;
|
||||
import com.cloud.dc.Vlan;
|
||||
import com.cloud.domain.Domain;
|
||||
import com.cloud.event.Event;
|
||||
@ -271,4 +273,5 @@ public interface ResponseGenerator {
|
||||
|
||||
LDAPConfigResponse createLDAPConfigResponse(String hostname, Integer port, Boolean useSSL, String queryFilter, String baseSearch, String dn);
|
||||
|
||||
StorageNetworkIpRangeResponse createStorageNetworkIpRangeResponse(StorageNetworkIpRange result);
|
||||
}
|
||||
|
||||
121
api/src/com/cloud/api/commands/CreateStorageNetworkIpRangeCmd.java
Executable file
121
api/src/com/cloud/api/commands/CreateStorageNetworkIpRangeCmd.java
Executable file
@ -0,0 +1,121 @@
|
||||
package com.cloud.api.commands;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.api.ApiConstants;
|
||||
import com.cloud.api.BaseAsyncCmd;
|
||||
import com.cloud.api.BaseCmd;
|
||||
import com.cloud.api.IdentityMapper;
|
||||
import com.cloud.api.Implementation;
|
||||
import com.cloud.api.Parameter;
|
||||
import com.cloud.api.ServerApiException;
|
||||
import com.cloud.api.BaseCmd.CommandType;
|
||||
import com.cloud.api.response.StorageNetworkIpRangeResponse;
|
||||
import com.cloud.dc.StorageNetworkIpRange;
|
||||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.exception.ConcurrentOperationException;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.user.Account;
|
||||
|
||||
@Implementation(description="Creates a VLAN IP range.", responseObject=StorageNetworkIpRangeResponse.class)
|
||||
public class CreateStorageNetworkIpRangeCmd extends BaseAsyncCmd {
|
||||
public static final Logger s_logger = Logger.getLogger(CreateStorageNetworkIpRangeCmd.class);
|
||||
|
||||
private static final String s_name = "createstoragenetworkiprangeresponse";
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
@IdentityMapper(entityTableName="host_pod_ref")
|
||||
@Parameter(name=ApiConstants.POD_ID, type=CommandType.LONG, description="optional parameter. Have to be specified for Direct Untagged vlan only.")
|
||||
private Long podId;
|
||||
|
||||
@Parameter(name=ApiConstants.START_IP, type=CommandType.STRING, required=true, description="the beginning IP address in the VLAN IP range")
|
||||
private String startIp;
|
||||
|
||||
@Parameter(name=ApiConstants.END_IP, type=CommandType.STRING, description="the ending IP address in the VLAN IP range")
|
||||
private String endIp;
|
||||
|
||||
@Parameter(name=ApiConstants.VLAN, type=CommandType.INTEGER, description="the ID or VID of the VLAN. Optional, null means no vlan")
|
||||
private Integer vlan;
|
||||
|
||||
@IdentityMapper(entityTableName="data_center")
|
||||
@Parameter(name=ApiConstants.ZONE_ID, type=CommandType.LONG, description="the Zone ID of the VLAN IP range")
|
||||
private Long zoneId;
|
||||
|
||||
@IdentityMapper(entityTableName="networks")
|
||||
@Parameter(name=ApiConstants.NETWORK_ID, type=CommandType.LONG, description="the network id")
|
||||
private Long networkID;
|
||||
|
||||
@Parameter(name=ApiConstants.NETMASK, type=CommandType.STRING, required=true, description="the netmask for the Pod")
|
||||
private String netmask;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public String getEndIp() {
|
||||
return endIp;
|
||||
}
|
||||
|
||||
public Long getPodId() {
|
||||
return podId;
|
||||
}
|
||||
|
||||
public String getStartIp() {
|
||||
return startIp;
|
||||
}
|
||||
|
||||
public Integer getVlan() {
|
||||
return vlan;
|
||||
}
|
||||
|
||||
public Long getZoneId() {
|
||||
return zoneId;
|
||||
}
|
||||
|
||||
public Long getNetworkID() {
|
||||
return networkID;
|
||||
}
|
||||
|
||||
public String getNetmask() {
|
||||
return netmask;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventType() {
|
||||
return EventTypes.EVENT_STORAGE_IP_RANGE_CREATE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventDescription() {
|
||||
return "Creating storage ip range from " + getStartIp() + " to " + getEndIp() + " with vlan " + getVlan();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
|
||||
ResourceAllocationException {
|
||||
try {
|
||||
StorageNetworkIpRange result = _storageNetworkService.createIpRange(this);
|
||||
StorageNetworkIpRangeResponse response = _responseGenerator.createStorageNetworkIpRangeResponse(result);
|
||||
response.setResponseName(getCommandName());
|
||||
this.setResponseObject(response);
|
||||
} catch (Exception e) {
|
||||
s_logger.warn("Create storage network IP range failed", e);
|
||||
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return s_name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
return Account.ACCOUNT_ID_SYSTEM;
|
||||
}
|
||||
|
||||
}
|
||||
0
api/src/com/cloud/api/commands/DeleteClusterCmd.java
Normal file → Executable file
0
api/src/com/cloud/api/commands/DeleteClusterCmd.java
Normal file → Executable file
76
api/src/com/cloud/api/commands/DeleteStorageNetworkIpRangeCmd.java
Executable file
76
api/src/com/cloud/api/commands/DeleteStorageNetworkIpRangeCmd.java
Executable file
@ -0,0 +1,76 @@
|
||||
package com.cloud.api.commands;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.api.ApiConstants;
|
||||
import com.cloud.api.BaseAsyncCmd;
|
||||
import com.cloud.api.BaseCmd;
|
||||
import com.cloud.api.IdentityMapper;
|
||||
import com.cloud.api.Implementation;
|
||||
import com.cloud.api.Parameter;
|
||||
import com.cloud.api.ServerApiException;
|
||||
import com.cloud.api.BaseCmd.CommandType;
|
||||
import com.cloud.api.response.SuccessResponse;
|
||||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.exception.ConcurrentOperationException;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.user.Account;
|
||||
|
||||
@Implementation(description="Deletes a storage network IP Range.", responseObject=SuccessResponse.class)
|
||||
public class DeleteStorageNetworkIpRangeCmd extends BaseAsyncCmd {
|
||||
public static final Logger s_logger = Logger.getLogger(DeleteStorageNetworkIpRangeCmd.class);
|
||||
|
||||
private static final String s_name = "deletestoragenetworkiprangeresponse";
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@IdentityMapper(entityTableName="dc_storage_network_ip_range")
|
||||
@Parameter(name=ApiConstants.ID, type=CommandType.LONG, required=true, description="the storage network IP range ID")
|
||||
private Long id;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventType() {
|
||||
return EventTypes.EVENT_STORAGE_IP_RANGE_DELETE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventDescription() {
|
||||
return "Deleting storage ip range " + getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
|
||||
ResourceAllocationException {
|
||||
try {
|
||||
_storageNetworkService.deleteIpRange(this);
|
||||
SuccessResponse response = new SuccessResponse(getCommandName());
|
||||
this.setResponseObject(response);
|
||||
} catch (Exception e) {
|
||||
s_logger.warn("Failed to delete storage network ip range " + getId(), e);
|
||||
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return s_name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
return Account.ACCOUNT_ID_SYSTEM;
|
||||
}
|
||||
|
||||
}
|
||||
104
api/src/com/cloud/api/commands/listStorageNetworkIpRangeCmd.java
Executable file
104
api/src/com/cloud/api/commands/listStorageNetworkIpRangeCmd.java
Executable file
@ -0,0 +1,104 @@
|
||||
package com.cloud.api.commands;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.api.ApiConstants;
|
||||
import com.cloud.api.BaseAsyncCmd;
|
||||
import com.cloud.api.BaseCmd;
|
||||
import com.cloud.api.IdentityMapper;
|
||||
import com.cloud.api.Implementation;
|
||||
import com.cloud.api.Parameter;
|
||||
import com.cloud.api.ServerApiException;
|
||||
import com.cloud.api.BaseCmd.CommandType;
|
||||
import com.cloud.api.response.ListResponse;
|
||||
import com.cloud.api.response.StorageNetworkIpRangeResponse;
|
||||
import com.cloud.dc.StorageNetworkIpRange;
|
||||
import com.cloud.event.EventTypes;
|
||||
import com.cloud.exception.ConcurrentOperationException;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
import com.cloud.exception.ResourceAllocationException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.user.Account;
|
||||
|
||||
@Implementation(description="List a storage network IP range.", responseObject=StorageNetworkIpRangeResponse.class)
|
||||
public class listStorageNetworkIpRangeCmd extends BaseAsyncCmd {
|
||||
public static final Logger s_logger = Logger.getLogger(listStorageNetworkIpRangeCmd.class);
|
||||
|
||||
String s_name = "liststoragenetworkiprangeresponse";
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
//////////////// API parameters /////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
@IdentityMapper(entityTableName="dc_storage_network_ip_range")
|
||||
@Parameter(name=ApiConstants.ID, type=CommandType.LONG, description="optional parameter. Storaget network IP range id, if specicied, using it to search the range.")
|
||||
private Long rangeId;
|
||||
|
||||
@IdentityMapper(entityTableName="host_pod_ref")
|
||||
@Parameter(name=ApiConstants.POD_ID, type=CommandType.LONG, description="optional parameter. Pod id, if specicied and range id is absent, using it to search the range.")
|
||||
private Long podId;
|
||||
|
||||
@IdentityMapper(entityTableName="data_center")
|
||||
@Parameter(name=ApiConstants.ZONE_ID, type=CommandType.LONG, description="optional parameter. Zone id, if specicied and both pod id and range id are absent, using it to search the range.")
|
||||
private Long zoneId;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
/////////////////// Accessors ///////////////////////
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
public Long getRangeId() {
|
||||
return rangeId;
|
||||
}
|
||||
|
||||
public Long getPodId() {
|
||||
return podId;
|
||||
}
|
||||
|
||||
public Long getZoneId() {
|
||||
return zoneId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventType() {
|
||||
return EventTypes.EVENT_STORAGE_IP_RANGE_LIST;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEventDescription() {
|
||||
return "List storage network IP range";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException,
|
||||
ResourceAllocationException {
|
||||
try {
|
||||
List<StorageNetworkIpRange> results = _storageNetworkService.listIpRange(this);
|
||||
ListResponse<StorageNetworkIpRangeResponse> response = new ListResponse<StorageNetworkIpRangeResponse>();
|
||||
List<StorageNetworkIpRangeResponse> resList = new ArrayList<StorageNetworkIpRangeResponse>(results.size());
|
||||
for (StorageNetworkIpRange r : results) {
|
||||
StorageNetworkIpRangeResponse resp = _responseGenerator.createStorageNetworkIpRangeResponse(r);
|
||||
resList.add(resp);
|
||||
}
|
||||
response.setResponses(resList);
|
||||
response.setObjectName(getCommandName());
|
||||
this.setResponseObject(response);
|
||||
} catch (Exception e) {
|
||||
s_logger.warn("Failed to list storage network ip range for rangeId=" + getRangeId() + " podId=" + getPodId() + " zoneId=" + getZoneId());
|
||||
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return s_name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
return Account.ACCOUNT_ID_SYSTEM;
|
||||
}
|
||||
|
||||
}
|
||||
57
api/src/com/cloud/api/response/StorageNetworkIpRangeResponse.java
Executable file
57
api/src/com/cloud/api/response/StorageNetworkIpRangeResponse.java
Executable file
@ -0,0 +1,57 @@
|
||||
package com.cloud.api.response;
|
||||
|
||||
import com.cloud.api.ApiConstants;
|
||||
import com.cloud.api.IdentityProxy;
|
||||
import com.cloud.serializer.Param;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class StorageNetworkIpRangeResponse extends BaseResponse {
|
||||
@SerializedName(ApiConstants.VLAN) @Param(description="the ID of storage network IP range.")
|
||||
private Long id;
|
||||
|
||||
@SerializedName(ApiConstants.VLAN) @Param(description="the ID or VID of the VLAN.")
|
||||
private Integer vlan;
|
||||
|
||||
@SerializedName(ApiConstants.POD_ID) @Param(description="the Pod ID for the VLAN IP range")
|
||||
private IdentityProxy podId = new IdentityProxy("host_pod_ref");
|
||||
|
||||
@SerializedName(ApiConstants.START_IP) @Param(description="the start ip of the VLAN IP range")
|
||||
private String startIp;
|
||||
|
||||
@SerializedName(ApiConstants.END_IP) @Param(description="the end ip of the VLAN IP range")
|
||||
private String endIp;
|
||||
|
||||
@SerializedName(ApiConstants.NETWORK_ID) @Param(description="the network id of vlan range")
|
||||
private IdentityProxy networkId = new IdentityProxy("networks");
|
||||
|
||||
@SerializedName(ApiConstants.ZONE_ID) @Param(description="the Zone ID of the VLAN IP range")
|
||||
private IdentityProxy zoneId = new IdentityProxy("data_center");
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public void setZoneId(Long zoneId) {
|
||||
this.zoneId.setValue(zoneId);
|
||||
}
|
||||
|
||||
public void setVlan(Integer vlan) {
|
||||
this.vlan = vlan;
|
||||
}
|
||||
|
||||
public void setPodId(Long podId) {
|
||||
this.podId.setValue(podId);
|
||||
}
|
||||
|
||||
public void setStartIp(String startIp) {
|
||||
this.startIp = startIp;
|
||||
}
|
||||
|
||||
public void setEndIp(String endIp) {
|
||||
this.endIp = endIp;
|
||||
}
|
||||
|
||||
public void setNetworkId(Long networkId) {
|
||||
this.networkId.setValue(networkId);
|
||||
}
|
||||
}
|
||||
17
api/src/com/cloud/dc/StorageNetworkIpRange.java
Executable file
17
api/src/com/cloud/dc/StorageNetworkIpRange.java
Executable file
@ -0,0 +1,17 @@
|
||||
package com.cloud.dc;
|
||||
|
||||
public interface StorageNetworkIpRange {
|
||||
long getId();
|
||||
|
||||
int getVlan();
|
||||
|
||||
long getPodId();
|
||||
|
||||
String getStartIp();
|
||||
|
||||
String getEndIp();
|
||||
|
||||
long getNetworkId();
|
||||
|
||||
long getDataCenterId();
|
||||
}
|
||||
@ -169,6 +169,10 @@ public class EventTypes {
|
||||
// VLANs/IP ranges
|
||||
public static final String EVENT_VLAN_IP_RANGE_CREATE = "VLAN.IP.RANGE.CREATE";
|
||||
public static final String EVENT_VLAN_IP_RANGE_DELETE = "VLAN.IP.RANGE.DELETE";
|
||||
|
||||
public static final String EVENT_STORAGE_IP_RANGE_CREATE = "STORAGE.IP.RANGE.CREATE";
|
||||
public static final String EVENT_STORAGE_IP_RANGE_DELETE = "STORAGE.IP.RANGE.DELETE";
|
||||
public static final String EVENT_STORAGE_IP_RANGE_LIST = "STORAGE.IP.RANGE.LIST";
|
||||
|
||||
// Configuration Table
|
||||
public static final String EVENT_CONFIGURATION_VALUE_EDIT = "CONFIGURATION.VALUE.EDIT";
|
||||
|
||||
17
api/src/com/cloud/network/StorageNetworkService.java
Executable file
17
api/src/com/cloud/network/StorageNetworkService.java
Executable file
@ -0,0 +1,17 @@
|
||||
package com.cloud.network;
|
||||
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
|
||||
import com.cloud.api.commands.CreateStorageNetworkIpRangeCmd;
|
||||
import com.cloud.api.commands.DeleteStorageNetworkIpRangeCmd;
|
||||
import com.cloud.api.commands.listStorageNetworkIpRangeCmd;
|
||||
import com.cloud.dc.StorageNetworkIpRange;
|
||||
|
||||
public interface StorageNetworkService {
|
||||
StorageNetworkIpRange createIpRange(CreateStorageNetworkIpRangeCmd cmd) throws SQLException;
|
||||
|
||||
void deleteIpRange(DeleteStorageNetworkIpRangeCmd cmd);
|
||||
|
||||
List<StorageNetworkIpRange> listIpRange(listStorageNetworkIpRangeCmd cmd);
|
||||
}
|
||||
@ -83,6 +83,7 @@ import com.cloud.api.response.ServiceOfferingResponse;
|
||||
import com.cloud.api.response.ServiceResponse;
|
||||
import com.cloud.api.response.SnapshotPolicyResponse;
|
||||
import com.cloud.api.response.SnapshotResponse;
|
||||
import com.cloud.api.response.StorageNetworkIpRangeResponse;
|
||||
import com.cloud.api.response.StoragePoolResponse;
|
||||
import com.cloud.api.response.SwiftResponse;
|
||||
import com.cloud.api.response.SystemVmInstanceResponse;
|
||||
@ -111,6 +112,7 @@ import com.cloud.dc.DataCenter;
|
||||
import com.cloud.dc.DataCenterVO;
|
||||
import com.cloud.dc.HostPodVO;
|
||||
import com.cloud.dc.Pod;
|
||||
import com.cloud.dc.StorageNetworkIpRange;
|
||||
import com.cloud.dc.Vlan;
|
||||
import com.cloud.dc.Vlan.VlanType;
|
||||
import com.cloud.dc.VlanVO;
|
||||
@ -3236,5 +3238,16 @@ public class ApiResponseHelper implements ResponseGenerator {
|
||||
return lr;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public StorageNetworkIpRangeResponse createStorageNetworkIpRangeResponse(StorageNetworkIpRange result) {
|
||||
StorageNetworkIpRangeResponse response = new StorageNetworkIpRangeResponse();
|
||||
response.setId(result.getId());
|
||||
response.setVlan(result.getVlan());
|
||||
response.setEndIp(result.getEndIp());
|
||||
response.setStartIp(result.getStartIp());
|
||||
response.setPodId(result.getPodId());
|
||||
response.setZoneId(result.getDataCenterId());
|
||||
response.setNetworkId(result.getNetworkId());
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
86
server/src/com/cloud/dc/StorageNetworkIpAddressVO.java
Executable file
86
server/src/com/cloud/dc/StorageNetworkIpAddressVO.java
Executable file
@ -0,0 +1,86 @@
|
||||
package com.cloud.dc;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.Temporal;
|
||||
import javax.persistence.TemporalType;
|
||||
|
||||
import com.cloud.network.IpAddress.State;
|
||||
|
||||
@Entity
|
||||
@Table(name="op_dc_storage_network_ip_address")
|
||||
public class StorageNetworkIpAddressVO {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "id")
|
||||
long id;
|
||||
|
||||
@Column(name = "range_id")
|
||||
long rangeId;
|
||||
|
||||
@Column(name = "cidr_size")
|
||||
int cidrSize;
|
||||
|
||||
@Column(name = "ip_address", updatable = false, nullable = false)
|
||||
String ipAddress;
|
||||
|
||||
@Column(name = "taken")
|
||||
@Temporal(value = TemporalType.TIMESTAMP)
|
||||
private Date takenAt;
|
||||
|
||||
@Column(name = "mac_address")
|
||||
long mac;
|
||||
|
||||
protected StorageNetworkIpAddressVO() {
|
||||
}
|
||||
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setTakenAt(Date takenDate) {
|
||||
this.takenAt = takenDate;
|
||||
}
|
||||
|
||||
public String getIpAddress() {
|
||||
return ipAddress;
|
||||
}
|
||||
|
||||
public void setIpAddress(String ip) {
|
||||
this.ipAddress = ip;
|
||||
}
|
||||
|
||||
public Date getTakenAt() {
|
||||
return takenAt;
|
||||
}
|
||||
|
||||
public long getRangeId() {
|
||||
return rangeId;
|
||||
}
|
||||
|
||||
public void setRangeId(long id) {
|
||||
this.rangeId = id;
|
||||
}
|
||||
|
||||
public long getMac() {
|
||||
return mac;
|
||||
}
|
||||
|
||||
public void setMac(long mac) {
|
||||
this.mac = mac;
|
||||
}
|
||||
|
||||
public int getCidrSize() {
|
||||
return cidrSize;
|
||||
}
|
||||
|
||||
public void setCidrSize(int cidr) {
|
||||
this.cidrSize =cidr;
|
||||
}
|
||||
}
|
||||
100
server/src/com/cloud/dc/StorageNetworkIpRangeVO.java
Executable file
100
server/src/com/cloud/dc/StorageNetworkIpRangeVO.java
Executable file
@ -0,0 +1,100 @@
|
||||
package com.cloud.dc;
|
||||
|
||||
import javax.persistence.Column;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
|
||||
@Entity
|
||||
@Table(name="dc_storage_network_ip_range")
|
||||
public class StorageNetworkIpRangeVO implements StorageNetworkIpRange {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
@Column(name = "id")
|
||||
private long id;
|
||||
|
||||
@Column(name = "vlan")
|
||||
private int vlan;
|
||||
|
||||
@Column(name = "data_center_id")
|
||||
private long dataCenterId;
|
||||
|
||||
@Column(name = "pod_id")
|
||||
private long podId;
|
||||
|
||||
@Column(name = "start_ip")
|
||||
private String startIp;
|
||||
|
||||
@Column(name = "end_ip")
|
||||
private String endIp;
|
||||
|
||||
@Column(name = "network_id")
|
||||
private long networkId;
|
||||
|
||||
public StorageNetworkIpRangeVO(long dcId, long podId, long networkId, String startIp, String endIp, int vlan) {
|
||||
this.dataCenterId = dcId;
|
||||
this.podId = podId;
|
||||
this.networkId = networkId;
|
||||
this.startIp = startIp;
|
||||
this.endIp = endIp;
|
||||
this.vlan = vlan;
|
||||
}
|
||||
|
||||
protected StorageNetworkIpRangeVO() {
|
||||
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public long getDataCenterId() {
|
||||
return dataCenterId;
|
||||
}
|
||||
|
||||
public void setDataCenterId(long dcId) {
|
||||
this.dataCenterId = dcId;
|
||||
}
|
||||
|
||||
public long getPodId() {
|
||||
return podId;
|
||||
}
|
||||
|
||||
public void setPodId(long podId) {
|
||||
this.podId = podId;
|
||||
}
|
||||
|
||||
public long getNetworkId() {
|
||||
return networkId;
|
||||
}
|
||||
|
||||
public void setNetworkId(long nwId) {
|
||||
this.networkId = nwId;
|
||||
}
|
||||
|
||||
public int getVlan() {
|
||||
return vlan;
|
||||
}
|
||||
|
||||
public void setVlan(int vlan) {
|
||||
this.vlan = vlan;
|
||||
}
|
||||
|
||||
public void setStartIp(String start) {
|
||||
this.startIp = start;
|
||||
}
|
||||
|
||||
public String getStartIp() {
|
||||
return startIp;
|
||||
}
|
||||
|
||||
public void setEndIp(String end) {
|
||||
this.endIp = end;
|
||||
}
|
||||
|
||||
public String getEndIp() {
|
||||
return endIp;
|
||||
}
|
||||
}
|
||||
16
server/src/com/cloud/dc/dao/StorageNetworkIpAddressDao.java
Executable file
16
server/src/com/cloud/dc/dao/StorageNetworkIpAddressDao.java
Executable file
@ -0,0 +1,16 @@
|
||||
package com.cloud.dc.dao;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.cloud.dc.StorageNetworkIpAddressVO;
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
|
||||
public interface StorageNetworkIpAddressDao extends GenericDao<StorageNetworkIpAddressVO, Long> {
|
||||
long countInUseIpByRangeId(long rangeId);
|
||||
|
||||
List<String> listInUseIpByRangeId(long rangeId);
|
||||
|
||||
StorageNetworkIpAddressVO takeIpAddress(long rangeId);
|
||||
|
||||
void releaseIpAddress(String ip);
|
||||
}
|
||||
95
server/src/com/cloud/dc/dao/StorageNetworkIpAddressDaoImpl.java
Executable file
95
server/src/com/cloud/dc/dao/StorageNetworkIpAddressDaoImpl.java
Executable file
@ -0,0 +1,95 @@
|
||||
package com.cloud.dc.dao;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.ejb.Local;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import com.cloud.dc.DataCenterIpAddressVO;
|
||||
import com.cloud.dc.StorageNetworkIpAddressVO;
|
||||
import com.cloud.utils.db.DB;
|
||||
import com.cloud.utils.db.Filter;
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.GenericSearchBuilder;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.utils.db.SearchCriteria2;
|
||||
import com.cloud.utils.db.Transaction;
|
||||
import com.cloud.utils.db.SearchCriteria.Func;
|
||||
import com.cloud.utils.db.SearchCriteria.Op;
|
||||
|
||||
@Local(value={StorageNetworkIpAddressDao.class})
|
||||
@DB(txn=false)
|
||||
public class StorageNetworkIpAddressDaoImpl extends GenericDaoBase<StorageNetworkIpAddressVO, Long> implements StorageNetworkIpAddressDao {
|
||||
protected final GenericSearchBuilder<StorageNetworkIpAddressVO, Long> countInUserIp;
|
||||
protected final GenericSearchBuilder<StorageNetworkIpAddressVO, String> listInUseIp;
|
||||
protected final SearchBuilder<StorageNetworkIpAddressVO> untakenIp;
|
||||
protected final SearchBuilder<StorageNetworkIpAddressVO> ipSearch;
|
||||
|
||||
|
||||
protected StorageNetworkIpAddressDaoImpl() {
|
||||
countInUserIp = createSearchBuilder(Long.class);
|
||||
countInUserIp.select(null, Func.COUNT, null);
|
||||
countInUserIp.and("rangeId", countInUserIp.entity().getRangeId(), Op.EQ);
|
||||
countInUserIp.and("taken", countInUserIp.entity().getTakenAt(), Op.NULL);
|
||||
countInUserIp.done();
|
||||
|
||||
listInUseIp = createSearchBuilder(String.class);
|
||||
listInUseIp.selectField(listInUseIp.entity().getIpAddress());
|
||||
listInUseIp.and("rangeId", listInUseIp.entity().getRangeId(), Op.EQ);
|
||||
listInUseIp.and("taken", listInUseIp.entity().getTakenAt(), Op.NULL);
|
||||
listInUseIp.done();
|
||||
|
||||
untakenIp = createSearchBuilder();
|
||||
untakenIp.and("rangeId", untakenIp.entity().getRangeId(), Op.EQ);
|
||||
untakenIp.and("taken", untakenIp.entity().getTakenAt(), Op.NULL);
|
||||
untakenIp.done();
|
||||
|
||||
ipSearch = createSearchBuilder();
|
||||
ipSearch.and("ipAddress", ipSearch.entity().getIpAddress(), Op.EQ);
|
||||
ipSearch.done();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long countInUseIpByRangeId(long rangeId) {
|
||||
SearchCriteria<Long> sc = countInUserIp.create();
|
||||
sc.setParameters("rangeId", rangeId);
|
||||
return customSearch(sc, null).get(0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> listInUseIpByRangeId(long rangeId) {
|
||||
SearchCriteria<String> sc = listInUseIp.create();
|
||||
sc.setParameters("rangeId", rangeId);
|
||||
return customSearch(sc, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@DB
|
||||
public StorageNetworkIpAddressVO takeIpAddress(long rangeId) {
|
||||
SearchCriteria<StorageNetworkIpAddressVO> sc = untakenIp.create();
|
||||
sc.setParameters("rangeId", rangeId);
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
txn.start();
|
||||
StorageNetworkIpAddressVO ip = lockOneRandomRow(sc, true);
|
||||
if (ip == null) {
|
||||
txn.rollback();
|
||||
return null;
|
||||
}
|
||||
ip.setTakenAt(new Date());
|
||||
update(ip.getId(), ip);
|
||||
txn.commit();
|
||||
return ip;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void releaseIpAddress(String ip) {
|
||||
SearchCriteria<StorageNetworkIpAddressVO> sc = ipSearch.create();
|
||||
sc.setParameters("ipAddress", ip);
|
||||
StorageNetworkIpAddressVO vo = createForUpdate();
|
||||
vo.setTakenAt(null);
|
||||
update(vo, sc);
|
||||
}
|
||||
}
|
||||
14
server/src/com/cloud/dc/dao/StorageNetworkIpRangeDao.java
Executable file
14
server/src/com/cloud/dc/dao/StorageNetworkIpRangeDao.java
Executable file
@ -0,0 +1,14 @@
|
||||
package com.cloud.dc.dao;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.cloud.dc.StorageNetworkIpRangeVO;
|
||||
import com.cloud.utils.db.GenericDao;
|
||||
|
||||
public interface StorageNetworkIpRangeDao extends GenericDao<StorageNetworkIpRangeVO, Long> {
|
||||
List<StorageNetworkIpRangeVO> listByRangeId(long rangeId);
|
||||
|
||||
List<StorageNetworkIpRangeVO> listByPodId(long podId);
|
||||
|
||||
List<StorageNetworkIpRangeVO> listByDataCenterId(long dcId);
|
||||
}
|
||||
41
server/src/com/cloud/dc/dao/StorageNetworkIpRangeDaoImpl.java
Executable file
41
server/src/com/cloud/dc/dao/StorageNetworkIpRangeDaoImpl.java
Executable file
@ -0,0 +1,41 @@
|
||||
package com.cloud.dc.dao;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import com.cloud.dc.StorageNetworkIpRangeVO;
|
||||
import com.cloud.utils.db.Filter;
|
||||
import com.cloud.utils.db.GenericDaoBase;
|
||||
import com.cloud.utils.db.GenericSearchBuilder;
|
||||
import com.cloud.utils.db.SearchBuilder;
|
||||
import com.cloud.utils.db.SearchCriteria;
|
||||
import com.cloud.utils.db.SearchCriteria2;
|
||||
import com.cloud.utils.db.SearchCriteriaService;
|
||||
import com.cloud.utils.db.SearchCriteria.Op;
|
||||
|
||||
public class StorageNetworkIpRangeDaoImpl extends GenericDaoBase<StorageNetworkIpRangeVO, Long> implements StorageNetworkIpRangeDao {
|
||||
|
||||
@Override
|
||||
public List<StorageNetworkIpRangeVO> listByPodId(long podId) {
|
||||
SearchCriteriaService<StorageNetworkIpRangeVO, StorageNetworkIpRangeVO> sc = SearchCriteria2.create(StorageNetworkIpRangeVO.class);
|
||||
sc.addAnd(sc.getEntity().getPodId(), Op.EQ, podId);
|
||||
return sc.list();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StorageNetworkIpRangeVO> listByRangeId(long rangeId) {
|
||||
SearchCriteriaService<StorageNetworkIpRangeVO, StorageNetworkIpRangeVO> sc = SearchCriteria2.create(StorageNetworkIpRangeVO.class);
|
||||
sc.addAnd(sc.getEntity().getId(), Op.EQ, rangeId);
|
||||
return sc.list();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StorageNetworkIpRangeVO> listByDataCenterId(long dcId) {
|
||||
SearchCriteriaService<StorageNetworkIpRangeVO, StorageNetworkIpRangeVO> sc = SearchCriteria2.create(StorageNetworkIpRangeVO.class);
|
||||
sc.addAnd(sc.getEntity().getDataCenterId(), Op.EQ, dcId);
|
||||
return sc.list();
|
||||
}
|
||||
|
||||
}
|
||||
12
server/src/com/cloud/network/StorageNetworkManager.java
Executable file
12
server/src/com/cloud/network/StorageNetworkManager.java
Executable file
@ -0,0 +1,12 @@
|
||||
package com.cloud.network;
|
||||
|
||||
import com.cloud.dc.StorageNetworkIpAddressVO;
|
||||
import com.cloud.utils.component.Manager;
|
||||
|
||||
public interface StorageNetworkManager extends Manager {
|
||||
StorageNetworkIpAddressVO acquireIpAddress(long podId);
|
||||
|
||||
void releaseIpAddress(String ip);
|
||||
|
||||
boolean isAStorageIpAddress(String ip);
|
||||
}
|
||||
278
server/src/com/cloud/network/StorageNetworkManagerImpl.java
Executable file
278
server/src/com/cloud/network/StorageNetworkManagerImpl.java
Executable file
@ -0,0 +1,278 @@
|
||||
package com.cloud.network;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.SQLException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.ejb.Local;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.api.commands.CreateStorageNetworkIpRangeCmd;
|
||||
import com.cloud.api.commands.DeleteStorageNetworkIpRangeCmd;
|
||||
import com.cloud.api.commands.listStorageNetworkIpRangeCmd;
|
||||
import com.cloud.dc.HostPodVO;
|
||||
import com.cloud.dc.StorageNetworkIpRange;
|
||||
import com.cloud.dc.StorageNetworkIpAddressVO;
|
||||
import com.cloud.dc.StorageNetworkIpRangeVO;
|
||||
import com.cloud.dc.dao.HostPodDao;
|
||||
import com.cloud.dc.dao.StorageNetworkIpAddressDao;
|
||||
import com.cloud.dc.dao.StorageNetworkIpRangeDao;
|
||||
import com.cloud.exception.InsufficientAddressCapacityException;
|
||||
import com.cloud.exception.InvalidParameterValueException;
|
||||
import com.cloud.network.Networks.TrafficType;
|
||||
import com.cloud.network.dao.NetworkDao;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.component.Inject;
|
||||
import com.cloud.utils.db.DB;
|
||||
import com.cloud.utils.db.SearchCriteria2;
|
||||
import com.cloud.utils.db.SearchCriteriaService;
|
||||
import com.cloud.utils.db.Transaction;
|
||||
import com.cloud.utils.db.SearchCriteria.Op;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.utils.net.NetUtils;
|
||||
|
||||
@Local(value = {StorageNetworkManager.class, StorageNetworkService.class})
|
||||
public class StorageNetworkManagerImpl implements StorageNetworkManager, StorageNetworkService {
|
||||
private static final Logger s_logger = Logger.getLogger(StorageNetworkManagerImpl.class);
|
||||
|
||||
String _name;
|
||||
@Inject
|
||||
StorageNetworkIpAddressDao _sNwIpDao;
|
||||
@Inject
|
||||
StorageNetworkIpRangeDao _sNwIpRangeDao;
|
||||
@Inject
|
||||
NetworkDao _networkDao;
|
||||
@Inject
|
||||
HostPodDao _podDao;
|
||||
|
||||
@Override
|
||||
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
|
||||
_name = name;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean start() {
|
||||
// TODO Auto-generated method stub
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean stop() {
|
||||
// TODO Auto-generated method stub
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
private void checkOverlapPrivateIpRange(long podId, String startIp, String endIp) {
|
||||
HostPodVO pod = _podDao.findById(podId);
|
||||
if (pod == null) {
|
||||
throw new CloudRuntimeException("Cannot find pod " + podId);
|
||||
}
|
||||
String[] IpRange = pod.getDescription().split("-");
|
||||
if ((IpRange[0] == null || IpRange[1] == null) || (!NetUtils.isValidIp(IpRange[0]) || !NetUtils.isValidIp(IpRange[1]))) {
|
||||
return;
|
||||
}
|
||||
if (NetUtils.ipRangesOverlap(startIp, endIp, IpRange[0], IpRange[1])) {
|
||||
throw new InvalidParameterValueException("The Storage network Start IP and endIP address range overlap with private IP :" + IpRange[0] + ":" + IpRange[1]);
|
||||
}
|
||||
}
|
||||
|
||||
private void checkOverlapStorageIpRange(long podId, String startIp, String endIp) {
|
||||
List<StorageNetworkIpRangeVO> curRanges = _sNwIpRangeDao.listByPodId(podId);
|
||||
for (StorageNetworkIpRangeVO range : curRanges) {
|
||||
if (NetUtils.ipRangesOverlap(startIp, endIp, range.getStartIp(), range.getEndIp())) {
|
||||
throw new InvalidParameterValueException("The Storage network Start IP and endIP address range overlap with private IP :" + range.getStartIp() + ":" + range.getEndIp());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void createStorageIpEntires(Transaction txn, long rangeId, String startIp, String endIp, String netmask, long zoneId) throws SQLException {
|
||||
long startIPLong = NetUtils.ip2Long(startIp);
|
||||
long endIPLong = NetUtils.ip2Long(endIp);
|
||||
String cidr = NetUtils.ipAndNetMaskToCidr(startIp, netmask);
|
||||
String[] cidrPair = cidr.split("\\/");
|
||||
int cidrSize = Integer.parseInt(cidrPair[1]);
|
||||
String insertSql = "INSERT INTO `cloud`.`op_dc_storage_network_ip_address` (range_id, ip_address, mac_address, cidr_size, taken) VALUES (?, ?, (select mac_address from `cloud`.`data_center` where id=?), ?, ?)";
|
||||
String updateSql = "UPDATE `cloud`.`data_center` set mac_address = mac_address+1 where id=?";
|
||||
PreparedStatement stmt = null;
|
||||
Connection conn = txn.getConnection();
|
||||
|
||||
while (startIPLong <= endIPLong) {
|
||||
stmt = conn.prepareStatement(insertSql);
|
||||
stmt.setLong(1, rangeId);
|
||||
stmt.setString(2, NetUtils.long2Ip(startIPLong++));
|
||||
stmt.setLong(3, zoneId);
|
||||
stmt.setInt(4, cidrSize);
|
||||
stmt.setNull(5, java.sql.Types.DATE);
|
||||
stmt.executeUpdate();
|
||||
stmt.close();
|
||||
|
||||
stmt = txn.prepareStatement(updateSql);
|
||||
stmt.setLong(1, zoneId);
|
||||
stmt.executeUpdate();
|
||||
stmt.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@DB
|
||||
public StorageNetworkIpRange createIpRange(CreateStorageNetworkIpRangeCmd cmd) throws SQLException {
|
||||
Long zoneId = cmd.getZoneId();
|
||||
Long podId = cmd.getPodId();
|
||||
String startIp = cmd.getStartIp();
|
||||
String endIp = cmd.getEndIp();
|
||||
Integer vlan = cmd.getVlan();
|
||||
String netmask = cmd.getNetmask();
|
||||
|
||||
if (endIp == null) {
|
||||
endIp = startIp;
|
||||
}
|
||||
|
||||
List<NetworkVO> nws = _networkDao.listByZoneAndTrafficType(zoneId, TrafficType.Storage);
|
||||
if (nws.size() == 0) {
|
||||
throw new CloudRuntimeException("Cannot find storage network in zone " + zoneId);
|
||||
}
|
||||
if (nws.size() > 1) {
|
||||
throw new CloudRuntimeException("Find more than one storage network in zone " + zoneId + "," + nws.size() + " found");
|
||||
}
|
||||
NetworkVO nw = nws.get(0);
|
||||
|
||||
checkOverlapPrivateIpRange(podId, startIp, endIp);
|
||||
checkOverlapStorageIpRange(podId, startIp, endIp);
|
||||
|
||||
Transaction txn = Transaction.currentTxn();
|
||||
StorageNetworkIpRangeVO range = null;
|
||||
|
||||
txn.start();
|
||||
range = new StorageNetworkIpRangeVO(zoneId, podId, nw.getId(), startIp, endIp, vlan);
|
||||
_sNwIpRangeDao.persist(range);
|
||||
try {
|
||||
createStorageIpEntires(txn, range.getId(), startIp, endIp, netmask, zoneId);
|
||||
} catch (SQLException e) {
|
||||
txn.rollback();
|
||||
StringBuilder err = new StringBuilder();
|
||||
err.append("Create storage network range failed.");
|
||||
err.append("startIp=" + startIp);
|
||||
err.append("endIp=" + endIp);
|
||||
err.append("netmask=" + netmask);
|
||||
err.append("zoneId=" + zoneId);
|
||||
s_logger.debug(err.toString(), e);
|
||||
throw e;
|
||||
}
|
||||
|
||||
txn.commit();
|
||||
|
||||
return range;
|
||||
}
|
||||
|
||||
private String getInUseIpAddress(long rangeId) {
|
||||
List<String> ips = _sNwIpDao.listInUseIpByRangeId(rangeId);
|
||||
StringBuilder res = new StringBuilder();
|
||||
res.append("Below IP of range " + rangeId + " is still in use:");
|
||||
for (String ip : ips) {
|
||||
res.append(ip);
|
||||
}
|
||||
return res.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
@DB
|
||||
public void deleteIpRange(DeleteStorageNetworkIpRangeCmd cmd) {
|
||||
long rangeId = cmd.getId();
|
||||
StorageNetworkIpRangeVO range = _sNwIpRangeDao.findById(rangeId);
|
||||
if (range == null) {
|
||||
throw new CloudRuntimeException("Can not find storage network ip range " + rangeId);
|
||||
}
|
||||
|
||||
if (_sNwIpDao.countInUseIpByRangeId(rangeId) > 0) {
|
||||
throw new CloudRuntimeException(getInUseIpAddress(rangeId));
|
||||
}
|
||||
|
||||
final Transaction txn = Transaction.currentTxn();
|
||||
txn.start();
|
||||
try {
|
||||
range = _sNwIpRangeDao.acquireInLockTable(rangeId);
|
||||
if (range == null) {
|
||||
String msg = "Unable to acquire lock on storage network ip range id=" + rangeId + ", delete failed";
|
||||
s_logger.warn(msg);
|
||||
throw new CloudRuntimeException(msg);
|
||||
}
|
||||
/* entries in op_dc_storage_network_ip_address will be deleted automatically due to fk_storage_ip_address__range_id constraint key */
|
||||
_sNwIpRangeDao.remove(rangeId);
|
||||
} finally {
|
||||
if (range != null) {
|
||||
_sNwIpRangeDao.releaseFromLockTable(rangeId);
|
||||
}
|
||||
}
|
||||
txn.commit();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<StorageNetworkIpRange> listIpRange(listStorageNetworkIpRangeCmd cmd) {
|
||||
Long rangeId = cmd.getRangeId();
|
||||
Long podId = cmd.getPodId();
|
||||
Long zoneId = cmd.getZoneId();
|
||||
|
||||
List result = null;
|
||||
if (rangeId != null) {
|
||||
result = _sNwIpRangeDao.listByRangeId(rangeId);
|
||||
} else if (podId != null) {
|
||||
result = _sNwIpRangeDao.listByPodId(podId);
|
||||
} else if (zoneId != null) {
|
||||
result = _sNwIpRangeDao.listByDataCenterId(zoneId);
|
||||
} else {
|
||||
result = _sNwIpRangeDao.listAll();
|
||||
}
|
||||
|
||||
return (List<StorageNetworkIpRange>)result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void releaseIpAddress(String ip) {
|
||||
_sNwIpDao.releaseIpAddress(ip);
|
||||
}
|
||||
|
||||
@Override
|
||||
public StorageNetworkIpAddressVO acquireIpAddress(long podId) {
|
||||
List<StorageNetworkIpRangeVO> ranges = _sNwIpRangeDao.listByPodId(podId);
|
||||
for (StorageNetworkIpRangeVO r : ranges) {
|
||||
try {
|
||||
r = _sNwIpRangeDao.acquireInLockTable(r.getId());
|
||||
if (r == null) {
|
||||
String msg = "Unable to acquire lock on storage network ip range id=" + r.getId() + ", delete failed";
|
||||
s_logger.warn(msg);
|
||||
throw new CloudRuntimeException(msg);
|
||||
}
|
||||
|
||||
StorageNetworkIpAddressVO ip = _sNwIpDao.takeIpAddress(r.getId());
|
||||
if (ip != null) {
|
||||
return ip;
|
||||
}
|
||||
} finally {
|
||||
if (r != null) {
|
||||
_sNwIpRangeDao.releaseFromLockTable(r.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAStorageIpAddress(String ip) {
|
||||
SearchCriteriaService<StorageNetworkIpAddressVO, StorageNetworkIpAddressVO> sc = SearchCriteria2.create(StorageNetworkIpAddressVO.class);
|
||||
sc.addAnd(sc.getEntity().getIpAddress(), Op.EQ, ip);
|
||||
return sc.find() == null ? false : true;
|
||||
}
|
||||
|
||||
}
|
||||
172
server/src/com/cloud/network/guru/StorageNetworkGuru.java
Executable file
172
server/src/com/cloud/network/guru/StorageNetworkGuru.java
Executable file
@ -0,0 +1,172 @@
|
||||
package com.cloud.network.guru;
|
||||
|
||||
import javax.ejb.Local;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.dc.Pod;
|
||||
import com.cloud.dc.StorageNetworkIpAddressVO;
|
||||
import com.cloud.dc.dao.DataCenterDao;
|
||||
import com.cloud.deploy.DeployDestination;
|
||||
import com.cloud.deploy.DeploymentPlan;
|
||||
import com.cloud.exception.ConcurrentOperationException;
|
||||
import com.cloud.exception.InsufficientAddressCapacityException;
|
||||
import com.cloud.exception.InsufficientVirtualNetworkCapcityException;
|
||||
import com.cloud.network.Network;
|
||||
import com.cloud.network.NetworkProfile;
|
||||
import com.cloud.network.NetworkVO;
|
||||
import com.cloud.network.Networks.AddressFormat;
|
||||
import com.cloud.network.Networks.BroadcastDomainType;
|
||||
import com.cloud.network.Networks.Mode;
|
||||
import com.cloud.network.Networks.TrafficType;
|
||||
import com.cloud.network.StorageNetworkManager;
|
||||
import com.cloud.offering.NetworkOffering;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.utils.Pair;
|
||||
import com.cloud.utils.component.AdapterBase;
|
||||
import com.cloud.utils.component.Inject;
|
||||
import com.cloud.utils.net.Ip4Address;
|
||||
import com.cloud.utils.net.NetUtils;
|
||||
import com.cloud.vm.NicProfile;
|
||||
import com.cloud.vm.ReservationContext;
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.VirtualMachineProfile;
|
||||
import com.cloud.vm.Nic.ReservationStrategy;
|
||||
|
||||
@Local(value = NetworkGuru.class)
|
||||
public class StorageNetworkGuru extends AdapterBase implements NetworkGuru {
|
||||
private static final Logger s_logger = Logger.getLogger(StorageNetworkGuru.class);
|
||||
@Inject StorageNetworkManager _sNwMgr;
|
||||
@Inject DataCenterDao _dcDao;
|
||||
|
||||
protected StorageNetworkGuru() {
|
||||
super();
|
||||
}
|
||||
|
||||
protected boolean canHandle(NetworkOffering offering) {
|
||||
if (offering.getTrafficType() == TrafficType.Storage && offering.isSystemOnly()) {
|
||||
return true;
|
||||
} else {
|
||||
s_logger.trace("It's not storage network offering, skip it.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Network design(NetworkOffering offering, DeploymentPlan plan, Network userSpecified, Account owner) {
|
||||
if (!canHandle(offering)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
NetworkVO config = new NetworkVO(offering.getTrafficType(), Mode.Static, BroadcastDomainType.Native, offering.getId(), Network.State.Setup,
|
||||
plan.getDataCenterId(), plan.getPhysicalNetworkId());
|
||||
return config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Network implement(Network network, NetworkOffering offering, DeployDestination destination, ReservationContext context)
|
||||
throws InsufficientVirtualNetworkCapcityException {
|
||||
assert network.getTrafficType() == TrafficType.Storage : "Why are you sending this configuration to me " + network;
|
||||
return network;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NicProfile allocate(Network network, NicProfile nic, VirtualMachineProfile<? extends VirtualMachine> vm)
|
||||
throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException, ConcurrentOperationException {
|
||||
assert network.getTrafficType() == TrafficType.Storage : "Well, I can't take care of this config now can I? " + network;
|
||||
return new NicProfile(ReservationStrategy.Start, null, null, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Ip4Address acquireIp4Address(Network network, String requestedIp, String reservationId) throws InsufficientAddressCapacityException {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean releaseIp4Address(Network network, String reservationId) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reserve(NicProfile nic, Network network, VirtualMachineProfile<? extends VirtualMachine> vm, DeployDestination dest, ReservationContext context)
|
||||
throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException, ConcurrentOperationException {
|
||||
Pod pod = dest.getPod();
|
||||
String ipAddress = null;
|
||||
Long macLong = null;
|
||||
Integer cidrSize = null;
|
||||
|
||||
StorageNetworkIpAddressVO ip = _sNwMgr.acquireIpAddress(pod.getId());
|
||||
if (ip != null) {
|
||||
ipAddress = ip.getIpAddress();
|
||||
macLong = ip.getMac();
|
||||
cidrSize = ip.getCidrSize();
|
||||
} else {
|
||||
s_logger.debug("Can not get an ip from storage network ip range for pod " + pod.getId() + ", acquire one from managment ip range");
|
||||
/* Pick up an ip from management ip range if there is no available in storage ip range because of either user not added it or run out of */
|
||||
Pair<String, Long>ip1 = _dcDao.allocatePrivateIpAddress(dest.getDataCenter().getId(), pod.getId(), nic.getId(),
|
||||
context.getReservationId());
|
||||
if (ip1 == null) {
|
||||
throw new InsufficientAddressCapacityException("Unable to get a storage network ip address", Pod.class, pod.getId());
|
||||
}
|
||||
ipAddress = ip1.first();
|
||||
macLong = ip1.second();
|
||||
cidrSize = pod.getCidrSize();
|
||||
}
|
||||
|
||||
nic.setIp4Address(ipAddress);
|
||||
nic.setMacAddress(NetUtils.long2Mac(NetUtils.createSequenceBasedMacAddress(macLong)));
|
||||
nic.setFormat(AddressFormat.Ip4);
|
||||
nic.setNetmask(NetUtils.getCidrNetmask(cidrSize));
|
||||
nic.setBroadcastType(BroadcastDomainType.Native);
|
||||
nic.setBroadcastUri(null);
|
||||
nic.setIsolationUri(null);
|
||||
s_logger.debug("Allocated a nic " + nic + " for " + vm);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean release(NicProfile nic, VirtualMachineProfile<? extends VirtualMachine> vm, String reservationId) {
|
||||
if (_sNwMgr.isAStorageIpAddress(nic.getIp4Address())) {
|
||||
_sNwMgr.releaseIpAddress(nic.getIp4Address());
|
||||
s_logger.debug("Release an storage ip " + nic.getIp4Address());
|
||||
} else {
|
||||
_dcDao.releasePrivateIpAddress(nic.getId(), nic.getReservationId());
|
||||
s_logger.debug("Release an storage ip that is from managment ip range " + nic.getIp4Address());
|
||||
}
|
||||
|
||||
nic.deallocate();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deallocate(Network network, NicProfile nic, VirtualMachineProfile<? extends VirtualMachine> vm) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateNicProfile(NicProfile profile, Network network) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutdown(NetworkProfile network, NetworkOffering offering) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean trash(Network network, NetworkOffering offering, Account owner) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateNetworkProfile(NetworkProfile networkProfile) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
3
server/src/com/cloud/test/IPRangeConfig.java
Normal file → Executable file
3
server/src/com/cloud/test/IPRangeConfig.java
Normal file → Executable file
@ -27,6 +27,7 @@ import java.sql.Statement;
|
||||
import java.util.List;
|
||||
import java.util.Vector;
|
||||
|
||||
import com.cloud.network.IpAddress;
|
||||
import com.cloud.utils.component.ComponentLocator;
|
||||
import com.cloud.utils.db.DB;
|
||||
import com.cloud.utils.db.Transaction;
|
||||
@ -448,7 +449,7 @@ public class IPRangeConfig {
|
||||
|
||||
return problemIPs;
|
||||
}
|
||||
|
||||
|
||||
public Vector<String> savePublicIPRange(Transaction txn, long startIP, long endIP, long zoneId, long vlanDbId, Long sourceNetworkId, long physicalNetworkId) {
|
||||
String insertSql = "INSERT INTO `cloud`.`user_ip_address` (public_ip_address, data_center_id, vlan_db_id, mac_address, source_network_id, physical_network_id) VALUES (?, ?, ?, (select mac_address from `cloud`.`data_center` where id=?), ?, ?)";
|
||||
String updateSql = "UPDATE `cloud`.`data_center` set mac_address = mac_address+1 where id=?";
|
||||
|
||||
@ -560,6 +560,33 @@ CREATE TABLE `cloud`.`op_dc_link_local_ip_address_alloc` (
|
||||
INDEX `i_op_dc_link_local_ip_address_alloc__nic_id_reservation_id`(`nic_id`,`reservation_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE `cloud`.`dc_storage_network_ip_range` (
|
||||
`id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT,
|
||||
`start_ip` char(40) NOT NULL COMMENT 'start ip address',
|
||||
`end_ip` char(40) NOT NULL COMMENT 'end ip address',
|
||||
`vlan` int unsigned DEFAULT NULL COMMENT 'vlan the storage network on',
|
||||
`data_center_id` bigint unsigned NOT NULL,
|
||||
`network_id` bigint unsigned NOT NULL COMMENT 'id of corresponding network offering',
|
||||
PRIMARY KEY (`id`),
|
||||
CONSTRAINT `fk_storage_ip_range__network_id` FOREIGN KEY (`network_id`) REFERENCES `networks`(`id`),
|
||||
CONSTRAINT `fk_storage_ip_range__data_center_id` FOREIGN KEY (`data_center_id`) REFERENCES `data_center`(`id`),
|
||||
CONSTRAINT `fk_storage_ip_range___network_id` FOREIGN KEY (`physical_network_id`) REFERENCES `physical_network`(`id`)
|
||||
CONSTRAINT `uc_vlan__uuid` UNIQUE (`uuid`),
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE `cloud`.`op_dc_storage_network_ip_address` (
|
||||
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'primary key',
|
||||
`range_id` bigint unsigned NOT NULL COMMENT 'id of ip range in dc_storage_network_ip_range',
|
||||
`pod_id` bigint unsigned NOT NULL COMMENT 'pod it belongs to',
|
||||
`ip_address` char(40) NOT NULL COMMENT 'ip address',
|
||||
`mac_address` bigint unsigned NOT NULL COMMENT 'mac address for storage ips',
|
||||
`cidr_size` int unsigned NOT NULL COMMENT 'CIDR size for storage network',
|
||||
`taken` datetime COMMENT 'Date taken',
|
||||
PRIMARY KEY (`id`),
|
||||
CONSTRAINT `fk_storage_ip_address__range_id` FOREIGN KEY (`range_id`) REFERENCES `dc_storage_network_ip_range`(`id`) ON DELETE CASCADE,
|
||||
CONSTRAINT `fk_storage_ip_address__pod_id` FOREIGN KEY (`pod_id`) REFERENCES `host_pod_ref`(`id`),
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
CREATE TABLE `cloud`.`host_pod_ref` (
|
||||
`id` bigint unsigned NOT NULL UNIQUE auto_increment,
|
||||
`name` varchar(255),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user