Bug 12777 - Add storage network configuration into CloudStack

most finish
This commit is contained in:
frank 2012-01-04 13:32:49 -08:00
parent 0b01c5dc1a
commit f72940e041
24 changed files with 223 additions and 108 deletions

View File

@ -19,7 +19,7 @@ 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)
@Implementation(description="Creates a Storage network IP range.", responseObject=StorageNetworkIpRangeResponse.class)
public class CreateStorageNetworkIpRangeCmd extends BaseAsyncCmd {
public static final Logger s_logger = Logger.getLogger(CreateStorageNetworkIpRangeCmd.class);
@ -29,27 +29,23 @@ public class CreateStorageNetworkIpRangeCmd extends BaseAsyncCmd {
//////////////// 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.")
@Parameter(name=ApiConstants.POD_ID, type=CommandType.LONG, description="UUID of pod where the ip range belongs to")
private Long podId;
@Parameter(name=ApiConstants.START_IP, type=CommandType.STRING, required=true, description="the beginning IP address in the VLAN IP range")
@Parameter(name=ApiConstants.START_IP, type=CommandType.STRING, required=true, description="the beginning IP address")
private String startIp;
@Parameter(name=ApiConstants.END_IP, type=CommandType.STRING, description="the ending IP address in the VLAN IP range")
@Parameter(name=ApiConstants.END_IP, type=CommandType.STRING, description="the ending IP address")
private String endIp;
@Parameter(name=ApiConstants.VLAN, type=CommandType.INTEGER, description="the ID or VID of the VLAN. Optional, null means no vlan")
@Parameter(name=ApiConstants.VLAN, type=CommandType.INTEGER, description="Optional. the vlan the ip range sits on")
private Integer vlan;
@IdentityMapper(entityTableName="data_center")
@Parameter(name=ApiConstants.ZONE_ID, type=CommandType.LONG, description="the Zone ID of the VLAN IP range")
@Parameter(name=ApiConstants.ZONE_ID, type=CommandType.LONG, description="The uuid of zone")
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")
@Parameter(name=ApiConstants.NETMASK, type=CommandType.STRING, required=true, description="the netmask for storage network")
private String netmask;
/////////////////////////////////////////////////////
@ -75,11 +71,7 @@ public class CreateStorageNetworkIpRangeCmd extends BaseAsyncCmd {
public Long getZoneId() {
return zoneId;
}
public Long getNetworkID() {
return networkID;
}
public String getNetmask() {
return netmask;
}

View File

@ -29,7 +29,7 @@ public class DeleteStorageNetworkIpRangeCmd extends BaseAsyncCmd {
/////////////////////////////////////////////////////
@IdentityMapper(entityTableName="dc_storage_network_ip_range")
@Parameter(name=ApiConstants.ID, type=CommandType.LONG, required=true, description="the storage network IP range ID")
@Parameter(name=ApiConstants.ID, type=CommandType.LONG, required=true, description="the uuid of the storage network ip range")
private Long id;
/////////////////////////////////////////////////////

View File

@ -34,15 +34,15 @@ public class listStorageNetworkIpRangeCmd extends BaseAsyncCmd {
/////////////////////////////////////////////////////
@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.")
@Parameter(name=ApiConstants.ID, type=CommandType.LONG, description="optional parameter. Storaget network IP range uuid, 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.")
@Parameter(name=ApiConstants.POD_ID, type=CommandType.LONG, description="optional parameter. Pod uuid, if specicied and range uuid 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.")
@Parameter(name=ApiConstants.ZONE_ID, type=CommandType.LONG, description="optional parameter. Zone uuid, if specicied and both pod uuid and range uuid are absent, using it to search the range.")
private Long zoneId;
/////////////////////////////////////////////////////

View File

@ -6,14 +6,14 @@ 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 uuid of storage network IP range.")
private String uuid;
@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.POD_ID) @Param(description="the Pod uuid for the VLAN IP range")
private String podUuid;
@SerializedName(ApiConstants.START_IP) @Param(description="the start ip of the VLAN IP range")
private String startIp;
@ -21,26 +21,26 @@ public class StorageNetworkIpRangeResponse extends BaseResponse {
@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.NETWORK_ID) @Param(description="the network uuid of vlan range")
private String networkUuid;
@SerializedName(ApiConstants.ZONE_ID) @Param(description="the Zone ID of the VLAN IP range")
private IdentityProxy zoneId = new IdentityProxy("data_center");
@SerializedName(ApiConstants.ZONE_ID) @Param(description="the Zone uuid of the VLAN IP range")
private String zoneUuid;
public void setId(Long id) {
this.id = id;
public void setUuid(String uuId) {
this.uuid = uuid;
}
public void setZoneId(Long zoneId) {
this.zoneId.setValue(zoneId);
public void setZoneUuid(String zoneUuid) {
this.zoneUuid = zoneUuid;
}
public void setVlan(Integer vlan) {
this.vlan = vlan;
}
public void setPodId(Long podId) {
this.podId.setValue(podId);
public void setPodUuid(String podUuid) {
this.podUuid = podUuid;
}
public void setStartIp(String startIp) {
@ -51,7 +51,7 @@ public class StorageNetworkIpRangeResponse extends BaseResponse {
this.endIp = endIp;
}
public void setNetworkId(Long networkId) {
this.networkId.setValue(networkId);
public void setNetworkUuid(String networkUuid) {
this.networkUuid = networkUuid;
}
}

View File

@ -1,17 +1,17 @@
package com.cloud.dc;
public interface StorageNetworkIpRange {
long getId();
String getUuid();
int getVlan();
Integer getVlan();
long getPodId();
String getPodUuid();
String getStartIp();
String getEndIp();
long getNetworkId();
String getNetworkUuid();
long getDataCenterId();
String getZoneUuid();
}

1
api/src/com/cloud/network/Networks.java Normal file → Executable file
View File

@ -61,6 +61,7 @@ public class Networks {
Vswitch("vs", String.class),
LinkLocal(null, null),
Vnet("vnet", Long.class),
Storage("storage", Integer.class),
UnDecided(null, null);
private String scheme;

View File

@ -317,3 +317,10 @@ addTrafficType=com.cloud.api.commands.AddTrafficTypeCmd;1
deleteTrafficType=com.cloud.api.commands.DeleteTrafficTypeCmd;1
listTrafficTypes=com.cloud.api.commands.ListTrafficTypesCmd;1
updateTrafficType=com.cloud.api.commands.UpdateTrafficTypeCmd;1
#### Storage Network commands
createStorageNetworkIpRange=com.cloud.api.commands.CreateStorageNetworkIpRangeCmd;1
deleteStorageNetworkIpRange=com.cloud.api.commands.DeleteStorageNetworkIpRangeCmd;1
listStorageNetworkIpRange=com.cloud.api.commands.listStorageNetworkIpRangeCmd;1

View File

@ -59,6 +59,7 @@
<adapter name="ControlNetworkGuru" class="com.cloud.network.guru.ControlNetworkGuru"/>
<adapter name="DirectNetworkGuru" class="com.cloud.network.guru.DirectNetworkGuru"/>
<adapter name="DirectPodBasedNetworkGuru" class="com.cloud.network.guru.DirectPodBasedNetworkGuru"/>
<adapter name="StorageNetworkGuru" class="com.cloud.network.guru.StorageNetworkGuru"/>
</adapters>
<adapters key="com.cloud.cluster.ClusterServiceAdapter">
<adapter name="ClusterService" class="com.cloud.cluster.ClusterServiceServletAdapter"/>

View File

@ -650,6 +650,14 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
long account = Long.parseLong(nic.getBroadcastUri().getHost());
return createTunnelNetwork(conn, account);
}
} else if (nic.getBroadcastType() == BroadcastDomainType.Storage) {
URI broadcastUri = nic.getBroadcastUri();
if (broadcastUri == null) {
return network.getNetwork();
} else {
long vlan = Long.parseLong(broadcastUri.getHost());
return enableVlanNetwork(conn, vlan, network);
}
}
throw new CloudRuntimeException("Unable to support this type of network broadcast domain: " + nic.getBroadcastUri());

View File

@ -589,10 +589,26 @@ setup_dhcpsrvr() {
fi
}
setup_storage_network() {
if [ x"$STORAGE_IP" == "x" -o x"$STORAGE_NETMASK" == "x" ]
then
log_it "Incompleted parameters STORAGE_IP:$STORAGE_IP, STORAGE_NETMASK:$STORAGE_NETMASK, STORAGE_CIDR:$STORAGE_CIDR. Cannot setup storage network"
return
fi
echo "" >> /etc/network/interfaces
echo "auto eth3" >> /etc/network/interfaces
setup_interface "3" "$STORAGE_IP" "$STORAGE_NETMASK"
#ip route add "$STORAGE_CIDR" via "$STORAGE_IP"
log_it "Successfully setup storage network with STORAGE_IP:$STORAGE_IP, STORAGE_NETMASK:$STORAGE_NETMASK, STORAGE_CIDR:$STORAGE_CIDR"
}
setup_secstorage() {
log_it "Setting up secondary storage system vm"
local hyp=$1
setup_common eth0 eth1 eth2
setup_storage_network
[ -n "$MTU" ] && ifconfig eth1 mtu $MTU
sed -i /gateway/d /etc/hosts
public_ip=$ETH2_IP
@ -719,6 +735,9 @@ CMDLINE=$(cat /var/cache/cloud/cmdline)
TYPE="unknown"
BOOTPROTO="static"
DISABLE_RP_FILTER="false"
STORAGE_IP=""
STORAGE_NETMASK=""
STORAGE_CIDR=""
for i in $CMDLINE
do
@ -787,8 +806,8 @@ for i in $CMDLINE
SSHONGUEST=$VALUE
;;
name)
NAME=$VALUE
;;
NAME=$VALUE
;;
dhcprange)
DHCP_RANGE=$(echo $VALUE | tr ':' ',')
;;
@ -797,7 +816,7 @@ for i in $CMDLINE
;;
type)
TYPE=$VALUE
;;
;;
defaultroute)
DEFAULTROUTE=$VALUE
;;
@ -825,6 +844,15 @@ for i in $CMDLINE
mtu)
MTU=$VALUE
;;
storageip)
STORAGE_IP=$VALUE
;;
storagenetmask)
STORAGE_NETMASK=$VALUE
;;
storagecidr)
STORAGE_CIDR=$VALUE
;;
esac
done
}

View File

@ -3241,13 +3241,13 @@ public class ApiResponseHelper implements ResponseGenerator {
@Override
public StorageNetworkIpRangeResponse createStorageNetworkIpRangeResponse(StorageNetworkIpRange result) {
StorageNetworkIpRangeResponse response = new StorageNetworkIpRangeResponse();
response.setId(result.getId());
response.setUuid(result.getUuid());
response.setVlan(result.getVlan());
response.setEndIp(result.getEndIp());
response.setStartIp(result.getStartIp());
response.setPodId(result.getPodId());
response.setZoneId(result.getDataCenterId());
response.setNetworkId(result.getNetworkId());
response.setPodUuid(result.getPodUuid());
response.setZoneUuid(result.getZoneUuid());
response.setNetworkUuid(result.getNetworkUuid());
return response;
}
}

View File

@ -55,6 +55,8 @@ import com.cloud.dc.dao.DataCenterIpAddressDaoImpl;
import com.cloud.dc.dao.DcDetailsDaoImpl;
import com.cloud.dc.dao.HostPodDaoImpl;
import com.cloud.dc.dao.PodVlanMapDaoImpl;
import com.cloud.dc.dao.StorageNetworkIpAddressDaoImpl;
import com.cloud.dc.dao.StorageNetworkIpRangeDaoImpl;
import com.cloud.dc.dao.VlanDaoImpl;
import com.cloud.domain.dao.DomainDaoImpl;
import com.cloud.event.dao.EventDaoImpl;
@ -71,6 +73,7 @@ import com.cloud.keystore.KeystoreManagerImpl;
import com.cloud.maint.UpgradeManagerImpl;
import com.cloud.maint.dao.AgentUpgradeDaoImpl;
import com.cloud.network.NetworkManagerImpl;
import com.cloud.network.StorageNetworkManagerImpl;
import com.cloud.network.dao.ExternalFirewallDeviceDaoImpl;
import com.cloud.network.dao.ExternalLoadBalancerDeviceDaoImpl;
import com.cloud.network.dao.FirewallRulesCidrsDaoImpl;
@ -327,6 +330,8 @@ public class DefaultComponentLibrary extends ComponentLibraryBase implements Com
addDao("NetworkExternalFirewallDao", NetworkExternalFirewallDaoImpl.class);
addDao("PhysicalNetworkTrafficTypeDao", PhysicalNetworkTrafficTypeDaoImpl.class);
addDao("NetworkServiceMapDao", NetworkServiceMapDaoImpl.class);
addDao("StorageNetworkIpAddressDao", StorageNetworkIpAddressDaoImpl.class);
addDao("StorageNetworkIpRangeDao", StorageNetworkIpRangeDaoImpl.class);
}
@Override
@ -382,6 +387,7 @@ public class DefaultComponentLibrary extends ComponentLibraryBase implements Com
addManager("ProjectManager", ProjectManagerImpl.class);
addManager("ElasticLoadBalancerManager", ElasticLoadBalancerManagerImpl.class);
addManager("SwiftManager", SwiftManagerImpl.class);
addManager("StorageNetworkManager", StorageNetworkManagerImpl.class);
}
@Override

View File

@ -7,6 +7,9 @@ import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.SecondaryTable;
import javax.persistence.SecondaryTables;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
@ -15,6 +18,7 @@ import com.cloud.network.IpAddress.State;
@Entity
@Table(name="op_dc_storage_network_ip_address")
@SecondaryTables({@SecondaryTable(name = "dc_storage_network_ip_range", pkJoinColumns = { @PrimaryKeyJoinColumn(name = "range_id", referencedColumnName = "id")})})
public class StorageNetworkIpAddressVO {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@ -36,6 +40,9 @@ public class StorageNetworkIpAddressVO {
@Column(name = "mac_address")
long mac;
@Column(name = "vlan", table = "dc_storage_network_ip_range", insertable = false, updatable = false)
Integer vlan;
protected StorageNetworkIpAddressVO() {
}
@ -83,4 +90,8 @@ public class StorageNetworkIpAddressVO {
public void setCidrSize(int cidr) {
this.cidrSize =cidr;
}
public Integer getVlan() {
return vlan;
}
}

View File

@ -1,22 +1,34 @@
package com.cloud.dc;
import java.util.UUID;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.PrimaryKeyJoinColumn;
import javax.persistence.SecondaryTable;
import javax.persistence.SecondaryTables;
import javax.persistence.Table;
@Entity
@Table(name="dc_storage_network_ip_range")
@SecondaryTables({@SecondaryTable(name="networks", pkJoinColumns={@PrimaryKeyJoinColumn(name="network_id", referencedColumnName="id")}),
@SecondaryTable(name="host_pod_ref", pkJoinColumns={@PrimaryKeyJoinColumn(name="pod_id", referencedColumnName="id")}),
@SecondaryTable(name="data_center", pkJoinColumns={@PrimaryKeyJoinColumn(name="data_center_id", referencedColumnName="id")}),
})
public class StorageNetworkIpRangeVO implements StorageNetworkIpRange {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
private long id;
@Column(name = "uuid")
String uuid;
@Column(name = "vlan")
private int vlan;
private Integer vlan;
@Column(name = "data_center_id")
private long dataCenterId;
@ -33,7 +45,17 @@ public class StorageNetworkIpRangeVO implements StorageNetworkIpRange {
@Column(name = "network_id")
private long networkId;
public StorageNetworkIpRangeVO(long dcId, long podId, long networkId, String startIp, String endIp, int vlan) {
@Column(name = "uuid", table = "networks", insertable = false, updatable = false)
String networkUuid;
@Column(name = "uuid", table = "host_pod_ref", insertable = false, updatable = false)
String podUuid;
@Column(name = "uuid", table = "data_center", insertable = false, updatable = false)
String zoneUuid;
public StorageNetworkIpRangeVO(long dcId, long podId, long networkId, String startIp, String endIp, Integer vlan) {
this();
this.dataCenterId = dcId;
this.podId = podId;
this.networkId = networkId;
@ -43,7 +65,7 @@ public class StorageNetworkIpRangeVO implements StorageNetworkIpRange {
}
protected StorageNetworkIpRangeVO() {
this.uuid = UUID.randomUUID().toString();
}
public long getId() {
@ -74,7 +96,7 @@ public class StorageNetworkIpRangeVO implements StorageNetworkIpRange {
this.networkId = nwId;
}
public int getVlan() {
public Integer getVlan() {
return vlan;
}
@ -93,8 +115,28 @@ public class StorageNetworkIpRangeVO implements StorageNetworkIpRange {
public void setEndIp(String end) {
this.endIp = end;
}
public String getEndIp() {
return endIp;
}
@Override
public String getUuid() {
return uuid;
}
@Override
public String getPodUuid() {
return podUuid;
}
@Override
public String getNetworkUuid() {
return networkUuid;
}
@Override
public String getZoneUuid() {
return zoneUuid;
}
}

View File

@ -33,13 +33,13 @@ public class StorageNetworkIpAddressDaoImpl extends GenericDaoBase<StorageNetwor
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.and("taken", countInUserIp.entity().getTakenAt(), Op.NNULL);
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.and("taken", listInUseIp.entity().getTakenAt(), Op.NNULL);
listInUseIp.done();
untakenIp = createSearchBuilder();

View File

@ -11,4 +11,6 @@ public interface StorageNetworkIpRangeDao extends GenericDao<StorageNetworkIpRan
List<StorageNetworkIpRangeVO> listByPodId(long podId);
List<StorageNetworkIpRangeVO> listByDataCenterId(long dcId);
long countRanges();
}

View File

@ -3,9 +3,11 @@ package com.cloud.dc.dao;
import java.util.List;
import java.util.Map;
import javax.ejb.Local;
import javax.naming.ConfigurationException;
import com.cloud.dc.StorageNetworkIpRangeVO;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.Filter;
import com.cloud.utils.db.GenericDaoBase;
import com.cloud.utils.db.GenericSearchBuilder;
@ -13,10 +15,20 @@ 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.Func;
import com.cloud.utils.db.SearchCriteria.Op;
@Local(value={StorageNetworkIpRangeDao.class})
@DB(txn=false)
public class StorageNetworkIpRangeDaoImpl extends GenericDaoBase<StorageNetworkIpRangeVO, Long> implements StorageNetworkIpRangeDao {
protected final GenericSearchBuilder<StorageNetworkIpRangeVO, Long> countRanges;
protected StorageNetworkIpRangeDaoImpl() {
countRanges = createSearchBuilder(Long.class);
countRanges.select(null, Func.COUNT, null);
countRanges.done();
}
@Override
public List<StorageNetworkIpRangeVO> listByPodId(long podId) {
SearchCriteriaService<StorageNetworkIpRangeVO, StorageNetworkIpRangeVO> sc = SearchCriteria2.create(StorageNetworkIpRangeVO.class);
@ -37,5 +49,11 @@ public class StorageNetworkIpRangeDaoImpl extends GenericDaoBase<StorageNetworkI
sc.addAnd(sc.getEntity().getDataCenterId(), Op.EQ, dcId);
return sc.list();
}
@Override
public long countRanges() {
SearchCriteria<Long> sc = countRanges.create();
return customSearch(sc, null).get(0);
}
}

View File

@ -8,5 +8,5 @@ public interface StorageNetworkManager extends Manager {
void releaseIpAddress(String ip);
boolean isAStorageIpAddress(String ip);
boolean isStorageIpRangeAvailable();
}

View File

@ -91,7 +91,7 @@ public class StorageNetworkManagerImpl implements StorageNetworkManager, Storage
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());
throw new InvalidParameterValueException("The Storage network Start IP and endIP address range overlap with private IP :" + range.getStartIp() + " - " + range.getEndIp());
}
}
}
@ -180,7 +180,7 @@ public class StorageNetworkManagerImpl implements StorageNetworkManager, Storage
StringBuilder res = new StringBuilder();
res.append("Below IP of range " + rangeId + " is still in use:");
for (String ip : ips) {
res.append(ip);
res.append(ip).append(",");
}
return res.toString();
}
@ -269,10 +269,8 @@ public class StorageNetworkManagerImpl implements StorageNetworkManager, Storage
}
@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;
public boolean isStorageIpRangeAvailable() {
return _sNwIpRangeDao.countRanges() > 0;
}
}

View File

@ -40,6 +40,7 @@ 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;
@ -58,6 +59,7 @@ import com.cloud.vm.VirtualMachineProfile;
public class PodBasedNetworkGuru extends AdapterBase implements NetworkGuru {
private static final Logger s_logger = Logger.getLogger(PodBasedNetworkGuru.class);
@Inject DataCenterDao _dcDao;
@Inject StorageNetworkManager _sNwMgr;
Random _rand = new Random(System.currentTimeMillis());
@Override
@ -68,6 +70,11 @@ public class PodBasedNetworkGuru extends AdapterBase implements NetworkGuru {
return null;
}
if (type == TrafficType.Storage && _sNwMgr.isStorageIpRangeAvailable()) {
s_logger.debug("There is some storage ip available, let StorageNetworkGuru to handle storage traffic type, not me");
return null;
}
NetworkVO config = new NetworkVO(type, Mode.Static, BroadcastDomainType.Native, offering.getId(), Network.State.Setup, plan.getDataCenterId(), plan.getPhysicalNetworkId());
return config;
}
@ -84,7 +91,7 @@ public class PodBasedNetworkGuru extends AdapterBase implements NetworkGuru {
public NicProfile allocate(Network config, NicProfile nic, VirtualMachineProfile<? extends VirtualMachine> vm) throws InsufficientVirtualNetworkCapcityException,
InsufficientAddressCapacityException {
TrafficType trafficType = config.getTrafficType();
assert (trafficType == TrafficType.Storage || trafficType == TrafficType.Management) : "Well, I can't take care of this config now can I? " + config;
assert trafficType == TrafficType.Management || trafficType == TrafficType.Storage: "Well, I can't take care of this config now can I? " + config;
if (nic != null) {
if (nic.getRequestedIp() != null) {

View File

@ -37,7 +37,6 @@ import com.cloud.vm.Nic.ReservationStrategy;
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();
@ -45,7 +44,12 @@ public class StorageNetworkGuru extends AdapterBase implements NetworkGuru {
protected boolean canHandle(NetworkOffering offering) {
if (offering.getTrafficType() == TrafficType.Storage && offering.isSystemOnly()) {
return true;
if (_sNwMgr.isStorageIpRangeAvailable()) {
return true;
} else {
s_logger.debug("No storage network ip range availabe, let PodBasedNetworkGuru to handle storage traffic type, not me");
return false;
}
} else {
s_logger.trace("It's not storage network offering, skip it.");
return false;
@ -93,48 +97,32 @@ public class StorageNetworkGuru extends AdapterBase implements NetworkGuru {
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;
Integer vlan = 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();
if (ip == null) {
throw new InsufficientAddressCapacityException("Unable to get a storage network ip address", Pod.class, pod.getId());
}
nic.setIp4Address(ipAddress);
nic.setMacAddress(NetUtils.long2Mac(NetUtils.createSequenceBasedMacAddress(macLong)));
vlan = ip.getVlan();
nic.setIp4Address(ip.getIpAddress());
nic.setMacAddress(NetUtils.long2Mac(NetUtils.createSequenceBasedMacAddress(ip.getMac())));
nic.setFormat(AddressFormat.Ip4);
nic.setNetmask(NetUtils.getCidrNetmask(cidrSize));
nic.setBroadcastType(BroadcastDomainType.Native);
nic.setBroadcastUri(null);
nic.setNetmask(NetUtils.getCidrNetmask(ip.getCidrSize()));
nic.setBroadcastType(BroadcastDomainType.Storage);
if (vlan != null) {
nic.setBroadcastUri(BroadcastDomainType.Storage.toUri(vlan));
} else {
nic.setBroadcastUri(null);
}
nic.setIsolationUri(null);
s_logger.debug("Allocated a nic " + nic + " for " + vm);
s_logger.debug("Allocated a storage 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());
}
_sNwMgr.releaseIpAddress(nic.getIp4Address());
s_logger.debug("Release an storage ip " + nic.getIp4Address());
nic.deallocate();
return true;
}

View File

@ -79,6 +79,7 @@ import com.cloud.network.guru.ControlNetworkGuru;
import com.cloud.network.guru.DirectPodBasedNetworkGuru;
import com.cloud.network.guru.PodBasedNetworkGuru;
import com.cloud.network.guru.PublicNetworkGuru;
import com.cloud.network.guru.StorageNetworkGuru;
import com.cloud.offering.NetworkOffering;
import com.cloud.offering.NetworkOffering.Availability;
import com.cloud.offerings.NetworkOfferingServiceMapVO;
@ -953,7 +954,7 @@ public class ConfigurationServerImpl implements ConfigurationServer {
guruNames.put(TrafficType.Public, PublicNetworkGuru.class.getSimpleName());
guruNames.put(TrafficType.Management, PodBasedNetworkGuru.class.getSimpleName());
guruNames.put(TrafficType.Control, ControlNetworkGuru.class.getSimpleName());
guruNames.put(TrafficType.Storage, PodBasedNetworkGuru.class.getSimpleName());
guruNames.put(TrafficType.Storage, StorageNetworkGuru.class.getSimpleName());
guruNames.put(TrafficType.Guest, DirectPodBasedNetworkGuru.class.getSimpleName());
for (DataCenterVO zone : zones) {
@ -978,7 +979,7 @@ public class ConfigurationServerImpl implements ConfigurationServer {
TrafficType trafficType= offering.getTrafficType();
boolean isNetworkDefault = false;
if (trafficType == TrafficType.Management || trafficType == TrafficType.Storage) {
if (trafficType == TrafficType.Management) {
broadcastDomainType = BroadcastDomainType.Native;
} else if (trafficType == TrafficType.Control) {
broadcastDomainType = BroadcastDomainType.LinkLocal;
@ -997,6 +998,8 @@ public class ConfigurationServerImpl implements ConfigurationServer {
}
networkDomain = "cs" + Long.toHexString(Account.ACCOUNT_ID_SYSTEM) + _domainSuffix;
} else if (offering.getTrafficType() == TrafficType.Storage) {
broadcastDomainType = BroadcastDomainType.Storage;
}
if (broadcastDomainType != null) {

View File

@ -525,7 +525,7 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V
NetworkVO defaultNetwork = defaultNetworks.get(0);
List<NetworkOfferingVO> offerings = _networkMgr.getSystemAccountNetworkOfferings(NetworkOfferingVO.SystemControlNetwork, NetworkOfferingVO.SystemManagementNetwork);
List<NetworkOfferingVO> offerings = _networkMgr.getSystemAccountNetworkOfferings(NetworkOfferingVO.SystemControlNetwork, NetworkOfferingVO.SystemManagementNetwork, NetworkOfferingVO.SystemStorageNetwork);
List<Pair<NetworkVO, NicProfile>> networks = new ArrayList<Pair<NetworkVO, NicProfile>>(offerings.size() + 1);
NicProfile defaultNic = new NicProfile();
defaultNic.setDefaultNic(true);
@ -1034,6 +1034,9 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V
buf.append(" private.network.device=").append("eth").append(deviceId);
} else if (nic.getTrafficType() == TrafficType.Public) {
buf.append(" public.network.device=").append("eth").append(deviceId);
} else if (nic.getTrafficType() == TrafficType.Storage) {
buf.append(" storageip=").append(nic.getIp4Address());
buf.append(" storagenetmask=").append(nic.getNetmask());
}
}

View File

@ -562,29 +562,29 @@ CREATE TABLE `cloud`.`op_dc_link_local_ip_address_alloc` (
CREATE TABLE `cloud`.`dc_storage_network_ip_range` (
`id` bigint unsigned NOT NULL UNIQUE AUTO_INCREMENT,
`uuid` varchar(40),
`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,
`pod_id` bigint unsigned NOT NULL COMMENT 'pod it belongs to',
`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`),
CONSTRAINT `fk_storage_ip_range__pod_id` FOREIGN KEY (`pod_id`) REFERENCES `host_pod_ref`(`id`),
CONSTRAINT `uc_storage_ip_range__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`),
CONSTRAINT `fk_storage_ip_address__range_id` FOREIGN KEY (`range_id`) REFERENCES `dc_storage_network_ip_range`(`id`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `cloud`.`host_pod_ref` (