1)Introduced new Network Guru - used for direct tagged network.

2)Made vm start with multiple networks
This commit is contained in:
alena 2010-12-09 10:58:42 -08:00
parent 8fb948650f
commit 157156dd35
9 changed files with 238 additions and 35 deletions

View File

@ -44,6 +44,7 @@
<adapter name="PublicNetworkGuru" class="com.cloud.network.guru.PublicNetworkGuru"/>
<adapter name="PodBasedNetworkGuru" class="com.cloud.network.guru.PodBasedNetworkGuru"/>
<adapter name="ControlNetworkGuru" class="com.cloud.network.guru.ControlNetworkGuru"/>
<adapter name="DirectNetworkGuru" class="com.cloud.network.guru.DirectNetworkGuru"/>
</adapters>
<adapters key="com.cloud.storage.secondary.SecondaryStorageVmAllocator">
<adapter name="Balance" class="com.cloud.storage.secondary.SecondaryStorageVmDefaultAllocator"/>

View File

@ -1507,6 +1507,11 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura
throw new InvalidParameterValueException("Gateway, netmask and zoneId have to be passed in for virtual network");
}
//if end ip is not specified, default it to startIp
if (endIP == null && startIP != null) {
endIP = startIP;
}
//Verify that network is valid, and ip range matches network's cidr
if (networkId != null) {
NetworkVO network = _networkDao.findById(networkId);
@ -2455,9 +2460,9 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura
throw new InvalidParameterValueException("Please specify a valid IP range id.");
}
if (vlan.getNetworkId() != null) {
throw new InvalidParameterValueException("Fail to delete a vlan range as there are networks associated with it");
}
// if (vlan.getNetworkId() != null) {
// throw new InvalidParameterValueException("Fail to delete a vlan range as there are networks associated with it");
// }
return deleteVlanAndPublicIpRange(userId, vlanDbId);

View File

@ -19,6 +19,7 @@ package com.cloud.network;
import java.util.List;
import com.cloud.dc.Vlan.VlanType;
import com.cloud.deploy.DeployDestination;
import com.cloud.deploy.DeploymentPlan;
import com.cloud.exception.ConcurrentOperationException;
@ -112,4 +113,6 @@ public interface NetworkManager extends NetworkService {
String getNextAvailableMacAddressInNetwork(long networkConfigurationId) throws InsufficientAddressCapacityException;
boolean applyRules(Ip ip, List<? extends FirewallRule> rules, boolean continueOnError) throws ResourceUnavailableException;
PublicIp fetchNewPublicIp(long dcId, VlanType vlanUse, Account owner, Long networkId, boolean sourceNat) throws InsufficientAddressCapacityException;
}

View File

@ -192,14 +192,19 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
private Map<String, String> _configs;
@DB
protected PublicIp fetchNewPublicIp(long dcId, VlanType vlanUse, Account owner, Long networkId, boolean sourceNat) throws InsufficientAddressCapacityException {
@Override @DB
public PublicIp fetchNewPublicIp(long dcId, VlanType vlanUse, Account owner, Long networkId, boolean sourceNat) throws InsufficientAddressCapacityException {
Transaction txn = Transaction.currentTxn();
txn.start();
SearchCriteria<IPAddressVO> sc = AssignIpAddressSearch.create();
sc.setParameters("dc", dcId);
sc.setJoinParameters("vlan", "type", vlanUse);
//for direct network take ip addresses only from the vlans belonging to the network
if (vlanUse == VlanType.DirectAttached) {
sc.setJoinParameters("vlan", "networkId", networkId);
}
sc.setJoinParameters("vlan", "type", vlanUse);
Filter filter = new Filter(IPAddressVO.class, "vlanId", true, 0l, 1l);
List<IPAddressVO> addrs = _ipAddressDao.lockRows(sc, filter, true);
@ -214,7 +219,11 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
addr.setAllocatedTime(new Date());
addr.setAllocatedInDomainId(owner.getDomainId());
addr.setAllocatedToAccountId(owner.getId());
addr.setAssociatedNetworkId(networkId);
addr.setState(IpAddress.State.Allocating);
if (vlanUse == VlanType.DirectAttached) {
addr.setState(IpAddress.State.Allocated);
}
if (!_ipAddressDao.update(addr.getAddress(), addr)) {
throw new CloudRuntimeException("Found address to allocate but unable to update: " + addr);
@ -445,6 +454,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
for (IPAddressVO addr : userIps) {
if (addr.getState() == IpAddress.State.Allocating) {
addr.setState(IpAddress.State.Allocated);
addr.setAssociatedNetworkId(network.getId());
_ipAddressDao.update(addr.getAddress(), addr);
} else if (addr.getState() == IpAddress.State.Releasing) {
_ipAddressDao.unassignIpAddress(addr.getAddress());
@ -531,7 +541,6 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
_accountMgr.incrementResourceCount(ownerId, ResourceType.public_ip);
String ipAddress = ip.getAddress();
event.setParameters("address=" + ipAddress + "\nsourceNat=" + false + "\ndcId=" + zoneId);
event.setDescription("Assigned a public IP address: " + ipAddress);
_eventDao.persist(event);
@ -714,6 +723,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
AssignIpAddressSearch.and("allocated", AssignIpAddressSearch.entity().getAllocatedTime(), Op.NULL);
AssignIpAddressSearch.join("vlan", vlanSearch, vlanSearch.entity().getId(), AssignIpAddressSearch.entity().getVlanId(), JoinType.INNER);
vlanSearch.and("type", vlanSearch.entity().getVlanType(), Op.EQ);
vlanSearch.and("networkId", vlanSearch.entity().getNetworkId(), Op.EQ);
AssignIpAddressSearch.done();
IpAddressSearch = _ipAddressDao.createSearchBuilder();
@ -773,17 +783,21 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
throw new ConcurrentOperationException("Unable to acquire lock on " + owner);
}
try {
List<NetworkVO> configs = _networksDao.listBy(owner.getId(), offering.getId(), plan.getDataCenterId());
if (predefined == null || (predefined.getBroadcastUri() == null && predefined.getBroadcastDomainType() != BroadcastDomainType.Vlan)) {
List<NetworkVO> configs = _networksDao.listBy(owner.getId(), offering.getId(), plan.getDataCenterId());
if (configs.size() > 0) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Found existing network configuration for offering " + offering + ": " + configs.get(0));
}
return configs;
}
} else if (predefined != null && predefined.getBroadcastUri() != null) {
//don't allow duplicated vlans in the same zone
List<NetworkVO> configs = _networksDao.listBy(owner.getId(), offering.getId(), plan.getDataCenterId());
}
configs = new ArrayList<NetworkVO>();
List<NetworkVO> configs = new ArrayList<NetworkVO>();
long related = -1;
@ -1047,16 +1061,17 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
nic.setNetmask(profile.getNetmask());
nic.setGateway(profile.getGateway());
nic.setAddressFormat(profile.getFormat());
_nicDao.update(nic.getId(), nic);
for (NetworkElement element : _networkElements) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Asking " + element.getName() + " to prepare for " + nic);
}
element.prepare(config, profile, vmProfile, dest, context);
}
_nicDao.update(nic.getId(), nic);
} else {
profile = new NicProfile(nic, config, nic.getBroadcastUri(), nic.getIsolationUri());
}
for (NetworkElement element : _networkElements) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Asking " + element.getName() + " to prepare for " + nic);
}
element.prepare(config, profile, vmProfile, dest, context);
}
vmProfile.addNic(profile);
}
@ -1587,6 +1602,11 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
Boolean isShared = cmd.getIsShared();
Account owner = null;
//if end ip is not specified, default it to startIp
if (endIP == null && startIP != null) {
endIP = startIP;
}
//Check if network offering exists
NetworkOfferingVO networkOffering = _networkOfferingDao.findById(networkOfferingId);
if (networkOffering == null || networkOffering.isSystemOnly()) {
@ -1617,6 +1637,15 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
owner = ctxAccount;
}
//Don't allow to create network with vlan that already exists in the system
if (networkOffering.getGuestIpType() == GuestIpType.Direct && vlanId != null) {
String uri ="vlan://" + vlanId;
List<NetworkVO> networks = _networksDao.listBy(zoneId, uri);
if ((networks != null && !networks.isEmpty())) {
throw new InvalidParameterValueException("Network with vlan " + vlanId + " already exists in zone " + zoneId);
}
}
//if VlanId is Direct untagged, verify if there is already network of this type in the zone
if (networkOffering.getGuestIpType() == GuestIpType.DirectPodBased && vlanId != null && vlanId.equalsIgnoreCase(Vlan.UNTAGGED)) {
SearchBuilder<NetworkVO> sb = _networksDao.createSearchBuilder();

View File

@ -44,4 +44,6 @@ public interface NetworkDao extends GenericDao<NetworkVO, Long> {
String getNextAvailableMacAddress(long networkConfigId);
List<NetworkVO> listBy(long accountId, long networkId);
List<NetworkVO> listBy(long zoneId, String broadcastUri);
}

View File

@ -50,6 +50,7 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long> implements N
final SearchBuilder<NetworkVO> AccountSearch;
final SearchBuilder<NetworkVO> RelatedConfigSearch;
final SearchBuilder<NetworkVO> AccountNetworkSearch;
final SearchBuilder<NetworkVO> ZoneBroadcastUriSearch;
NetworkAccountDaoImpl _accountsDao = new NetworkAccountDaoImpl();
final TableGenerator _tgMacAddress;
@ -93,6 +94,12 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long> implements N
AccountNetworkSearch.join("networkSearch", mapJoin, AccountNetworkSearch.entity().getId(), mapJoin.entity().getNetworkId(), JoinBuilder.JoinType.INNER);
AccountNetworkSearch.done();
ZoneBroadcastUriSearch = createSearchBuilder();
ZoneBroadcastUriSearch.and("dataCenterId", ZoneBroadcastUriSearch.entity().getDataCenterId(), Op.EQ);
ZoneBroadcastUriSearch.and("broadcastUri", ZoneBroadcastUriSearch.entity().getBroadcastUri(), Op.EQ);
ZoneBroadcastUriSearch.done();
_tgMacAddress = _tgs.get("macAddress");
}
@ -200,4 +207,11 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long> implements N
sc.setJoinParameters("networkSearch", "accountId", accountId);
return listBy(sc);
}
public List<NetworkVO> listBy(long zoneId, String broadcastUri) {
SearchCriteria<NetworkVO> sc = ZoneBroadcastUriSearch.create();
sc.setParameters("dataCenterId", zoneId);
sc.setParameters("broadcastUri", broadcastUri);
return search(sc, null);
}
}

View File

@ -0,0 +1,158 @@
/**
*
*/
package com.cloud.network.guru;
import java.util.Random;
import javax.ejb.Local;
import org.apache.log4j.Logger;
import com.cloud.dc.DataCenter;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.Vlan.VlanType;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.dc.dao.VlanDao;
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.exception.InvalidParameterValueException;
import com.cloud.network.Network;
import com.cloud.network.NetworkManager;
import com.cloud.network.NetworkVO;
import com.cloud.network.Network.State;
import com.cloud.network.Networks.AddressFormat;
import com.cloud.network.Networks.BroadcastDomainType;
import com.cloud.network.Networks.IsolationType;
import com.cloud.network.Networks.Mode;
import com.cloud.network.Networks.TrafficType;
import com.cloud.network.addr.PublicIp;
import com.cloud.network.dao.IPAddressDao;
import com.cloud.offering.NetworkOffering;
import com.cloud.offering.NetworkOffering.GuestIpType;
import com.cloud.resource.Resource.ReservationStrategy;
import com.cloud.user.Account;
import com.cloud.utils.component.AdapterBase;
import com.cloud.utils.component.Inject;
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;
@Local(value={NetworkGuru.class})
public class DirectNetworkGuru extends AdapterBase implements NetworkGuru {
private static final Logger s_logger = Logger.getLogger(DirectNetworkGuru.class);
@Inject DataCenterDao _dcDao;
@Inject VlanDao _vlanDao;
@Inject NetworkManager _networkMgr;
@Inject IPAddressDao _ipAddressDao;
Random _rand = new Random(System.currentTimeMillis());
@Override
public Network design(NetworkOffering offering, DeploymentPlan plan, Network userSpecified, Account owner) {
//Change traffic type to Public after Alex's fix
if (!(offering.getTrafficType() == TrafficType.Guest && offering.getGuestIpType() == GuestIpType.Direct)) {
s_logger.trace("We only take care of public direct network, so this is no ours");
return null;
}
NetworkVO config = new NetworkVO(offering.getTrafficType(), offering.getGuestIpType(), Mode.Dhcp, BroadcastDomainType.Vlan, offering.getId(), plan.getDataCenterId());
DataCenterVO dc = _dcDao.findById(plan.getDataCenterId());
if (userSpecified != null) {
if ((userSpecified.getCidr() == null && userSpecified.getGateway() != null) ||
(userSpecified.getCidr() != null && userSpecified.getGateway() == null)) {
throw new InvalidParameterValueException("cidr and gateway must be specified together.");
}
if (userSpecified.getCidr() != null) {
config.setCidr(userSpecified.getCidr());
config.setGateway(userSpecified.getGateway());
}
if (userSpecified.getBroadcastUri() != null) {
config.setBroadcastUri(userSpecified.getBroadcastUri());
config.setState(State.Setup);
}
}
config.setDns1(dc.getDns1());
config.setDns2(dc.getDns2());
return config;
}
protected DirectNetworkGuru() {
super();
}
protected void getIp(NicProfile nic, DataCenter dc, VirtualMachineProfile<? extends VirtualMachine> vm, Network network) throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException, ConcurrentOperationException {
if (nic.getIp4Address() == null) {
PublicIp ip = _networkMgr.fetchNewPublicIp(dc.getId(), VlanType.DirectAttached, vm.getOwner(), network.getId(), false);
nic.setIp4Address(ip.getAddress());
nic.setGateway(ip.getGateway());
nic.setNetmask(ip.getNetmask());
nic.setIsolationUri(IsolationType.Vlan.toUri(ip.getVlanTag()));
nic.setBroadcastType(BroadcastDomainType.Vlan);
nic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(ip.getVlanTag()));
nic.setFormat(AddressFormat.Ip4);
nic.setReservationId(ip.getVlanTag());
nic.setMacAddress(NetUtils.long2Mac(ip.getMacAddress() | 0x060000000000l | (((long)_rand.nextInt(32768) << 25) & 0x00fffe000000l)));
}
nic.setDns1(dc.getDns1());
nic.setDns2(dc.getDns2());
}
@Override
public NicProfile allocate(Network network, NicProfile nic, VirtualMachineProfile<? extends VirtualMachine> vm) throws InsufficientVirtualNetworkCapcityException,
InsufficientAddressCapacityException, ConcurrentOperationException {
if (nic == null) {
nic = new NicProfile(ReservationStrategy.Create, null, null, null, null);
} else if (nic.getIp4Address() == null) {
nic.setStrategy(ReservationStrategy.Start);
} else {
nic.setStrategy(ReservationStrategy.Create);
}
DataCenter dc = _dcDao.findById(network.getDataCenterId());
getIp(nic, dc, vm, network);
return nic;
}
@Override
public void reserve(NicProfile nic, Network network, VirtualMachineProfile<? extends VirtualMachine> vm, DeployDestination dest, ReservationContext context) throws InsufficientVirtualNetworkCapcityException, InsufficientAddressCapacityException, ConcurrentOperationException {
if (nic.getIp4Address() == null) {
getIp(nic, dest.getDataCenter(), vm, network);
}
}
@Override
public boolean release(NicProfile nic, VirtualMachineProfile<? extends VirtualMachine> vm, String reservationId) {
return true;
}
@Override
public Network implement(Network network, NetworkOffering offering, DeployDestination destination, ReservationContext context) {
return network;
}
@Override
public void deallocate(Network network, NicProfile nic, VirtualMachineProfile<? extends VirtualMachine> vm) {
}
@Override
public void destroy(Network network, NetworkOffering offering) {
}
@Override
public boolean trash(Network network, NetworkOffering offering, Account owner) {
return true;
}
}

View File

@ -71,7 +71,7 @@ public class GuestNetworkGuru extends AdapterBase implements NetworkGuru {
@Override
public Network design(NetworkOffering offering, DeploymentPlan plan, Network userSpecified, Account owner) {
if (offering.getTrafficType() != TrafficType.Guest) {
if (offering.getTrafficType() != TrafficType.Guest || offering.getGuestIpType() != GuestIpType.Virtual) {
return null;
}

View File

@ -132,7 +132,6 @@ import com.cloud.network.rules.PortForwardingRule;
import com.cloud.network.rules.PortForwardingRuleVO;
import com.cloud.network.rules.RulesManager;
import com.cloud.offering.NetworkOffering;
import com.cloud.offering.NetworkOffering.GuestIpType;
import com.cloud.offerings.NetworkOfferingVO;
import com.cloud.offerings.dao.NetworkOfferingDao;
import com.cloud.service.ServiceOfferingVO;
@ -177,9 +176,9 @@ import com.cloud.vm.State;
import com.cloud.vm.UserVmVO;
import com.cloud.vm.VirtualMachine;
import com.cloud.vm.VirtualMachineGuru;
import com.cloud.vm.VirtualMachineManager;
import com.cloud.vm.VirtualMachineName;
import com.cloud.vm.VirtualMachineProfile;
import com.cloud.vm.VirtualMachineManager;
import com.cloud.vm.dao.DomainRouterDao;
import com.cloud.vm.dao.NicDao;
import com.cloud.vm.dao.UserVmDao;
@ -2174,21 +2173,13 @@ public class DomainRouterManagerImpl implements DomainRouterManager, DomainRoute
String type = null;
String dhcpRange = null;
if (network.getGuestType() == GuestIpType.Virtual) {
//If network is virtual, get first ip address from cidr
String cidr = network.getCidr();
String[] splitResult = cidr.split("\\/");
long size = Long.valueOf(splitResult[1]);
dhcpRange = NetUtils.getIpRangeStartIpFromCidr(splitResult[0], size);
} else {
//If network is direct, get first ip address of corresponding vlan
List<VlanVO> vlans = _vlanDao.listVlansByNetworkId(network.getId());
if (vlans != null) {
String ipRange = vlans.get(0).getIpRange();
String[] ips = ipRange.split("-");
dhcpRange = ips[0];
}
}
//get first ip address from network cidr
String cidr = network.getCidr();
String[] splitResult = cidr.split("\\/");
long size = Long.valueOf(splitResult[1]);
dhcpRange = NetUtils.getIpRangeStartIpFromCidr(splitResult[0], size);
String domain = network.getNetworkDomain();
if (router.getRole() == Role.DHCP_USERDATA) {