diff --git a/api/src/com/cloud/dc/Vlan.java b/api/src/com/cloud/dc/Vlan.java index d6076bd0431..ad1769776a2 100644 --- a/api/src/com/cloud/dc/Vlan.java +++ b/api/src/com/cloud/dc/Vlan.java @@ -36,12 +36,8 @@ public interface Vlan { public long getDataCenterId(); - public void setIpRange(String description); - public String getIpRange(); - public void setVlanType(VlanType ipRange); - public VlanType getVlanType(); public Long getNetworkId(); diff --git a/client/tomcatconf/components.xml.in b/client/tomcatconf/components.xml.in index 9dc7e240b13..61052977b66 100755 --- a/client/tomcatconf/components.xml.in +++ b/client/tomcatconf/components.xml.in @@ -99,6 +99,8 @@ - + + + diff --git a/server/src/com/cloud/api/ApiDBUtils.java b/server/src/com/cloud/api/ApiDBUtils.java index 5682e8af0b9..58a0e682938 100755 --- a/server/src/com/cloud/api/ApiDBUtils.java +++ b/server/src/com/cloud/api/ApiDBUtils.java @@ -32,10 +32,10 @@ import com.cloud.network.LoadBalancerVO; import com.cloud.network.Network; import com.cloud.network.Network.Capability; import com.cloud.network.Network.Service; +import com.cloud.network.Networks.TrafficType; import com.cloud.network.NetworkManager; import com.cloud.network.NetworkRuleConfigVO; import com.cloud.network.NetworkVO; -import com.cloud.network.Networks.TrafficType; import com.cloud.network.dao.IPAddressDao; import com.cloud.network.dao.LoadBalancerDao; import com.cloud.network.dao.NetworkDao; @@ -517,25 +517,7 @@ public class ApiDBUtils { } public static long getPublicNetworkIdByZone(long zoneId) { - //find system public network offering - Long networkOfferingId = null; - List offerings = _networkOfferingDao.listSystemNetworkOfferings(); - for (NetworkOfferingVO offering: offerings) { - if (offering.getGuestIpType() == null && offering.getTrafficType() == TrafficType.Public) { - networkOfferingId = offering.getId(); - break; - } - } - - if (networkOfferingId == null) { - throw new InvalidParameterValueException("Unable to find system Public network offering"); - } - - List networks = _networkDao.listBy(Account.ACCOUNT_ID_SYSTEM, networkOfferingId, zoneId); - if (networks == null) { - throw new InvalidParameterValueException("Unable to find public network in zone " + zoneId); - } - return networks.get(0).getId(); + return _networkMgr.getSystemNetworkIdByZoneAndTrafficTypeAndGuestType(zoneId, TrafficType.Public, null); } public static Long getVlanNetworkId(long vlanId) { diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java index 36b4590c349..2599bc0ca45 100755 --- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java @@ -1590,65 +1590,86 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura throw new ServerApiException(BaseCmd.PARAM_ERROR, "Please specify a valid account."); } } + + //Verify that network exists + NetworkVO network = null; + if (networkId != null) { + network = _networkDao.findById(networkId); + if (network == null) { + throw new InvalidParameterValueException("Unable to find network by id " + networkId); + } else { + zoneId = network.getDataCenterId(); + } + } - //if Vlan is direct, don't allow to specify networkId - if (forVirtualNetwork && networkId != null) { - throw new InvalidParameterValueException("Can't specify networkId for Virtual network"); + //Verify that zone exists + DataCenterVO zone = _zoneDao.findById(zoneId); + if (zone == null) { + throw new InvalidParameterValueException("Unable to find zone by id " + zoneId); } - if (forVirtualNetwork && (vlanGateway == null || vlanNetmask == null || zoneId == null)) { - throw new InvalidParameterValueException("Gateway, netmask and zoneId have to be passed in for virtual network"); - } + //If networkId is not specified, and vlan is Virtual or Direct Untagged, try to locate default networks + if (forVirtualNetwork){ + if (network == null) { + //find default public network in the zone + networkId = _networkMgr.getSystemNetworkIdByZoneAndTrafficTypeAndGuestType(zoneId, TrafficType.Public, null); + } else if (network.getGuestType() != null || network.getTrafficType() != TrafficType.Public){ + throw new InvalidParameterValueException("Can't find Public network by id=" + networkId); + } + } else { + if (network == null) { + if (zone.getNetworkType() == DataCenter.NetworkType.Basic) { + networkId = _networkMgr.getSystemNetworkIdByZoneAndTrafficTypeAndGuestType(zoneId, TrafficType.Public, GuestIpType.DirectPodBased); + } else { + throw new InvalidParameterValueException("Nework id is required for Direct vlan creation "); + } + } else if (network.getGuestType() == null || network.getGuestType() == GuestIpType.Virtual) { + throw new InvalidParameterValueException("Can't create direct vlan for network id=" + networkId + " with GuestType: " + network.getGuestType()); + } + } //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); - if (network == null) { - throw new InvalidParameterValueException("Unable to find network by id " + networkId); - } else { - //Check that network is of type Direct - if (network.getGuestType() == GuestIpType.Virtual) { - throw new InvalidParameterValueException("Can't create direct vlan for network with GuestType " + network.getGuestType().toString()); - } - - //check if startIp and endIp belong to network Cidr - String networkCidr = network.getCidr(); - String networkGateway = network.getGateway(); - - Long networkZoneId = network.getDataCenterId(); - String[] splitResult = networkCidr.split("\\/"); - long size = Long.valueOf(splitResult[1]); - String networkNetmask = NetUtils.getCidrNetmask(size); - - //Check if ip addresses are in network range - if (!NetUtils.sameSubnet(startIP, networkGateway, networkNetmask)) { - throw new InvalidParameterValueException("Start ip is not in network cidr: " + networkCidr); + + if (forVirtualNetwork || zone.getNetworkType() == DataCenter.NetworkType.Basic) { + if (vlanGateway == null || vlanNetmask == null || zoneId == null) { + throw new InvalidParameterValueException("Gateway, netmask and zoneId have to be passed in for virtual and direct untagged networks"); + } + } else { + //check if startIp and endIp belong to network Cidr + String networkCidr = network.getCidr(); + String networkGateway = network.getGateway(); + + Long networkZoneId = network.getDataCenterId(); + String[] splitResult = networkCidr.split("\\/"); + long size = Long.valueOf(splitResult[1]); + String networkNetmask = NetUtils.getCidrNetmask(size); + + //Check if ip addresses are in network range + if (!NetUtils.sameSubnet(startIP, networkGateway, networkNetmask)) { + throw new InvalidParameterValueException("Start ip is not in network cidr: " + networkCidr); + } + + if (endIP != null) { + if (!NetUtils.sameSubnet(endIP, networkGateway, networkNetmask)) { + throw new InvalidParameterValueException("End ip is not in network cidr: " + networkCidr); } - - if (endIP != null) { - if (!NetUtils.sameSubnet(endIP, networkGateway, networkNetmask)) { - throw new InvalidParameterValueException("End ip is not in network cidr: " + networkCidr); - } - } - - //set gateway, netmask, zone from network object - vlanGateway = networkGateway; - vlanNetmask = networkNetmask; - zoneId = networkZoneId; - - //set vlanId if it's not null for the network - URI uri = network.getBroadcastUri(); - if (uri != null) { - String[] vlan = uri.toString().split("vlan:\\/\\/"); - vlanId = vlan[1]; - } - } - } + } + + //set gateway, netmask, zone from network object + vlanGateway = networkGateway; + vlanNetmask = networkNetmask; + zoneId = networkZoneId; + + //set vlanId if it's not null for the network + URI uri = network.getBroadcastUri(); + if (uri != null) { + String[] vlan = uri.toString().split("vlan:\\/\\/"); + vlanId = vlan[1]; + } + } return createVlanAndPublicIpRange(userId, zoneId, podId, startIP, endIP, vlanGateway, vlanNetmask, forVirtualNetwork, vlanId, account, networkId); } diff --git a/server/src/com/cloud/dc/VlanVO.java b/server/src/com/cloud/dc/VlanVO.java index 99eeda2de0e..9981e0275f4 100644 --- a/server/src/com/cloud/dc/VlanVO.java +++ b/server/src/com/cloud/dc/VlanVO.java @@ -83,10 +83,6 @@ public class VlanVO implements Vlan { public String getVlanGateway() { return vlanGateway; } - - public void setVlanGateway(String vlanGateway) { - this.vlanGateway = vlanGateway; - } public String getVlanNetmask() { return vlanNetmask; @@ -96,18 +92,10 @@ public class VlanVO implements Vlan { return dataCenterId; } - public void setIpRange(String ipRange) { - this.ipRange = ipRange; - } - public String getIpRange() { return ipRange; } - public void setVlanType(VlanType vlanType) { - this.vlanType = vlanType; - } - public VlanType getVlanType() { return vlanType; } @@ -115,4 +103,8 @@ public class VlanVO implements Vlan { public Long getNetworkId() { return networkId; } + + public void setNetworkId(Long networkId) { + this.networkId = networkId; + } } diff --git a/server/src/com/cloud/dc/dao/VlanDao.java b/server/src/com/cloud/dc/dao/VlanDao.java index a3f39f464ab..a0bf95e7067 100644 --- a/server/src/com/cloud/dc/dao/VlanDao.java +++ b/server/src/com/cloud/dc/dao/VlanDao.java @@ -31,6 +31,8 @@ public interface VlanDao extends GenericDao { List listByZone(long zoneId); + List listByType(Vlan.VlanType vlanType); + List listByZoneAndType(long zoneId, Vlan.VlanType vlanType); List listVlansForPod(long podId); diff --git a/server/src/com/cloud/dc/dao/VlanDaoImpl.java b/server/src/com/cloud/dc/dao/VlanDaoImpl.java index 6c69fa91227..b6fca31c79d 100644 --- a/server/src/com/cloud/dc/dao/VlanDaoImpl.java +++ b/server/src/com/cloud/dc/dao/VlanDaoImpl.java @@ -112,6 +112,14 @@ public class VlanDaoImpl extends GenericDaoBase implements VlanDao sc.setParameters("vlanType", vlanType); return listBy(sc); } + + + @Override + public List listByType(VlanType vlanType) { + SearchCriteria sc = ZoneTypeSearch.create(); + sc.setParameters("vlanType", vlanType); + return listBy(sc); + } @Override public List listVlansForPod(long podId) { diff --git a/server/src/com/cloud/network/NetworkManager.java b/server/src/com/cloud/network/NetworkManager.java index 884288bdca9..38930949279 100644 --- a/server/src/com/cloud/network/NetworkManager.java +++ b/server/src/com/cloud/network/NetworkManager.java @@ -29,8 +29,10 @@ import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.Network.Capability; import com.cloud.network.Network.Service; +import com.cloud.network.Networks.TrafficType; import com.cloud.network.addr.PublicIp; import com.cloud.network.rules.FirewallRule; +import com.cloud.offering.NetworkOffering.GuestIpType; import com.cloud.offerings.NetworkOfferingVO; import com.cloud.service.ServiceOfferingVO; import com.cloud.user.Account; @@ -128,4 +130,7 @@ public interface NetworkManager extends NetworkService { boolean applyRules(List rules, boolean continueOnError) throws ResourceUnavailableException; Map> getZoneCapabilities(long zoneId); + + long getSystemNetworkIdByZoneAndTrafficTypeAndGuestType(long zoneId, TrafficType trafficType, GuestIpType guestType); + } diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index ea4a0c82781..18835e29c1a 100755 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -2205,4 +2205,27 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag return networkCapabilities; } + @Override + public long getSystemNetworkIdByZoneAndTrafficTypeAndGuestType(long zoneId, TrafficType trafficType, GuestIpType guestType) { + //find system public network offering + Long networkOfferingId = null; + List offerings = _networkOfferingDao.listSystemNetworkOfferings(); + for (NetworkOfferingVO offering: offerings) { + if (offering.getTrafficType() == trafficType && offering.getGuestIpType() == guestType) { + networkOfferingId = offering.getId(); + break; + } + } + + if (networkOfferingId == null) { + throw new InvalidParameterValueException("Unable to find system network offering with traffic type " + trafficType + " and guestIpType " + guestType); + } + + List networks = _networksDao.listBy(Account.ACCOUNT_ID_SYSTEM, networkOfferingId, zoneId); + if (networks == null) { + throw new InvalidParameterValueException("Unable to find network with traffic type " + trafficType + " in zone " + zoneId); + } + return networks.get(0).getId(); + } + } diff --git a/server/src/com/cloud/server/ConfigurationServerImpl.java b/server/src/com/cloud/server/ConfigurationServerImpl.java index 9ebdceebc1b..c9bff361a5f 100644 --- a/server/src/com/cloud/server/ConfigurationServerImpl.java +++ b/server/src/com/cloud/server/ConfigurationServerImpl.java @@ -47,8 +47,11 @@ import com.cloud.configuration.dao.ConfigurationDao; import com.cloud.dc.DataCenter.NetworkType; import com.cloud.dc.DataCenterVO; import com.cloud.dc.HostPodVO; +import com.cloud.dc.Vlan.VlanType; +import com.cloud.dc.VlanVO; import com.cloud.dc.dao.DataCenterDao; import com.cloud.dc.dao.HostPodDao; +import com.cloud.dc.dao.VlanDao; import com.cloud.domain.DomainVO; import com.cloud.domain.dao.DomainDao; import com.cloud.exception.InternalErrorException; @@ -71,6 +74,7 @@ import com.cloud.storage.DiskOfferingVO; import com.cloud.storage.SnapshotPolicyVO; import com.cloud.storage.dao.DiskOfferingDao; import com.cloud.storage.dao.SnapshotPolicyDao; +import com.cloud.user.Account; import com.cloud.user.User; import com.cloud.utils.PasswordGenerator; import com.cloud.utils.PropertiesUtil; @@ -93,6 +97,7 @@ public class ConfigurationServerImpl implements ConfigurationServer { private final NetworkOfferingDao _networkOfferingDao; private final DataCenterDao _dataCenterDao; private final NetworkDao _networkDao; + private final VlanDao _vlanDao; public ConfigurationServerImpl() { @@ -107,6 +112,7 @@ public class ConfigurationServerImpl implements ConfigurationServer { _domainDao = locator.getDao(DomainDao.class); _dataCenterDao = locator.getDao(DataCenterDao.class); _networkDao = locator.getDao(NetworkDao.class); + _vlanDao = locator.getDao(VlanDao.class); } @Override @@ -206,45 +212,6 @@ public class ConfigurationServerImpl implements ConfigurationServer { s_logger.debug("ConfigurationServer saved \"" + hostIpAdr + "\" as host."); } -// // Get the gateway and netmask of this machine -// String[] gatewayAndNetmask = getGatewayAndNetmask(); -// -// if (gatewayAndNetmask != null) { -// String gateway = gatewayAndNetmask[0]; -// String netmask = gatewayAndNetmask[1]; -// long cidrSize = NetUtils.getCidrSize(netmask); -// -// // Create a default zone -// String dns = getDNS(); -// if (dns == null) { -// dns = "4.2.2.2"; -// } -// DataCenterVO zone = createZone(User.UID_SYSTEM, "Default", dns, null, dns, null, null,"10.1.1.0/24", null, null, NetworkType.Basic); -// -// //Create untagged network -// DataCenterDeployment plan = new DataCenterDeployment(zone.getId(), null, null, null); -// NetworkVO userNetwork = new NetworkVO(); -// userNetwork.setBroadcastDomainType(BroadcastDomainType.Native); -// -// Account systemAccount = _accountDao.findById(Account.ACCOUNT_ID_SYSTEM); -// List networkOffering = _networkOfferingDao.findByType(GuestIpType.DirectPodBased); -// if (networkOffering == null || networkOffering.isEmpty()) { -// throw new CloudRuntimeException("No default DirectPodBased network offering is found"); -// } -// _networkMgr.setupNetworkConfiguration(systemAccount, networkOffering.get(0), userNetwork, plan, null, null, true); -// -// // Create a default pod -// String networkType = _configDao.getValue("network.type"); -// if (networkType != null && networkType.equals("vnet")) { -// createPod(User.UID_SYSTEM, "Default", zone.getId(), "169.254.1.1", "169.254.1.0/24", "169.254.1.2", "169.254.1.254"); -// } else { -// createPod(User.UID_SYSTEM, "Default", zone.getId(), gateway, gateway + "/" + cidrSize, null, null); -// } -// s_logger.debug("ConfigurationServer saved a default pod and zone, with gateway: " + gateway + " and netmask: " + netmask); -// } else { -// s_logger.debug("ConfigurationServer could not detect the gateway and netmask of the management server."); -// } - // generate a single sign-on key updateSSOKey(); @@ -254,6 +221,15 @@ public class ConfigurationServerImpl implements ConfigurationServer { //Create default networks createDefaultNetworks(); + //Update existing vlans with networkId + List vlans = _vlanDao.listAll(); + if (vlans != null && !vlans.isEmpty()) { + for (VlanVO vlan : vlans) { + if (vlan.getNetworkId().longValue() == 0) { + updateVlanWithNetworkId(vlan); + } + } + } } // store the public and private keys in the database @@ -591,7 +567,6 @@ public class ConfigurationServerImpl implements ConfigurationServer { } } - //checking the following params outside checkzoneparams method as we do not use these params for updatezone //hence the method below is generic to check for common params if ((guestCidr != null) && !NetUtils.isValidCIDR(guestCidr)) { @@ -799,4 +774,40 @@ public class ConfigurationServerImpl implements ConfigurationServer { } } + + private void updateVlanWithNetworkId(VlanVO vlan) { + long zoneId = vlan.getDataCenterId(); + long networkId = 0L; + if (vlan.getVlanType() == VlanType.VirtualNetwork) { + networkId = getSystemNetworkIdByZoneAndTrafficTypeAndGuestType(zoneId, TrafficType.Public, null); + } else if (vlan.getVlanType() == VlanType.DirectAttached) { + networkId = getSystemNetworkIdByZoneAndTrafficTypeAndGuestType(zoneId, TrafficType.Public, GuestIpType.DirectPodBased); + } + + vlan.setNetworkId(networkId); + _vlanDao.update(vlan.getId(), vlan); + } + + private long getSystemNetworkIdByZoneAndTrafficTypeAndGuestType(long zoneId, TrafficType trafficType, GuestIpType guestType) { + //find system public network offering + Long networkOfferingId = null; + List offerings = _networkOfferingDao.listSystemNetworkOfferings(); + for (NetworkOfferingVO offering: offerings) { + if (offering.getTrafficType() == trafficType && offering.getGuestIpType() == guestType) { + networkOfferingId = offering.getId(); + break; + } + } + + if (networkOfferingId == null) { + throw new InvalidParameterValueException("Unable to find system network offering with traffic type " + trafficType + " and guestIpType " + guestType); + } + + List networks = _networkDao.listBy(Account.ACCOUNT_ID_SYSTEM, networkOfferingId, zoneId); + if (networks == null) { + throw new InvalidParameterValueException("Unable to find network with traffic type " + trafficType + " in zone " + zoneId); + } + return networks.get(0).getId(); + } + } diff --git a/server/src/com/cloud/test/DatabaseConfig.java b/server/src/com/cloud/test/DatabaseConfig.java index 7b16b3ba612..fe2d292d826 100644 --- a/server/src/com/cloud/test/DatabaseConfig.java +++ b/server/src/com/cloud/test/DatabaseConfig.java @@ -663,7 +663,8 @@ public class DatabaseConfig { long zoneDbId = Long.parseLong(zoneId); String zoneName = PodZoneConfig.getZoneName(zoneDbId); - pzc.modifyVlan(zoneName, true, vlanId, gateway, netmask, vlanPodName, vlanType, publicIpRange); + //Set networkId to be 0, the value will be updated after management server starts up + pzc.modifyVlan(zoneName, true, vlanId, gateway, netmask, vlanPodName, vlanType, publicIpRange, 0); long vlanDbId = pzc.getVlanDbId(zoneName, vlanId); iprc.saveIPRange("public", -1, zoneDbId, vlanDbId, startIP, endIP); diff --git a/server/src/com/cloud/test/PodZoneConfig.java b/server/src/com/cloud/test/PodZoneConfig.java index ea9a4589f63..cad5f8567f7 100644 --- a/server/src/com/cloud/test/PodZoneConfig.java +++ b/server/src/com/cloud/test/PodZoneConfig.java @@ -183,7 +183,7 @@ public class PodZoneConfig { "Unable to start DB connection to read vlan DB id. Please contact Cloud Support."); } - public List modifyVlan(String zone, boolean add, String vlanId, String vlanGateway, String vlanNetmask, String pod, String vlanType, String ipRange) { + public List modifyVlan(String zone, boolean add, String vlanId, String vlanGateway, String vlanNetmask, String pod, String vlanType, String ipRange, long networkId) { // Check if the zone is valid long zoneId = getZoneId(zone); if (zoneId == -1) @@ -219,7 +219,7 @@ public class PodZoneConfig { */ // Everything was fine, so persist the VLAN - saveVlan(zoneId, podId, vlanId, vlanGateway, vlanNetmask, vlanType, ipRange); + saveVlan(zoneId, podId, vlanId, vlanGateway, vlanNetmask, vlanType, ipRange, networkId); if (podId != null) { long vlanDbId = getVlanDbId(zone, vlanId); String sql = "INSERT INTO `cloud`.`pod_vlan_map` (pod_id, vlan_db_id) " + "VALUES ('" + podId + "','" + vlanDbId + "')"; @@ -342,8 +342,8 @@ public class PodZoneConfig { DatabaseConfig.saveSQL(sql, "Failed to delete zone due to exception. Please contact Cloud Support."); } - public void saveVlan(long zoneId, Long podId, String vlanId, String vlanGateway, String vlanNetmask, String vlanType, String ipRange) { - String sql = "INSERT INTO `cloud`.`vlan` (vlan_id, vlan_gateway, vlan_netmask, data_center_id, vlan_type, description) " + "VALUES ('" + vlanId + "','" + vlanGateway + "','" + vlanNetmask + "','" + zoneId + "','" + vlanType + "','" + ipRange + "')"; + public void saveVlan(long zoneId, Long podId, String vlanId, String vlanGateway, String vlanNetmask, String vlanType, String ipRange, long networkId) { + String sql = "INSERT INTO `cloud`.`vlan` (vlan_id, vlan_gateway, vlan_netmask, data_center_id, vlan_type, description, network_id) " + "VALUES ('" + vlanId + "','" + vlanGateway + "','" + vlanNetmask + "','" + zoneId + "','" + vlanType + "','" + ipRange + "','" + networkId + "')"; DatabaseConfig.saveSQL(sql, "Failed to save vlan due to exception. Please contact Cloud Support."); } diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql index 44674656f2d..02dea7eefc2 100755 --- a/setup/db/create-schema.sql +++ b/setup/db/create-schema.sql @@ -372,7 +372,7 @@ CREATE TABLE `cloud`.`vlan` ( `description` varchar(255), `vlan_type` varchar(255), `data_center_id` bigint unsigned NOT NULL, - `network_id` bigint unsigned COMMENT 'id of corresponding network offering', + `network_id` bigint unsigned NOT NULL COMMENT 'id of corresponding network offering', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;