diff --git a/client/tomcatconf/components.xml.in b/client/tomcatconf/components.xml.in
index e7095585d93..7164a764dd5 100755
--- a/client/tomcatconf/components.xml.in
+++ b/client/tomcatconf/components.xml.in
@@ -44,6 +44,7 @@
+
diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
index b45b6600f5d..fbe8a5c6cbd 100755
--- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
+++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java
@@ -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);
diff --git a/server/src/com/cloud/network/NetworkManager.java b/server/src/com/cloud/network/NetworkManager.java
index d86f097123f..83006c00878 100644
--- a/server/src/com/cloud/network/NetworkManager.java
+++ b/server/src/com/cloud/network/NetworkManager.java
@@ -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;
}
diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java
index 967078c9991..25a3ba01d9e 100755
--- a/server/src/com/cloud/network/NetworkManagerImpl.java
+++ b/server/src/com/cloud/network/NetworkManagerImpl.java
@@ -192,14 +192,19 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
private Map _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 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 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 configs = _networksDao.listBy(owner.getId(), offering.getId(), plan.getDataCenterId());
+
if (predefined == null || (predefined.getBroadcastUri() == null && predefined.getBroadcastDomainType() != BroadcastDomainType.Vlan)) {
+ List 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 configs = _networksDao.listBy(owner.getId(), offering.getId(), plan.getDataCenterId());
}
- configs = new ArrayList();
+ List configs = new ArrayList();
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 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 sb = _networksDao.createSearchBuilder();
diff --git a/server/src/com/cloud/network/dao/NetworkDao.java b/server/src/com/cloud/network/dao/NetworkDao.java
index 14a7c35b2e9..abfec4f3491 100644
--- a/server/src/com/cloud/network/dao/NetworkDao.java
+++ b/server/src/com/cloud/network/dao/NetworkDao.java
@@ -44,4 +44,6 @@ public interface NetworkDao extends GenericDao {
String getNextAvailableMacAddress(long networkConfigId);
List listBy(long accountId, long networkId);
+
+ List listBy(long zoneId, String broadcastUri);
}
diff --git a/server/src/com/cloud/network/dao/NetworkDaoImpl.java b/server/src/com/cloud/network/dao/NetworkDaoImpl.java
index 2151ea4a756..9c51e46ebcd 100644
--- a/server/src/com/cloud/network/dao/NetworkDaoImpl.java
+++ b/server/src/com/cloud/network/dao/NetworkDaoImpl.java
@@ -50,6 +50,7 @@ public class NetworkDaoImpl extends GenericDaoBase implements N
final SearchBuilder AccountSearch;
final SearchBuilder RelatedConfigSearch;
final SearchBuilder AccountNetworkSearch;
+ final SearchBuilder ZoneBroadcastUriSearch;
NetworkAccountDaoImpl _accountsDao = new NetworkAccountDaoImpl();
final TableGenerator _tgMacAddress;
@@ -93,6 +94,12 @@ public class NetworkDaoImpl extends GenericDaoBase 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 implements N
sc.setJoinParameters("networkSearch", "accountId", accountId);
return listBy(sc);
}
+
+ public List listBy(long zoneId, String broadcastUri) {
+ SearchCriteria sc = ZoneBroadcastUriSearch.create();
+ sc.setParameters("dataCenterId", zoneId);
+ sc.setParameters("broadcastUri", broadcastUri);
+ return search(sc, null);
+ }
}
diff --git a/server/src/com/cloud/network/guru/DirectNetworkGuru.java b/server/src/com/cloud/network/guru/DirectNetworkGuru.java
new file mode 100644
index 00000000000..1ab35c1e1f3
--- /dev/null
+++ b/server/src/com/cloud/network/guru/DirectNetworkGuru.java
@@ -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;
+ }
+}
diff --git a/server/src/com/cloud/network/guru/GuestNetworkGuru.java b/server/src/com/cloud/network/guru/GuestNetworkGuru.java
index 5a914922ef5..3aeef29c916 100644
--- a/server/src/com/cloud/network/guru/GuestNetworkGuru.java
+++ b/server/src/com/cloud/network/guru/GuestNetworkGuru.java
@@ -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;
}
diff --git a/server/src/com/cloud/network/router/DomainRouterManagerImpl.java b/server/src/com/cloud/network/router/DomainRouterManagerImpl.java
index 5e078d2a840..a6091480de7 100644
--- a/server/src/com/cloud/network/router/DomainRouterManagerImpl.java
+++ b/server/src/com/cloud/network/router/DomainRouterManagerImpl.java
@@ -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 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) {