From 432ea9c7d4aff3f7e682f2951f49ed3e95778d9f Mon Sep 17 00:00:00 2001 From: Murali Reddy Date: Tue, 11 Dec 2012 23:06:13 +0530 Subject: [PATCH] CLOUDSTACK-265: provide option to turn-off automatic public IP association for each VM when using EIP service. - introduces Capability in the network offering, which decides when EIP service is enabled, by defualt public IP should be assigned to the VM or not - default network offering with EIP/ELB service will still work with old EIP semantics, i.e) assign a public IP to each VM on start --- api/src/com/cloud/network/Network.java | 11 +- .../com/cloud/offering/NetworkOffering.java | 2 + .../ConfigurationManagerImpl.java | 142 ++++++------------ .../cloud/network/rules/RulesManagerImpl.java | 40 ++--- .../cloud/offerings/NetworkOfferingVO.java | 28 ++-- .../cloud/server/ConfigurationServerImpl.java | 49 ++---- .../com/cloud/upgrade/dao/Upgrade40to41.java | 38 +++++ .../src/com/cloud/vm/UserVmManagerImpl.java | 140 +++-------------- setup/db/create-schema.sql | 1 + setup/db/db/schema-40to41.sql | 23 +++ 10 files changed, 186 insertions(+), 288 deletions(-) create mode 100644 setup/db/db/schema-40to41.sql diff --git a/api/src/com/cloud/network/Network.java b/api/src/com/cloud/network/Network.java index d38f7401682..188ef92e57b 100644 --- a/api/src/com/cloud/network/Network.java +++ b/api/src/com/cloud/network/Network.java @@ -16,11 +16,6 @@ // under the License. package com.cloud.network; -import java.net.URI; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; - import com.cloud.acl.ControlledEntity; import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.network.Networks.Mode; @@ -28,6 +23,11 @@ import com.cloud.network.Networks.TrafficType; import com.cloud.utils.fsm.FiniteState; import com.cloud.utils.fsm.StateMachine; +import java.net.URI; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + /** * owned by an account. */ @@ -168,6 +168,7 @@ public interface Network extends ControlledEntity { public static final Capability AllowDnsSuffixModification = new Capability("AllowDnsSuffixModification"); public static final Capability RedundantRouter = new Capability("RedundantRouter"); public static final Capability ElasticIp = new Capability("ElasticIp"); + public static final Capability AssociatePublicIP = new Capability("AssociatePublicIP"); public static final Capability ElasticLb = new Capability("ElasticLb"); public static final Capability AutoScaleCounters = new Capability("AutoScaleCounters"); diff --git a/api/src/com/cloud/offering/NetworkOffering.java b/api/src/com/cloud/offering/NetworkOffering.java index a514ccf17f4..29828ab6172 100644 --- a/api/src/com/cloud/offering/NetworkOffering.java +++ b/api/src/com/cloud/offering/NetworkOffering.java @@ -105,6 +105,8 @@ public interface NetworkOffering { boolean getElasticIp(); + boolean getAssociatePublicIP(); + boolean getElasticLb(); boolean getSpecifyIpRanges(); diff --git a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java index ef940e89f61..33baaf12ca4 100755 --- a/server/src/com/cloud/configuration/ConfigurationManagerImpl.java +++ b/server/src/com/cloud/configuration/ConfigurationManagerImpl.java @@ -16,110 +16,35 @@ // under the License. package com.cloud.configuration; -import java.net.URI; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Hashtable; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.UUID; - -import javax.ejb.Local; -import javax.naming.ConfigurationException; -import javax.naming.Context; -import javax.naming.NamingException; -import javax.naming.directory.DirContext; -import javax.naming.directory.InitialDirContext; - -import org.apache.log4j.Logger; - import com.cloud.acl.SecurityChecker; import com.cloud.alert.AlertManager; import com.cloud.api.ApiConstants.LDAPParams; import com.cloud.api.ApiDBUtils; -import com.cloud.api.commands.CreateDiskOfferingCmd; -import com.cloud.api.commands.CreateNetworkOfferingCmd; -import com.cloud.api.commands.CreateServiceOfferingCmd; -import com.cloud.api.commands.CreateVlanIpRangeCmd; -import com.cloud.api.commands.CreateZoneCmd; -import com.cloud.api.commands.DeleteDiskOfferingCmd; -import com.cloud.api.commands.DeleteNetworkOfferingCmd; -import com.cloud.api.commands.DeletePodCmd; -import com.cloud.api.commands.DeleteServiceOfferingCmd; -import com.cloud.api.commands.DeleteVlanIpRangeCmd; -import com.cloud.api.commands.DeleteZoneCmd; -import com.cloud.api.commands.LDAPConfigCmd; -import com.cloud.api.commands.LDAPRemoveCmd; -import com.cloud.api.commands.ListNetworkOfferingsCmd; -import com.cloud.api.commands.UpdateCfgCmd; -import com.cloud.api.commands.UpdateDiskOfferingCmd; -import com.cloud.api.commands.UpdateNetworkOfferingCmd; -import com.cloud.api.commands.UpdatePodCmd; -import com.cloud.api.commands.UpdateServiceOfferingCmd; -import com.cloud.api.commands.UpdateZoneCmd; +import com.cloud.api.commands.*; import com.cloud.capacity.dao.CapacityDao; import com.cloud.configuration.Resource.ResourceType; import com.cloud.configuration.dao.ConfigurationDao; -import com.cloud.dc.AccountVlanMapVO; -import com.cloud.dc.ClusterVO; -import com.cloud.dc.DataCenter; +import com.cloud.dc.*; import com.cloud.dc.DataCenter.NetworkType; -import com.cloud.dc.DataCenterIpAddressVO; -import com.cloud.dc.DataCenterLinkLocalIpAddressVO; -import com.cloud.dc.DataCenterVO; -import com.cloud.dc.HostPodVO; -import com.cloud.dc.Pod; -import com.cloud.dc.PodVlanMapVO; -import com.cloud.dc.Vlan; import com.cloud.dc.Vlan.VlanType; -import com.cloud.dc.VlanVO; -import com.cloud.dc.dao.AccountVlanMapDao; -import com.cloud.dc.dao.ClusterDao; -import com.cloud.dc.dao.DataCenterDao; -import com.cloud.dc.dao.DataCenterIpAddressDao; -import com.cloud.dc.dao.DataCenterLinkLocalIpAddressDaoImpl; -import com.cloud.dc.dao.HostPodDao; -import com.cloud.dc.dao.PodVlanMapDao; -import com.cloud.dc.dao.VlanDao; +import com.cloud.dc.dao.*; import com.cloud.deploy.DataCenterDeployment; import com.cloud.domain.Domain; import com.cloud.domain.DomainVO; import com.cloud.domain.dao.DomainDao; import com.cloud.event.ActionEvent; import com.cloud.event.EventTypes; -import com.cloud.exception.ConcurrentOperationException; -import com.cloud.exception.InsufficientCapacityException; -import com.cloud.exception.InvalidParameterValueException; -import com.cloud.exception.PermissionDeniedException; -import com.cloud.exception.ResourceAllocationException; -import com.cloud.exception.ResourceUnavailableException; +import com.cloud.exception.*; import com.cloud.host.HostVO; import com.cloud.hypervisor.Hypervisor.HypervisorType; -import com.cloud.network.IPAddressVO; -import com.cloud.network.Network; +import com.cloud.network.*; import com.cloud.network.Network.Capability; import com.cloud.network.Network.GuestType; import com.cloud.network.Network.Provider; import com.cloud.network.Network.Service; -import com.cloud.network.NetworkManager; -import com.cloud.network.NetworkVO; import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.network.Networks.TrafficType; -import com.cloud.network.PhysicalNetwork; -import com.cloud.network.PhysicalNetworkVO; -import com.cloud.network.dao.FirewallRulesDao; -import com.cloud.network.dao.IPAddressDao; -import com.cloud.network.dao.NetworkDao; -import com.cloud.network.dao.PhysicalNetworkDao; -import com.cloud.network.dao.PhysicalNetworkTrafficTypeDao; -import com.cloud.network.dao.PhysicalNetworkTrafficTypeVO; +import com.cloud.network.dao.*; import com.cloud.network.vpc.VpcManager; import com.cloud.offering.DiskOffering; import com.cloud.offering.NetworkOffering; @@ -142,12 +67,7 @@ import com.cloud.storage.dao.SwiftDao; import com.cloud.storage.secondary.SecondaryStorageVmManager; import com.cloud.storage.swift.SwiftManager; import com.cloud.test.IPRangeConfig; -import com.cloud.user.Account; -import com.cloud.user.AccountManager; -import com.cloud.user.AccountVO; -import com.cloud.user.ResourceLimitService; -import com.cloud.user.User; -import com.cloud.user.UserContext; +import com.cloud.user.*; import com.cloud.user.dao.AccountDao; import com.cloud.utils.NumbersUtil; import com.cloud.utils.StringUtils; @@ -163,8 +83,20 @@ import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.NetUtils; import com.cloud.vm.VirtualMachine; import com.cloud.vm.dao.NicDao; - import edu.emory.mathcs.backport.java.util.Arrays; +import org.apache.log4j.Logger; + +import javax.ejb.Local; +import javax.naming.ConfigurationException; +import javax.naming.Context; +import javax.naming.NamingException; +import javax.naming.directory.DirContext; +import javax.naming.directory.InitialDirContext; +import java.net.URI; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.*; @Local(value = { ConfigurationManager.class, ConfigurationService.class }) public class ConfigurationManagerImpl implements ConfigurationManager, ConfigurationService { @@ -3138,20 +3070,33 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura void validateStaticNatServiceCapablities(Map staticNatServiceCapabilityMap) { if (staticNatServiceCapabilityMap != null && !staticNatServiceCapabilityMap.isEmpty()) { - if (staticNatServiceCapabilityMap.keySet().size() > 1) { - throw new InvalidParameterValueException("Only " + Capability.ElasticIp.getName() + " capabilitiy can be sepcified for static nat service"); + if (staticNatServiceCapabilityMap.keySet().size() > 2) { + throw new InvalidParameterValueException("Only " + Capability.ElasticIp.getName() + " and " + Capability.AssociatePublicIP.getName() + " capabilitiy can be sepcified for static nat service"); } - + boolean eipEnabled = false; + boolean eipDisabled = false; + boolean associatePublicIP = true; for (Capability capability : staticNatServiceCapabilityMap.keySet()) { String value = staticNatServiceCapabilityMap.get(capability); if (capability == Capability.ElasticIp) { - boolean enabled = value.contains("true"); - boolean disabled = value.contains("false"); - if (!enabled && !disabled) { + eipEnabled = value.contains("true"); + eipDisabled = value.contains("false"); + if (!eipEnabled && !eipDisabled) { throw new InvalidParameterValueException("Unknown specified value for " + Capability.ElasticIp.getName()); } + } else if (capability == Capability.AssociatePublicIP) { + if (value.contains("true")) { + associatePublicIP = true; + } else if (value.contains("false")) { + associatePublicIP = false; + } else { + throw new InvalidParameterValueException("Unknown specified value for " + Capability.AssociatePublicIP.getName()); + } } else { - throw new InvalidParameterValueException("Only " + Capability.ElasticIp.getName() + " capabilitiy can be sepcified for static nat service"); + throw new InvalidParameterValueException("Only " + Capability.ElasticIp.getName() + " and " + Capability.AssociatePublicIP.getName() + " capabilitiy can be sepcified for static nat service"); + } + if (eipDisabled && associatePublicIP) { + throw new InvalidParameterValueException("Capability " + Capability.AssociatePublicIP.getName() + " can only be set when capability " + Capability.ElasticIp.getName() + " is true"); } } } @@ -3205,6 +3150,7 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura boolean sharedSourceNat = false; boolean redundantRouter = false; boolean elasticIp = false; + boolean associatePublicIp = false; if (serviceCapabilityMap != null && !serviceCapabilityMap.isEmpty()) { Map lbServiceCapabilityMap = serviceCapabilityMap.get(Service.Lb); @@ -3245,13 +3191,17 @@ public class ConfigurationManagerImpl implements ConfigurationManager, Configura String param = staticNatServiceCapabilityMap.get(Capability.ElasticIp); if (param != null) { elasticIp = param.contains("true"); + String associatePublicIP = staticNatServiceCapabilityMap.get(Capability.AssociatePublicIP); + if (associatePublicIP != null) { + associatePublicIp = associatePublicIP.contains("true"); + } } } } NetworkOfferingVO offering = new NetworkOfferingVO(name, displayText, trafficType, systemOnly, specifyVlan, networkRate, multicastRate, isDefault, availability, tags, type, conserveMode, dedicatedLb, - sharedSourceNat, redundantRouter, elasticIp, elasticLb, specifyIpRanges); + sharedSourceNat, redundantRouter, elasticIp, elasticLb, associatePublicIp, specifyIpRanges); if (serviceOfferingId != null) { offering.setServiceOfferingId(serviceOfferingId); diff --git a/server/src/com/cloud/network/rules/RulesManagerImpl.java b/server/src/com/cloud/network/rules/RulesManagerImpl.java index a4e0722c0b2..02d186d9b3b 100755 --- a/server/src/com/cloud/network/rules/RulesManagerImpl.java +++ b/server/src/com/cloud/network/rules/RulesManagerImpl.java @@ -16,17 +16,6 @@ // under the License. package com.cloud.network.rules; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import javax.ejb.Local; -import javax.naming.ConfigurationException; - -import org.apache.log4j.Logger; - import com.cloud.api.commands.ListPortForwardingRulesCmd; import com.cloud.configuration.ConfigurationManager; import com.cloud.domain.dao.DomainDao; @@ -61,18 +50,12 @@ import com.cloud.user.AccountManager; import com.cloud.user.DomainManager; import com.cloud.user.UserContext; import com.cloud.uservm.UserVm; -import com.cloud.utils.IdentityProxy; import com.cloud.utils.Pair; import com.cloud.utils.Ternary; import com.cloud.utils.component.Inject; import com.cloud.utils.component.Manager; -import com.cloud.utils.db.DB; -import com.cloud.utils.db.Filter; -import com.cloud.utils.db.JoinBuilder; -import com.cloud.utils.db.SearchBuilder; -import com.cloud.utils.db.SearchCriteria; +import com.cloud.utils.db.*; import com.cloud.utils.db.SearchCriteria.Op; -import com.cloud.utils.db.Transaction; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.Ip; import com.cloud.vm.Nic; @@ -81,6 +64,11 @@ import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachine.Type; import com.cloud.vm.dao.NicDao; import com.cloud.vm.dao.UserVmDao; +import org.apache.log4j.Logger; + +import javax.ejb.Local; +import javax.naming.ConfigurationException; +import java.util.*; @Local(value = { RulesManager.class, RulesService.class }) public class RulesManagerImpl implements RulesManager, RulesService, Manager { @@ -1185,11 +1173,12 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { Network guestNetwork = _networkMgr.getNetwork(ipAddress.getAssociatedWithNetworkId()); NetworkOffering offering = _configMgr.getNetworkOffering(guestNetwork.getNetworkOfferingId()); if (offering.getElasticIp()) { - getSystemIpAndEnableStaticNatForVm(_vmDao.findById(vmId), true); - return true; - } else { - return disableStaticNat(ipId, caller, ctx.getCallerUserId(), false); + if (offering.getAssociatePublicIP()) { + getSystemIpAndEnableStaticNatForVm(_vmDao.findById(vmId), true); + return true; + } } + return disableStaticNat(ipId, caller, ctx.getCallerUserId(), false); } @Override @@ -1375,7 +1364,11 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { Network guestNetwork = _networkMgr.getNetwork(nic.getNetworkId()); NetworkOffering offering = _configMgr.getNetworkOffering(guestNetwork.getNetworkOfferingId()); if (offering.getElasticIp()) { - + boolean isSystemVM = (vm.getType() == Type.ConsoleProxy || vm.getType() == Type.SecondaryStorageVm); + // for user VM's associate public IP only if offering is marked to associate a public IP by default on start of VM + if (!isSystemVM && !offering.getAssociatePublicIP()) { + continue; + } // check if there is already static nat enabled if (_ipAddressDao.findByAssociatedVmId(vm.getId()) != null && !getNewIp) { s_logger.debug("Vm " + vm + " already has ip associated with it in guest network " + guestNetwork); @@ -1390,7 +1383,6 @@ public class RulesManagerImpl implements RulesManager, RulesService, Manager { s_logger.debug("Allocated system ip " + ip + ", now enabling static nat on it for vm " + vm); - boolean isSystemVM = (vm.getType() == Type.ConsoleProxy || vm.getType() == Type.SecondaryStorageVm); try { success = enableStaticNat(ip.getId(), vm.getId(), guestNetwork.getId(), isSystemVM); } catch (NetworkRuleConflictException ex) { diff --git a/server/src/com/cloud/offerings/NetworkOfferingVO.java b/server/src/com/cloud/offerings/NetworkOfferingVO.java index 77407560c7e..2570b70f630 100755 --- a/server/src/com/cloud/offerings/NetworkOfferingVO.java +++ b/server/src/com/cloud/offerings/NetworkOfferingVO.java @@ -16,24 +16,16 @@ // under the License. package com.cloud.offerings; -import java.util.Date; -import java.util.UUID; - -import javax.persistence.Column; -import javax.persistence.Entity; -import javax.persistence.EnumType; -import javax.persistence.Enumerated; -import javax.persistence.GeneratedValue; -import javax.persistence.GenerationType; -import javax.persistence.Id; -import javax.persistence.Table; - import com.cloud.api.Identity; import com.cloud.network.Network; import com.cloud.network.Networks.TrafficType; import com.cloud.offering.NetworkOffering; import com.cloud.utils.db.GenericDao; +import javax.persistence.*; +import java.util.Date; +import java.util.UUID; + @Entity @Table(name = "network_offerings") public class NetworkOfferingVO implements NetworkOffering, Identity { @@ -122,6 +114,9 @@ public class NetworkOfferingVO implements NetworkOffering, Identity { @Column(name = "elastic_lb_service") boolean elasticLb; + @Column(name = "eip_associate_public_ip") + boolean eipAssociatePublicIp; + @Override public String getDisplayText() { return displayText; @@ -282,18 +277,20 @@ public class NetworkOfferingVO implements NetworkOffering, Identity { this.redundantRouter = false; this.elasticIp = false; this.elasticLb = false; + this.eipAssociatePublicIp = true; this.specifyIpRanges = specifyIpRanges; } public NetworkOfferingVO(String name, String displayText, TrafficType trafficType, boolean systemOnly, boolean specifyVlan, Integer rateMbps, Integer multicastRateMbps, boolean isDefault, Availability availability, String tags, Network.GuestType guestType, boolean conserveMode, boolean dedicatedLb, boolean sharedSourceNat, boolean redundantRouter, boolean elasticIp, boolean elasticLb, - boolean specifyIpRanges) { + boolean associatePublicIP, boolean specifyIpRanges) { this(name, displayText, trafficType, systemOnly, specifyVlan, rateMbps, multicastRateMbps, isDefault, availability, tags, guestType, conserveMode, specifyIpRanges); this.dedicatedLB = dedicatedLb; this.sharedSourceNat = sharedSourceNat; this.redundantRouter = redundantRouter; this.elasticIp = elasticIp; this.elasticLb = elasticLb; + this.eipAssociatePublicIp = associatePublicIP; } public NetworkOfferingVO() { @@ -355,6 +352,11 @@ public class NetworkOfferingVO implements NetworkOffering, Identity { return elasticIp; } + @Override + public boolean getAssociatePublicIP() { + return eipAssociatePublicIp; + } + @Override public boolean getElasticLb() { return elasticLb; diff --git a/server/src/com/cloud/server/ConfigurationServerImpl.java b/server/src/com/cloud/server/ConfigurationServerImpl.java index d2f0bb01a3e..c0c29ed8eb8 100755 --- a/server/src/com/cloud/server/ConfigurationServerImpl.java +++ b/server/src/com/cloud/server/ConfigurationServerImpl.java @@ -16,33 +16,6 @@ // under the License. package com.cloud.server; -import java.io.DataInputStream; -import java.io.EOFException; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.security.NoSuchAlgorithmException; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.UUID; -import java.util.regex.Pattern; - -import javax.crypto.KeyGenerator; -import javax.crypto.SecretKey; - -import org.apache.commons.codec.binary.Base64; -import org.apache.log4j.Logger; - import com.cloud.configuration.Config; import com.cloud.configuration.ConfigurationVO; import com.cloud.configuration.Resource; @@ -72,11 +45,7 @@ import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.network.Networks.Mode; import com.cloud.network.Networks.TrafficType; import com.cloud.network.dao.NetworkDao; -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.network.guru.*; import com.cloud.offering.NetworkOffering; import com.cloud.offering.NetworkOffering.Availability; import com.cloud.offerings.NetworkOfferingServiceMapVO; @@ -102,6 +71,20 @@ import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.net.NetUtils; import com.cloud.utils.script.Script; import com.cloud.uuididentity.dao.IdentityDao; +import org.apache.commons.codec.binary.Base64; +import org.apache.log4j.Logger; + +import javax.crypto.KeyGenerator; +import javax.crypto.SecretKey; +import java.io.*; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.security.NoSuchAlgorithmException; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.*; +import java.util.regex.Pattern; public class ConfigurationServerImpl implements ConfigurationServer { public static final Logger s_logger = Logger.getLogger(ConfigurationServerImpl.class.getName()); @@ -988,7 +971,7 @@ public class ConfigurationServerImpl implements ConfigurationServer { "Offering for Shared networks with Elastic IP and Elastic LB capabilities", TrafficType.Guest, false, true, null, null, true, Availability.Optional, - null, Network.GuestType.Shared, true, false, false, false, true, true, true); + null, Network.GuestType.Shared, true, false, false, false, true, true, true, true); defaultNetscalerNetworkOffering.setState(NetworkOffering.State.Enabled); defaultNetscalerNetworkOffering = _networkOfferingDao.persistDefaultNetworkOffering(defaultNetscalerNetworkOffering); diff --git a/server/src/com/cloud/upgrade/dao/Upgrade40to41.java b/server/src/com/cloud/upgrade/dao/Upgrade40to41.java index 5067f39d011..393aefd744c 100644 --- a/server/src/com/cloud/upgrade/dao/Upgrade40to41.java +++ b/server/src/com/cloud/upgrade/dao/Upgrade40to41.java @@ -17,8 +17,13 @@ package com.cloud.upgrade.dao; +import com.cloud.utils.exception.CloudRuntimeException; + import java.io.File; import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; /** * @author htrippaers @@ -70,6 +75,7 @@ public class Upgrade40to41 extends Upgrade30xBase implements DbUpgrade { */ @Override public void performDataMigration(Connection conn) { + upgradeEIPNetworkOfferings(conn); } /* (non-Javadoc) @@ -80,4 +86,36 @@ public class Upgrade40to41 extends Upgrade30xBase implements DbUpgrade { return new File[0]; } + private void upgradeEIPNetworkOfferings(Connection conn) { + PreparedStatement pstmt = null; + ResultSet rs = null; + + try { + pstmt = conn.prepareStatement("select id, elastic_ip_service from `cloud`.`network_offerings` where traffic_type='Guest'"); + rs = pstmt.executeQuery(); + while (rs.next()) { + long id = rs.getLong(1); + // check if elastic IP service is enabled for network offering + if (rs.getLong(2) != 0) { + //update network offering with eip_associate_public_ip set to true + pstmt = conn.prepareStatement("UPDATE `cloud`.`network_offerings` set eip_associate_public_ip=? where id=?"); + pstmt.setBoolean(1, true); + pstmt.setLong(2, id); + pstmt.executeUpdate(); + } + } + } catch (SQLException e) { + throw new CloudRuntimeException("Unable to set elastic_ip_service for network offerings with EIP service enabled.", e); + } finally { + try { + if (rs != null) { + rs.close(); + } + if (pstmt != null) { + pstmt.close(); + } + } catch (SQLException e) { + } + } + } } diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index eeb1c78a44f..02d630f31fd 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -16,41 +16,10 @@ // under the License. package com.cloud.vm; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; - -import javax.ejb.Local; -import javax.naming.ConfigurationException; - -import org.apache.commons.codec.binary.Base64; -import org.apache.log4j.Logger; - import com.cloud.acl.ControlledEntity.ACLType; import com.cloud.acl.SecurityChecker.AccessType; import com.cloud.agent.AgentManager; -import com.cloud.agent.api.Answer; -import com.cloud.agent.api.AttachIsoCommand; -import com.cloud.agent.api.AttachVolumeAnswer; -import com.cloud.agent.api.AttachVolumeCommand; -import com.cloud.agent.api.ComputeChecksumCommand; -import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand; -import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand; -import com.cloud.agent.api.GetVmStatsAnswer; -import com.cloud.agent.api.GetVmStatsCommand; -import com.cloud.agent.api.SnapshotCommand; -import com.cloud.agent.api.StartAnswer; -import com.cloud.agent.api.StopAnswer; -import com.cloud.agent.api.UpgradeSnapshotCommand; -import com.cloud.agent.api.VmStatsEntry; +import com.cloud.agent.api.*; import com.cloud.agent.api.storage.CreatePrivateTemplateAnswer; import com.cloud.agent.api.to.NicTO; import com.cloud.agent.api.to.VirtualMachineTO; @@ -59,22 +28,7 @@ import com.cloud.agent.manager.Commands; import com.cloud.alert.AlertManager; import com.cloud.api.ApiDBUtils; import com.cloud.api.BaseCmd; -import com.cloud.api.commands.AssignVMCmd; -import com.cloud.api.commands.AttachVolumeCmd; -import com.cloud.api.commands.CreateTemplateCmd; -import com.cloud.api.commands.CreateVMGroupCmd; -import com.cloud.api.commands.DeleteVMGroupCmd; -import com.cloud.api.commands.DeployVMCmd; -import com.cloud.api.commands.DestroyVMCmd; -import com.cloud.api.commands.DetachVolumeCmd; -import com.cloud.api.commands.ListVMsCmd; -import com.cloud.api.commands.RebootVMCmd; -import com.cloud.api.commands.RecoverVMCmd; -import com.cloud.api.commands.ResetVMPasswordCmd; -import com.cloud.api.commands.RestoreVMCmd; -import com.cloud.api.commands.StartVMCmd; -import com.cloud.api.commands.UpdateVMCmd; -import com.cloud.api.commands.UpgradeVMCmd; +import com.cloud.api.commands.*; import com.cloud.async.AsyncJobExecutor; import com.cloud.async.AsyncJobManager; import com.cloud.async.AsyncJobVO; @@ -99,37 +53,18 @@ import com.cloud.event.ActionEvent; import com.cloud.event.EventTypes; import com.cloud.event.UsageEventVO; import com.cloud.event.dao.UsageEventDao; -import com.cloud.exception.ConcurrentOperationException; -import com.cloud.exception.InsufficientCapacityException; -import com.cloud.exception.InvalidParameterValueException; -import com.cloud.exception.ManagementServerException; -import com.cloud.exception.OperationTimedoutException; -import com.cloud.exception.PermissionDeniedException; -import com.cloud.exception.ResourceAllocationException; -import com.cloud.exception.ResourceUnavailableException; -import com.cloud.exception.StorageUnavailableException; -import com.cloud.exception.VirtualMachineMigrationException; +import com.cloud.exception.*; import com.cloud.ha.HighAvailabilityManager; import com.cloud.host.Host; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; import com.cloud.hypervisor.Hypervisor.HypervisorType; import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao; -import com.cloud.network.IPAddressVO; -import com.cloud.network.LoadBalancerVMMapVO; -import com.cloud.network.Network; +import com.cloud.network.*; import com.cloud.network.Network.Provider; import com.cloud.network.Network.Service; -import com.cloud.network.NetworkManager; -import com.cloud.network.NetworkVO; import com.cloud.network.Networks.TrafficType; -import com.cloud.network.PhysicalNetwork; -import com.cloud.network.dao.FirewallRulesDao; -import com.cloud.network.dao.IPAddressDao; -import com.cloud.network.dao.LoadBalancerVMMapDao; -import com.cloud.network.dao.NetworkDao; -import com.cloud.network.dao.NetworkServiceMapDao; -import com.cloud.network.dao.PhysicalNetworkDao; +import com.cloud.network.dao.*; import com.cloud.network.element.UserDataServiceProvider; import com.cloud.network.lb.LoadBalancingRulesManager; import com.cloud.network.rules.FirewallManager; @@ -159,50 +94,19 @@ import com.cloud.server.Criteria; import com.cloud.server.ResourceTag.TaggedResourceType; import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; -import com.cloud.storage.DiskOfferingVO; -import com.cloud.storage.GuestOSVO; -import com.cloud.storage.Snapshot; -import com.cloud.storage.SnapshotVO; -import com.cloud.storage.Storage; +import com.cloud.storage.*; import com.cloud.storage.Storage.ImageFormat; import com.cloud.storage.Storage.StoragePoolType; import com.cloud.storage.Storage.TemplateType; -import com.cloud.storage.StorageManager; -import com.cloud.storage.StoragePool; -import com.cloud.storage.StoragePoolStatus; -import com.cloud.storage.StoragePoolVO; -import com.cloud.storage.VMTemplateHostVO; import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; -import com.cloud.storage.VMTemplateVO; -import com.cloud.storage.VMTemplateZoneVO; -import com.cloud.storage.Volume; import com.cloud.storage.Volume.Type; -import com.cloud.storage.VolumeHostVO; -import com.cloud.storage.VolumeVO; -import com.cloud.storage.dao.DiskOfferingDao; -import com.cloud.storage.dao.GuestOSDao; -import com.cloud.storage.dao.SnapshotDao; -import com.cloud.storage.dao.StoragePoolDao; -import com.cloud.storage.dao.VMTemplateDao; -import com.cloud.storage.dao.VMTemplateDetailsDao; -import com.cloud.storage.dao.VMTemplateHostDao; -import com.cloud.storage.dao.VMTemplateZoneDao; -import com.cloud.storage.dao.VolumeDao; -import com.cloud.storage.dao.VolumeHostDao; +import com.cloud.storage.dao.*; import com.cloud.storage.snapshot.SnapshotManager; import com.cloud.tags.ResourceTagVO; import com.cloud.tags.dao.ResourceTagDao; import com.cloud.template.VirtualMachineTemplate; import com.cloud.template.VirtualMachineTemplate.BootloaderType; -import com.cloud.user.Account; -import com.cloud.user.AccountManager; -import com.cloud.user.AccountService; -import com.cloud.user.AccountVO; -import com.cloud.user.ResourceLimitService; -import com.cloud.user.SSHKeyPair; -import com.cloud.user.User; -import com.cloud.user.UserContext; -import com.cloud.user.UserVO; +import com.cloud.user.*; import com.cloud.user.dao.AccountDao; import com.cloud.user.dao.SSHKeyPairDao; import com.cloud.user.dao.UserDao; @@ -216,24 +120,22 @@ import com.cloud.utils.component.Inject; import com.cloud.utils.component.Manager; import com.cloud.utils.concurrency.NamedThreadFactory; import com.cloud.utils.crypt.RSAHelper; -import com.cloud.utils.db.DB; -import com.cloud.utils.db.Filter; -import com.cloud.utils.db.GlobalLock; -import com.cloud.utils.db.JoinBuilder; -import com.cloud.utils.db.SearchBuilder; -import com.cloud.utils.db.SearchCriteria; -import com.cloud.utils.db.Transaction; +import com.cloud.utils.db.*; import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.utils.exception.ExecutionException; import com.cloud.utils.fsm.NoTransitionException; import com.cloud.utils.net.NetUtils; import com.cloud.vm.VirtualMachine.State; -import com.cloud.vm.dao.InstanceGroupDao; -import com.cloud.vm.dao.InstanceGroupVMMapDao; -import com.cloud.vm.dao.NicDao; -import com.cloud.vm.dao.UserVmDao; -import com.cloud.vm.dao.UserVmDetailsDao; -import com.cloud.vm.dao.VMInstanceDao; +import com.cloud.vm.dao.*; +import org.apache.commons.codec.binary.Base64; +import org.apache.log4j.Logger; + +import javax.ejb.Local; +import javax.naming.ConfigurationException; +import java.util.*; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; @Local(value = { UserVmManager.class, UserVmService.class }) public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager { @@ -2857,6 +2759,10 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager if (ip != null && ip.getSystem()) { UserContext ctx = UserContext.current(); try { + long networkId = ip.getAssociatedWithNetworkId(); + Network guestNetwork = _networkMgr.getNetwork(networkId); + NetworkOffering offering = _configMgr.getNetworkOffering(guestNetwork.getNetworkOfferingId()); + assert (offering.getAssociatePublicIP() == true) : "User VM should not have system owned public IP associated with it when offering configured not to associate public IP."; _rulesMgr.disableStaticNat(ip.getId(), ctx.getCaller(), ctx.getCallerUserId(), true); } catch (Exception ex) { s_logger.warn("Failed to disable static nat and release system ip " + ip + " as a part of vm " + profile.getVirtualMachine() + " stop due to exception ", ex); diff --git a/setup/db/create-schema.sql b/setup/db/create-schema.sql index fff084e6336..b0457d7ef3e 100755 --- a/setup/db/create-schema.sql +++ b/setup/db/create-schema.sql @@ -303,6 +303,7 @@ CREATE TABLE `cloud`.`network_offerings` ( `state` char(32) COMMENT 'state of the network offering that has Disabled value by default', `guest_type` char(32) COMMENT 'type of guest network that can be shared or isolated', `elastic_ip_service` int(1) unsigned NOT NULL DEFAULT 0 COMMENT 'true if the network offering provides elastic ip service', + `eip_associate_public_ip` int(1) unsigned NOT NULL DEFAULT 0 COMMENT 'true if public IP is associated with user VM creation by default when EIP service is enabled.', `elastic_lb_service` int(1) unsigned NOT NULL DEFAULT 0 COMMENT 'true if the network offering provides elastic lb service', `specify_ip_ranges` int(1) unsigned NOT NULL DEFAULT 0 COMMENT 'true if the network offering provides an ability to define ip ranges', PRIMARY KEY (`id`), diff --git a/setup/db/db/schema-40to41.sql b/setup/db/db/schema-40to41.sql new file mode 100644 index 00000000000..51afde47bfe --- /dev/null +++ b/setup/db/db/schema-40to41.sql @@ -0,0 +1,23 @@ +-- Licensed to the Apache Software Foundation (ASF) under one +-- or more contributor license agreements. See the NOTICE file +-- distributed with this work for additional information +-- regarding copyright ownership. The ASF licenses this file +-- to you under the Apache License, Version 2.0 (the +-- "License"); you may not use this file except in compliance +-- with the License. You may obtain a copy of the License at +-- +-- http://www.apache.org/licenses/LICENSE-2.0 +-- +-- Unless required by applicable law or agreed to in writing, +-- software distributed under the License is distributed on an +-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +-- KIND, either express or implied. See the License for the +-- specific language governing permissions and limitations +-- under the License. + +--; +-- Schema upgrade from 4.0 to 4.1.0; +--; + + +ALTER TABLE `cloud`.`network_offerings` ADD COLUMN `eip_associate_public_ip` int(1) unsigned NOT NULL DEFAULT 0 COMMENT 'true if public IP is associated with user VM creation by default when EIP service is enabled.' AFTER `elastic_ip_service`;