apply network acls; acls items to pvt gw; vpc ip association Conflicts: server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java server/src/com/cloud/network/rules/VirtualNetworkApplianceFactory.java server/src/org/apache/cloudstack/network/topology/BasicNetworkTopology.java
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/b97f2b05 Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/b97f2b05 Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/b97f2b05 Branch: refs/heads/master Commit: b97f2b05c738d0ba386923f271f18a78f7fc70a1 Parents: f23ba91 Author: Wilder Rodrigues <wrodrig...@schubergphilis.com> Authored: Thu Jul 17 15:22:25 2014 +0200 Committer: wilderrodrigues <wrodrig...@schubergphilis.com> Committed: Tue Oct 14 15:01:14 2014 +0200 ---------------------------------------------------------------------- .../com/cloud/network/element/OvsElement.java | 139 ++++++----- .../element/VpcVirtualRouterElement.java | 28 ++- .../router/VirtualNetworkApplianceManager.java | 45 +--- .../VirtualNetworkApplianceManagerImpl.java | 242 +------------------ .../VpcVirtualNetworkApplianceManager.java | 14 -- .../VpcVirtualNetworkApplianceManagerImpl.java | 136 ----------- .../cloud/network/rules/NetworkAclsRules.java | 55 ++++- .../cloud/network/rules/NicPlugInOutRules.java | 202 ++++++++++++++++ .../com/cloud/network/rules/RuleApplier.java | 14 +- .../network/rules/SshKeyToRouterRules.java | 1 - .../rules/VirtualNetworkApplianceFactory.java | 49 ++++ .../network/rules/VpcIpAssociationRules.java | 128 +++++++++- .../topology/AdvancedNetworkTopology.java | 54 ++++- .../topology/AdvancedNetworkVisitor.java | 47 ++-- .../network/topology/BasicNetworkTopology.java | 21 +- .../network/topology/BasicNetworkVisitor.java | 36 +-- .../network/topology/NetworkTopology.java | 12 +- .../topology/NetworkTopologyVisitor.java | 2 + .../MockVpcVirtualNetworkApplianceManager.java | 100 +------- 19 files changed, 679 insertions(+), 646 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b97f2b05/plugins/network-elements/ovs/src/com/cloud/network/element/OvsElement.java ---------------------------------------------------------------------- diff --git a/plugins/network-elements/ovs/src/com/cloud/network/element/OvsElement.java b/plugins/network-elements/ovs/src/com/cloud/network/element/OvsElement.java index faf58fc..5ce4d93 100644 --- a/plugins/network-elements/ovs/src/com/cloud/network/element/OvsElement.java +++ b/plugins/network-elements/ovs/src/com/cloud/network/element/OvsElement.java @@ -16,8 +16,6 @@ // under the License. package com.cloud.network.element; -import com.cloud.host.dao.HostDao; -import com.cloud.vm.dao.UserVmDao; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -28,13 +26,15 @@ import javax.ejb.Local; import javax.inject.Inject; import javax.naming.ConfigurationException; +import org.apache.cloudstack.network.topology.NetworkTopology; +import org.apache.cloudstack.network.topology.NetworkTopologyContext; import org.apache.log4j.Logger; -import com.google.gson.Gson; - import com.cloud.agent.api.StartupCommand; import com.cloud.agent.api.StartupOvsCommand; import com.cloud.agent.api.to.LoadBalancerTO; +import com.cloud.dc.DataCenterVO; +import com.cloud.dc.dao.DataCenterDao; import com.cloud.deploy.DeployDestination; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientCapacityException; @@ -42,10 +42,12 @@ import com.cloud.exception.InvalidParameterValueException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.host.Host; import com.cloud.host.HostVO; +import com.cloud.host.dao.HostDao; import com.cloud.network.Network; import com.cloud.network.Network.Capability; import com.cloud.network.Network.Provider; import com.cloud.network.Network.Service; +import com.cloud.network.NetworkMigrationResponder; import com.cloud.network.NetworkModel; import com.cloud.network.Networks; import com.cloud.network.Networks.BroadcastDomainType; @@ -54,10 +56,8 @@ import com.cloud.network.PublicIpAddress; import com.cloud.network.dao.NetworkServiceMapDao; import com.cloud.network.lb.LoadBalancingRule; import com.cloud.network.lb.LoadBalancingRule.LbStickinessPolicy; -import com.cloud.network.NetworkMigrationResponder; import com.cloud.network.ovs.OvsTunnelManager; import com.cloud.network.router.VirtualRouter.Role; -import com.cloud.network.router.VpcVirtualNetworkApplianceManager; import com.cloud.network.rules.LbStickinessMethod; import com.cloud.network.rules.LbStickinessMethod.StickinessMethodType; import com.cloud.network.rules.LoadBalancerContainer; @@ -74,9 +74,11 @@ import com.cloud.utils.exception.CloudRuntimeException; import com.cloud.vm.DomainRouterVO; import com.cloud.vm.NicProfile; import com.cloud.vm.ReservationContext; +import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachineProfile; import com.cloud.vm.dao.DomainRouterDao; -import com.cloud.vm.VirtualMachine; +import com.cloud.vm.dao.UserVmDao; +import com.google.gson.Gson; @Local(value = {NetworkElement.class, ConnectivityProvider.class, SourceNatServiceProvider.class, StaticNatServiceProvider.class, @@ -96,11 +98,14 @@ StaticNatServiceProvider, IpDeployer { @Inject DomainRouterDao _routerDao; @Inject - VpcVirtualNetworkApplianceManager _routerMgr; - @Inject UserVmDao _userVmDao; @Inject HostDao _hostDao; + @Inject + DataCenterDao _dcDao; + + @Inject + NetworkTopologyContext _networkTopologyContext; private static final Logger s_logger = Logger.getLogger(OvsElement.class); private static final Map<Service, Map<Capability, String>> capabilities = setCapabilities(); @@ -115,7 +120,7 @@ StaticNatServiceProvider, IpDeployer { return Provider.Ovs; } - protected boolean canHandle(Network network, Service service) { + protected boolean canHandle(final Network network, final Service service) { s_logger.debug("Checking if OvsElement can handle service " + service.getName() + " on network " + network.getDisplayText()); if (network.getBroadcastDomainType() != BroadcastDomainType.Vswitch) { @@ -139,7 +144,7 @@ StaticNatServiceProvider, IpDeployer { } @Override - public boolean configure(String name, Map<String, Object> params) + public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException { super.configure(name, params); _resourceMgr.registerResourceStateAdapter(name, this); @@ -147,8 +152,8 @@ StaticNatServiceProvider, IpDeployer { } @Override - public boolean implement(Network network, NetworkOffering offering, - DeployDestination dest, ReservationContext context) + public boolean implement(final Network network, final NetworkOffering offering, + final DeployDestination dest, final ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { s_logger.debug("entering OvsElement implement function for network " @@ -162,9 +167,9 @@ StaticNatServiceProvider, IpDeployer { } @Override - public boolean prepare(Network network, NicProfile nic, - VirtualMachineProfile vm, - DeployDestination dest, ReservationContext context) + public boolean prepare(final Network network, final NicProfile nic, + final VirtualMachineProfile vm, + final DeployDestination dest, final ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException { if (!canHandle(network, Service.Connectivity)) { @@ -190,9 +195,9 @@ StaticNatServiceProvider, IpDeployer { } @Override - public boolean release(Network network, NicProfile nic, - VirtualMachineProfile vm, - ReservationContext context) throws ConcurrentOperationException, + public boolean release(final Network network, final NicProfile nic, + final VirtualMachineProfile vm, + final ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException { if (!canHandle(network, Service.Connectivity)) { return false; @@ -211,8 +216,8 @@ StaticNatServiceProvider, IpDeployer { } @Override - public boolean shutdown(Network network, ReservationContext context, - boolean cleanup) throws ConcurrentOperationException, + public boolean shutdown(final Network network, final ReservationContext context, + final boolean cleanup) throws ConcurrentOperationException, ResourceUnavailableException { if (!canHandle(network, Service.Connectivity)) { return false; @@ -221,7 +226,7 @@ StaticNatServiceProvider, IpDeployer { } @Override - public boolean destroy(Network network, ReservationContext context) + public boolean destroy(final Network network, final ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException { if (!canHandle(network, Service.Connectivity)) { return false; @@ -230,13 +235,13 @@ StaticNatServiceProvider, IpDeployer { } @Override - public boolean isReady(PhysicalNetworkServiceProvider provider) { + public boolean isReady(final PhysicalNetworkServiceProvider provider) { return true; } @Override public boolean shutdownProviderInstances( - PhysicalNetworkServiceProvider provider, ReservationContext context) + final PhysicalNetworkServiceProvider provider, final ReservationContext context) throws ConcurrentOperationException, ResourceUnavailableException { return true; } @@ -247,7 +252,7 @@ StaticNatServiceProvider, IpDeployer { } @Override - public boolean verifyServicesCombination(Set<Service> services) { + public boolean verifyServicesCombination(final Set<Service> services) { if (!services.contains(Service.Connectivity)) { s_logger.warn("Unable to provide services without Connectivity service enabled for this element"); return false; @@ -392,15 +397,15 @@ StaticNatServiceProvider, IpDeployer { } @Override - public HostVO createHostVOForConnectedAgent(HostVO host, - StartupCommand[] cmd) { + public HostVO createHostVOForConnectedAgent(final HostVO host, + final StartupCommand[] cmd) { return null; } @Override - public HostVO createHostVOForDirectConnectAgent(HostVO host, - StartupCommand[] startup, ServerResource resource, - Map<String, String> details, List<String> hostTags) { + public HostVO createHostVOForDirectConnectAgent(final HostVO host, + final StartupCommand[] startup, final ServerResource resource, + final Map<String, String> details, final List<String> hostTags) { if (!(startup[0] instanceof StartupOvsCommand)) { return null; } @@ -409,8 +414,8 @@ StaticNatServiceProvider, IpDeployer { } @Override - public DeleteHostAnswer deleteHost(HostVO host, boolean isForced, - boolean isForceDeleteStorage) throws UnableDeleteHostException { + public DeleteHostAnswer deleteHost(final HostVO host, final boolean isForced, + final boolean isForceDeleteStorage) throws UnableDeleteHostException { if (!(host.getType() == Host.Type.L2Networking)) { return null; } @@ -418,13 +423,13 @@ StaticNatServiceProvider, IpDeployer { } @Override - public IpDeployer getIpDeployer(Network network) { + public IpDeployer getIpDeployer(final Network network) { return this; } @Override - public boolean applyIps(Network network, - List<? extends PublicIpAddress> ipAddress, Set<Service> services) + public boolean applyIps(final Network network, + final List<? extends PublicIpAddress> ipAddress, final Set<Service> services) throws ResourceUnavailableException { boolean canHandle = true; for (Service service : services) { @@ -444,14 +449,17 @@ StaticNatServiceProvider, IpDeployer { return true; } - return _routerMgr.associatePublicIP(network, ipAddress, routers); + DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId()); + NetworkTopology networkTopology = _networkTopologyContext.retrieveNetworkTopology(dcVO); + + return networkTopology.associatePublicIP(network, ipAddress, routers); } else { return false; } } @Override - public boolean applyStaticNats(Network network, List<? extends StaticNat> rules) + public boolean applyStaticNats(final Network network, final List<? extends StaticNat> rules) throws ResourceUnavailableException { if (!canHandle(network, Service.StaticNat)) { return false; @@ -464,11 +472,14 @@ StaticNatServiceProvider, IpDeployer { return true; } - return _routerMgr.applyStaticNats(network, rules, routers); + DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId()); + NetworkTopology networkTopology = _networkTopologyContext.retrieveNetworkTopology(dcVO); + + return networkTopology.applyStaticNats(network, rules, routers); } @Override - public boolean applyPFRules(Network network, List<PortForwardingRule> rules) + public boolean applyPFRules(final Network network, final List<PortForwardingRule> rules) throws ResourceUnavailableException { if (!canHandle(network, Service.PortForwarding)) { return false; @@ -481,11 +492,14 @@ StaticNatServiceProvider, IpDeployer { return true; } - return _routerMgr.applyFirewallRules(network, rules, routers); + DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId()); + NetworkTopology networkTopology = _networkTopologyContext.retrieveNetworkTopology(dcVO); + + return networkTopology.applyFirewallRules(network, rules, routers); } @Override - public boolean applyLBRules(Network network, List<LoadBalancingRule> rules) + public boolean applyLBRules(final Network network, final List<LoadBalancingRule> rules) throws ResourceUnavailableException { if (canHandle(network, Service.Lb)) { if (!canHandleLbRules(rules)) { @@ -501,7 +515,10 @@ StaticNatServiceProvider, IpDeployer { return true; } - if (!_routerMgr.applyLoadBalancingRules(network, rules, routers)) { + DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId()); + NetworkTopology networkTopology = _networkTopologyContext.retrieveNetworkTopology(dcVO); + + if (!networkTopology.applyLoadBalancingRules(network, rules, routers)) { throw new CloudRuntimeException( "Failed to apply load balancing rules in network " + network.getId()); @@ -514,7 +531,7 @@ StaticNatServiceProvider, IpDeployer { } @Override - public boolean validateLBRule(Network network, LoadBalancingRule rule) { + public boolean validateLBRule(final Network network, final LoadBalancingRule rule) { List<LoadBalancingRule> rules = new ArrayList<LoadBalancingRule>(); rules.add(rule); if (canHandle(network, Service.Lb) && canHandleLbRules(rules)) { @@ -529,13 +546,13 @@ StaticNatServiceProvider, IpDeployer { } @Override - public List<LoadBalancerTO> updateHealthChecks(Network network, - List<LoadBalancingRule> lbrules) { + public List<LoadBalancerTO> updateHealthChecks(final Network network, + final List<LoadBalancingRule> lbrules) { // TODO Auto-generated method stub return null; } - private boolean canHandleLbRules(List<LoadBalancingRule> rules) { + private boolean canHandleLbRules(final List<LoadBalancingRule> rules) { Map<Capability, String> lbCaps = getCapabilities().get(Service.Lb); if (!lbCaps.isEmpty()) { String schemeCaps = lbCaps.get(Capability.LbSchemes); @@ -553,7 +570,7 @@ StaticNatServiceProvider, IpDeployer { return true; } - public static boolean validateHAProxyLBRule(LoadBalancingRule rule) { + public static boolean validateHAProxyLBRule(final LoadBalancingRule rule) { String timeEndChar = "dhms"; for (LbStickinessPolicy stickinessPolicy : rule.getStickinessPolicies()) { @@ -572,10 +589,12 @@ StaticNatServiceProvider, IpDeployer { for (Pair<String, String> paramKV : paramsList) { String key = paramKV.first(); String value = paramKV.second(); - if ("tablesize".equalsIgnoreCase(key)) + if ("tablesize".equalsIgnoreCase(key)) { tablesize = value; - if ("expire".equalsIgnoreCase(key)) + } + if ("expire".equalsIgnoreCase(key)) { expire = value; + } } if ((expire != null) && !containsOnlyNumbers(expire, timeEndChar)) { @@ -601,10 +620,12 @@ StaticNatServiceProvider, IpDeployer { for (Pair<String, String> paramKV : paramsList) { String key = paramKV.first(); String value = paramKV.second(); - if ("length".equalsIgnoreCase(key)) + if ("length".equalsIgnoreCase(key)) { length = value; - if ("holdtime".equalsIgnoreCase(key)) + } + if ("holdtime".equalsIgnoreCase(key)) { holdTime = value; + } } if ((length != null) && (!containsOnlyNumbers(length, null))) { @@ -631,15 +652,18 @@ StaticNatServiceProvider, IpDeployer { * like 12 2) time or tablesize like 12h, 34m, 45k, 54m , here last * character is non-digit but from known characters . */ - private static boolean containsOnlyNumbers(String str, String endChar) { - if (str == null) + private static boolean containsOnlyNumbers(final String str, final String endChar) { + if (str == null) { return false; + } String number = str; if (endChar != null) { boolean matchedEndChar = false; if (str.length() < 2) + { return false; // atleast one numeric and one char. example: + } // 3h char strEnd = str.toCharArray()[str.length() - 1]; for (char c : endChar.toCharArray()) { @@ -649,8 +673,9 @@ StaticNatServiceProvider, IpDeployer { break; } } - if (!matchedEndChar) + if (!matchedEndChar) { return false; + } } try { Integer.parseInt(number); @@ -661,7 +686,7 @@ StaticNatServiceProvider, IpDeployer { } @Override - public boolean prepareMigration(NicProfile nic, Network network, VirtualMachineProfile vm, DeployDestination dest, ReservationContext context) { + public boolean prepareMigration(final NicProfile nic, final Network network, final VirtualMachineProfile vm, final DeployDestination dest, final ReservationContext context) { if (!canHandle(network, Service.Connectivity)) { return false; } @@ -685,12 +710,12 @@ StaticNatServiceProvider, IpDeployer { } @Override - public void rollbackMigration(NicProfile nic, Network network, VirtualMachineProfile vm, ReservationContext src, ReservationContext dst) { + public void rollbackMigration(final NicProfile nic, final Network network, final VirtualMachineProfile vm, final ReservationContext src, final ReservationContext dst) { return; } @Override - public void commitMigration(NicProfile nic, Network network, VirtualMachineProfile vm, ReservationContext src, ReservationContext dst) { + public void commitMigration(final NicProfile nic, final Network network, final VirtualMachineProfile vm, final ReservationContext src, final ReservationContext dst) { return; } } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b97f2b05/server/src/com/cloud/network/element/VpcVirtualRouterElement.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/network/element/VpcVirtualRouterElement.java b/server/src/com/cloud/network/element/VpcVirtualRouterElement.java index c1bfb9f..5bc62c0 100644 --- a/server/src/com/cloud/network/element/VpcVirtualRouterElement.java +++ b/server/src/com/cloud/network/element/VpcVirtualRouterElement.java @@ -446,30 +446,33 @@ public class VpcVirtualRouterElement extends VirtualRouterElement implements Vpc DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId()); NetworkTopology networkTopology = networkTopologyContext.retrieveNetworkTopology(dcVO); - return _vpcRouterMgr.associatePublicIP(network, ipAddress, routers); + return networkTopology.associatePublicIP(network, ipAddress, routers); } else { return false; } } @Override - public boolean applyNetworkACLs(final Network config, final List<? extends NetworkACLItem> rules) throws ResourceUnavailableException { - if (canHandle(config, Service.NetworkACL)) { - List<DomainRouterVO> routers = _routerDao.listByNetworkAndRole(config.getId(), Role.VIRTUAL_ROUTER); + public boolean applyNetworkACLs(final Network network, final List<? extends NetworkACLItem> rules) throws ResourceUnavailableException { + if (canHandle(network, Service.NetworkACL)) { + List<DomainRouterVO> routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER); if (routers == null || routers.isEmpty()) { s_logger.debug("Virtual router elemnt doesn't need to apply firewall rules on the backend; virtual " + "router doesn't exist in the network " + - config.getId()); + network.getId()); return true; } + DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId()); + NetworkTopology networkTopology = networkTopologyContext.retrieveNetworkTopology(dcVO); + try { - if (!_vpcRouterMgr.applyNetworkACLs(config, rules, routers, false)) { + if (!networkTopology.applyNetworkACLs(network, rules, routers, false)) { return false; } else { return true; } } catch (Exception ex) { - s_logger.debug("Failed to apply network acl in network " + config.getId()); + s_logger.debug("Failed to apply network acl in network " + network.getId()); return false; } } else { @@ -500,18 +503,21 @@ public class VpcVirtualRouterElement extends VirtualRouterElement implements Vpc @Override public boolean applyACLItemsToPrivateGw(final PrivateGateway gateway, final List<? extends NetworkACLItem> rules) throws ResourceUnavailableException { - Network config = _networkDao.findById(gateway.getNetworkId()); + Network network = _networkDao.findById(gateway.getNetworkId()); boolean isPrivateGateway = true; List<DomainRouterVO> routers = _vpcRouterMgr.getVpcRouters(gateway.getVpcId()); if (routers == null || routers.isEmpty()) { s_logger.debug("Virtual router element doesn't need to apply network acl rules on the backend; virtual " + "router doesn't exist in the network " + - config.getId()); + network.getId()); return true; } - if (!_vpcRouterMgr.applyNetworkACLs(config, rules, routers, isPrivateGateway)) { - throw new CloudRuntimeException("Failed to apply network acl in network " + config.getId()); + DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId()); + NetworkTopology networkTopology = networkTopologyContext.retrieveNetworkTopology(dcVO); + + if (!networkTopology.applyNetworkACLs(network, rules, routers, isPrivateGateway)) { + throw new CloudRuntimeException("Failed to apply network acl in network " + network.getId()); } else { return true; } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b97f2b05/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java index 2b92288..857cfe9 100644 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java @@ -25,13 +25,9 @@ import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.Network; -import com.cloud.network.PublicIpAddress; import com.cloud.network.RemoteAccessVpn; import com.cloud.network.VirtualNetworkApplianceService; import com.cloud.network.VpnUser; -import com.cloud.network.lb.LoadBalancingRule; -import com.cloud.network.rules.FirewallRule; -import com.cloud.network.rules.StaticNat; import com.cloud.user.Account; import com.cloud.user.User; import com.cloud.utils.component.Manager; @@ -53,15 +49,15 @@ public interface VirtualNetworkApplianceManager extends Manager, VirtualNetworkA static final String RouterAlertsCheckIntervalCK = "router.alerts.check.interval"; static final ConfigKey<String> RouterTemplateXen = new ConfigKey<String>(String.class, RouterTemplateXenCK, "Advanced", "SystemVM Template (XenServer)", - "Name of the default router template on Xenserver.", true, ConfigKey.Scope.Zone, null); + "Name of the default router template on Xenserver.", true, ConfigKey.Scope.Zone, null); static final ConfigKey<String> RouterTemplateKvm = new ConfigKey<String>(String.class, RouterTemplateKvmCK, "Advanced", "SystemVM Template (KVM)", - "Name of the default router template on KVM.", true, ConfigKey.Scope.Zone, null); + "Name of the default router template on KVM.", true, ConfigKey.Scope.Zone, null); static final ConfigKey<String> RouterTemplateVmware = new ConfigKey<String>(String.class, RouterTemplateVmwareCK, "Advanced", "SystemVM Template (vSphere)", - "Name of the default router template on Vmware.", true, ConfigKey.Scope.Zone, null); + "Name of the default router template on Vmware.", true, ConfigKey.Scope.Zone, null); static final ConfigKey<String> RouterTemplateHyperV = new ConfigKey<String>(String.class, RouterTemplateHyperVCK, "Advanced", "SystemVM Template (HyperV)", - "Name of the default router template on Hyperv.", true, ConfigKey.Scope.Zone, null); + "Name of the default router template on Hyperv.", true, ConfigKey.Scope.Zone, null); static final ConfigKey<String> RouterTemplateLxc = new ConfigKey<String>(String.class, RouterTemplateLxcCK, "Advanced", "SystemVM Template (LXC)", - "Name of the default router template on LXC.", true, ConfigKey.Scope.Zone, null); + "Name of the default router template on LXC.", true, ConfigKey.Scope.Zone, null); static final ConfigKey<String> SetServiceMonitor = new ConfigKey<String>(String.class, SetServiceMonitorCK, "Advanced", "true", "service monitoring in router enable/disable option, default true", true, ConfigKey.Scope.Zone, null); @@ -82,29 +78,10 @@ public interface VirtualNetworkApplianceManager extends Manager, VirtualNetworkA */ boolean sendSshKeysToHost(Long hostId, String pubKey, String prvKey); - /** - * save a vm password on the router. - * @param routers TODO - * - */ - boolean savePasswordToRouter(Network network, NicProfile nic, VirtualMachineProfile profile, List<? extends VirtualRouter> routers) - throws ResourceUnavailableException; - - boolean saveSSHPublicKeyToRouter(Network network, NicProfile nic, VirtualMachineProfile profile, List<? extends VirtualRouter> routers, String sshPublicKey) - throws ResourceUnavailableException; - - boolean saveUserDataToRouter(Network network, NicProfile nic, VirtualMachineProfile profile, List<? extends VirtualRouter> routers) - throws ResourceUnavailableException; - boolean startRemoteAccessVpn(Network network, RemoteAccessVpn vpn, List<? extends VirtualRouter> routers) throws ResourceUnavailableException; boolean deleteRemoteAccessVpn(Network network, RemoteAccessVpn vpn, List<? extends VirtualRouter> routers) throws ResourceUnavailableException; - boolean associatePublicIP(Network network, final List<? extends PublicIpAddress> ipAddress, List<? extends VirtualRouter> routers) - throws ResourceUnavailableException; - - boolean applyFirewallRules(Network network, final List<? extends FirewallRule> rules, List<? extends VirtualRouter> routers) throws ResourceUnavailableException; - List<VirtualRouter> getRoutersForNetwork(long networkId); String[] applyVpnUsers(Network network, List<? extends VpnUser> users, List<DomainRouterVO> routers) throws ResourceUnavailableException; @@ -113,18 +90,8 @@ public interface VirtualNetworkApplianceManager extends Manager, VirtualNetworkA String getDnsBasicZoneUpdate(); - boolean applyStaticNats(Network network, final List<? extends StaticNat> rules, List<? extends VirtualRouter> routers) throws ResourceUnavailableException; - - boolean applyDhcpEntry(Network config, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, List<DomainRouterVO> routers) - throws ResourceUnavailableException; - - boolean applyUserData(Network config, NicProfile nic, VirtualMachineProfile vm, DeployDestination dest, List<DomainRouterVO> routers) - throws ResourceUnavailableException; - - boolean applyLoadBalancingRules(Network network, List<? extends LoadBalancingRule> rules, List<? extends VirtualRouter> routers) throws ResourceUnavailableException; - boolean configDhcpForSubnet(Network network, NicProfile nic, VirtualMachineProfile uservm, DeployDestination dest, List<DomainRouterVO> routers) - throws ResourceUnavailableException; + throws ResourceUnavailableException; boolean removeDhcpSupportForSubnet(Network network, List<DomainRouterVO> routers) throws ResourceUnavailableException; http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b97f2b05/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java index 1fd8e5a..cea7118 100755 --- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java @@ -214,7 +214,6 @@ import com.cloud.service.ServiceOfferingVO; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.GuestOSVO; import com.cloud.storage.Storage.ProvisioningType; -import com.cloud.storage.VMTemplateVO; import com.cloud.storage.dao.GuestOSDao; import com.cloud.storage.dao.VMTemplateDao; import com.cloud.storage.dao.VolumeDao; @@ -500,72 +499,8 @@ Configurable, StateListener<State, VirtualMachine.Event, VirtualMachine> { } - @Override - public boolean savePasswordToRouter(final Network network, final NicProfile nic, final VirtualMachineProfile profile, final List<? extends VirtualRouter> routers) - throws ResourceUnavailableException { - _userVmDao.loadDetails((UserVmVO) profile.getVirtualMachine()); - - final VirtualMachineProfile updatedProfile = profile; - - return applyRules(network, routers, "save password entry", false, null, false, new RuleApplier() { - @Override - public boolean execute(final Network network, final VirtualRouter router) throws ResourceUnavailableException { - // for basic zone, send vm data/password information only to the - // router in the same pod - final Commands cmds = new Commands(Command.OnError.Stop); - final NicVO nicVo = _nicDao.findById(nic.getId()); - createPasswordCommand(router, updatedProfile, nicVo, cmds); - return sendCommandsToRouter(router, cmds); - } - }); - } - - @Override - public boolean saveSSHPublicKeyToRouter(final Network network, final NicProfile nic, final VirtualMachineProfile profile, final List<? extends VirtualRouter> routers, - final String sshPublicKey) throws ResourceUnavailableException { - final UserVmVO vm = _userVmDao.findById(profile.getVirtualMachine().getId()); - _userVmDao.loadDetails(vm); - - final VirtualMachineProfile updatedProfile = profile; - - return applyRules(network, routers, "save SSHkey entry", false, null, false, new RuleApplier() { - @Override - public boolean execute(final Network network, final VirtualRouter router) throws ResourceUnavailableException { - // for basic zone, send vm data/password information only to the - // router in the same pod - final Commands cmds = new Commands(Command.OnError.Stop); - final NicVO nicVo = _nicDao.findById(nic.getId()); - final VMTemplateVO template = _templateDao.findByIdIncludingRemoved(updatedProfile.getTemplateId()); - if (template != null && template.getEnablePassword()) { - createPasswordCommand(router, updatedProfile, nicVo, cmds); - } - createVmDataCommand(router, vm, nicVo, sshPublicKey, cmds); - return sendCommandsToRouter(router, cmds); - } - }); - } - - @Override - public boolean saveUserDataToRouter(final Network network, final NicProfile nic, final VirtualMachineProfile profile, final List<? extends VirtualRouter> routers) - throws ResourceUnavailableException { - final UserVmVO vm = _userVmDao.findById(profile.getVirtualMachine().getId()); - _userVmDao.loadDetails(vm); - - return applyRules(network, routers, "save userdata entry", false, null, false, new RuleApplier() { - @Override - public boolean execute(final Network network, final VirtualRouter router) throws ResourceUnavailableException { - // for basic zone, send vm data/password information only to the - // router in the same pod - final Commands cmds = new Commands(Command.OnError.Stop); - final NicVO nicVo = _nicDao.findById(nic.getId()); - createVmDataCommand(router, vm, nicVo, null, cmds); - return sendCommandsToRouter(router, cmds); - } - }); - } - - @Override @ActionEvent(eventType = EventTypes.EVENT_ROUTER_STOP, eventDescription = "stopping router Vm", async = true) + @Override public VirtualRouter stopRouter(final long routerId, final boolean forced) throws ResourceUnavailableException, ConcurrentOperationException { final CallContext context = CallContext.current(); final Account account = context.getCallingAccount(); @@ -2478,45 +2413,6 @@ Configurable, StateListener<State, VirtualMachine.Event, VirtualMachine> { return false; } - @Override - public boolean applyDhcpEntry(final Network network, final NicProfile nic, final VirtualMachineProfile profile, final DeployDestination dest, - final List<DomainRouterVO> routers) throws ResourceUnavailableException { - if (s_logger.isTraceEnabled()) { - s_logger.trace("applyDhcpEntry(" + network.getCidr() + ", " + nic.getMacAddress() + ", " + profile.getUuid() + ", " + dest.getHost() + ", " + routers + ")"); - } - final UserVmVO vm = _userVmDao.findById(profile.getId()); - _userVmDao.loadDetails(vm); - - final VirtualMachineProfile updatedProfile = profile; - final boolean isZoneBasic = dest.getDataCenter().getNetworkType() == NetworkType.Basic; - final Long podId = isZoneBasic ? dest.getPod().getId() : null; - - boolean podLevelException = false; - // for user vm in Basic zone we should try to re-deploy vm in a diff pod - // if it fails to deploy in original pod; so throwing exception with Pod - // scope - if (isZoneBasic && podId != null && updatedProfile.getVirtualMachine().getType() == VirtualMachine.Type.User && network.getTrafficType() == TrafficType.Guest - && network.getGuestType() == Network.GuestType.Shared) { - podLevelException = true; - } - - return applyRules(network, routers, "dhcp entry", podLevelException, podId, true, new RuleApplier() { - @Override - public boolean execute(final Network network, final VirtualRouter router) throws ResourceUnavailableException { - // for basic zone, send dhcp/dns information to all routers in - // the basic network only when _dnsBasicZoneUpdates is set to - // "all" value - final Commands cmds = new Commands(Command.OnError.Stop); - if (!(isZoneBasic && router.getPodIdToDeployIn().longValue() != podId.longValue() && _dnsBasicZoneUpdates.equalsIgnoreCase("pod"))) { - final NicVO nicVo = _nicDao.findById(nic.getId()); - createDhcpEntryCommand(router, vm, nicVo, cmds); - return sendCommandsToRouter(router, cmds); - } - return true; - } - }); - } - private void createDeleteIpAliasCommand(final DomainRouterVO router, final List<IpAliasTO> deleteIpAliasTOs, final List<IpAliasTO> createIpAliasTos, final long networkId, final Commands cmds) { final String routerip = getRouterIpInNetwork(networkId, router.getId()); @@ -2561,42 +2457,6 @@ Configurable, StateListener<State, VirtualMachine.Event, VirtualMachine> { return defaultNic; } - @Override - public boolean applyUserData(final Network network, final NicProfile nic, final VirtualMachineProfile profile, final DeployDestination dest, final List<DomainRouterVO> routers) - throws ResourceUnavailableException { - final UserVmVO vm = _userVmDao.findById(profile.getId()); - _userVmDao.loadDetails(vm); - - final VirtualMachineProfile updatedProfile = profile; - final boolean isZoneBasic = dest.getDataCenter().getNetworkType() == NetworkType.Basic; - final Long podId = isZoneBasic ? dest.getPod().getId() : null; - - boolean podLevelException = false; - // for user vm in Basic zone we should try to re-deploy vm in a diff pod - // if it fails to deploy in original pod; so throwing exception with Pod - // scope - if (isZoneBasic && podId != null && updatedProfile.getVirtualMachine().getType() == VirtualMachine.Type.User && network.getTrafficType() == TrafficType.Guest - && network.getGuestType() == Network.GuestType.Shared) { - podLevelException = true; - } - - return applyRules(network, routers, "userdata and password entry", podLevelException, podId, false, new RuleApplier() { - @Override - public boolean execute(final Network network, final VirtualRouter router) throws ResourceUnavailableException { - // for basic zone, send vm data/password information only to the - // router in the same pod - final Commands cmds = new Commands(Command.OnError.Stop); - if (!(isZoneBasic && router.getPodIdToDeployIn().longValue() != podId.longValue())) { - final NicVO nicVo = _nicDao.findById(nic.getId()); - createPasswordCommand(router, updatedProfile, nicVo, cmds); - createVmDataCommand(router, vm, nicVo, vm.getDetail("SSH.PublicKey"), cmds); - return sendCommandsToRouter(router, cmds); - } - return true; - } - }); - } - protected void createApplyVpnUsersCommand(final List<? extends VpnUser> users, final VirtualRouter router, final Commands cmds) { final List<VpnUser> addUsers = new ArrayList<VpnUser>(); final List<VpnUser> removeUsers = new ArrayList<VpnUser>(); @@ -3179,91 +3039,6 @@ Configurable, StateListener<State, VirtualMachine.Event, VirtualMachine> { } } - @Override - public boolean associatePublicIP(final Network network, final List<? extends PublicIpAddress> ipAddress, final List<? extends VirtualRouter> routers) - throws ResourceUnavailableException { - if (ipAddress == null || ipAddress.isEmpty()) { - s_logger.debug("No ip association rules to be applied for network " + network.getId()); - return true; - } - return applyRules(network, routers, "ip association", false, null, false, new RuleApplier() { - @Override - public boolean execute(final Network network, final VirtualRouter router) throws ResourceUnavailableException { - final Commands cmds = new Commands(Command.OnError.Continue); - createAssociateIPCommands(router, ipAddress, cmds, 0); - return sendCommandsToRouter(router, cmds); - } - }); - } - - @Override - public boolean applyFirewallRules(final Network network, final List<? extends FirewallRule> rules, final List<? extends VirtualRouter> routers) - throws ResourceUnavailableException { - if (rules == null || rules.isEmpty()) { - s_logger.debug("No firewall rules to be applied for network " + network.getId()); - return true; - } - return applyRules(network, routers, "firewall rules", false, null, false, new RuleApplier() { - @Override - public boolean execute(final Network network, final VirtualRouter router) throws ResourceUnavailableException { - if (rules.get(0).getPurpose() == Purpose.LoadBalancing) { - // for load balancer we have to resend all lb rules for the - // network - final List<LoadBalancerVO> lbs = _loadBalancerDao.listByNetworkIdAndScheme(network.getId(), Scheme.Public); - final List<LoadBalancingRule> lbRules = new ArrayList<LoadBalancingRule>(); - for (final LoadBalancerVO lb : lbs) { - final List<LbDestination> dstList = _lbMgr.getExistingDestinations(lb.getId()); - final List<LbStickinessPolicy> policyList = _lbMgr.getStickinessPolicies(lb.getId()); - final List<LbHealthCheckPolicy> hcPolicyList = _lbMgr.getHealthCheckPolicies(lb.getId()); - final LbSslCert sslCert = _lbMgr.getLbSslCert(lb.getId()); - final Ip sourceIp = _networkModel.getPublicIpAddress(lb.getSourceIpAddressId()).getAddress(); - final LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList, policyList, hcPolicyList, sourceIp, sslCert, lb.getLbProtocol()); - - lbRules.add(loadBalancing); - } - return sendLBRules(router, lbRules, network.getId()); - } else if (rules.get(0).getPurpose() == Purpose.PortForwarding) { - return sendPortForwardingRules(router, (List<PortForwardingRule>) rules, network.getId()); - } else if (rules.get(0).getPurpose() == Purpose.StaticNat) { - return sendStaticNatRules(router, (List<StaticNatRule>) rules, network.getId()); - } else if (rules.get(0).getPurpose() == Purpose.Firewall) { - return sendFirewallRules(router, (List<FirewallRule>) rules, network.getId()); - } else { - s_logger.warn("Unable to apply rules of purpose: " + rules.get(0).getPurpose()); - return false; - } - } - }); - } - - @Override - public boolean applyLoadBalancingRules(final Network network, final List<? extends LoadBalancingRule> rules, final List<? extends VirtualRouter> routers) - throws ResourceUnavailableException { - if (rules == null || rules.isEmpty()) { - s_logger.debug("No lb rules to be applied for network " + network.getId()); - return true; - } - return applyRules(network, routers, "loadbalancing rules", false, null, false, new RuleApplier() { - @Override - public boolean execute(final Network network, final VirtualRouter router) throws ResourceUnavailableException { - // for load balancer we have to resend all lb rules for the - // network - final List<LoadBalancerVO> lbs = _loadBalancerDao.listByNetworkIdAndScheme(network.getId(), Scheme.Public); - final List<LoadBalancingRule> lbRules = new ArrayList<LoadBalancingRule>(); - for (final LoadBalancerVO lb : lbs) { - final List<LbDestination> dstList = _lbMgr.getExistingDestinations(lb.getId()); - final List<LbStickinessPolicy> policyList = _lbMgr.getStickinessPolicies(lb.getId()); - final List<LbHealthCheckPolicy> hcPolicyList = _lbMgr.getHealthCheckPolicies(lb.getId()); - final LbSslCert sslCert = _lbMgr.getLbSslCert(lb.getId()); - final Ip sourceIp = _networkModel.getPublicIpAddress(lb.getSourceIpAddressId()).getAddress(); - final LoadBalancingRule loadBalancing = new LoadBalancingRule(lb, dstList, policyList, hcPolicyList, sourceIp, sslCert, lb.getLbProtocol()); - lbRules.add(loadBalancing); - } - return sendLBRules(router, lbRules, network.getId()); - } - }); - } - protected boolean sendLBRules(final VirtualRouter router, final List<LoadBalancingRule> rules, final long guestNetworkId) throws ResourceUnavailableException { final Commands cmds = new Commands(Command.OnError.Continue); createApplyLoadBalancingRulesCommands(rules, router, cmds, guestNetworkId); @@ -3433,20 +3208,6 @@ Configurable, StateListener<State, VirtualMachine.Event, VirtualMachine> { return result; } - @Override - public boolean applyStaticNats(final Network network, final List<? extends StaticNat> rules, final List<? extends VirtualRouter> routers) throws ResourceUnavailableException { - if (rules == null || rules.isEmpty()) { - s_logger.debug("No static nat rules to be applied for network " + network.getId()); - return true; - } - return applyRules(network, routers, "static nat rules", false, null, false, new RuleApplier() { - @Override - public boolean execute(final Network network, final VirtualRouter router) throws ResourceUnavailableException { - return applyStaticNat(router, rules, network.getId()); - } - }); - } - protected boolean applyStaticNat(final VirtualRouter router, final List<? extends StaticNat> rules, final long guestNetworkId) throws ResourceUnavailableException { final Commands cmds = new Commands(Command.OnError.Continue); createApplyStaticNatCommands(rules, router, cmds, guestNetworkId); @@ -3817,5 +3578,4 @@ Configurable, StateListener<State, VirtualMachine.Event, VirtualMachine> { public boolean completeAggregatedExecution(final Network network, final List<DomainRouterVO> routers) throws AgentUnavailableException { return aggregationExecution(Action.Finish, network, routers); } - } http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b97f2b05/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManager.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManager.java b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManager.java index ab94d02..db8a1dc 100644 --- a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManager.java +++ b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManager.java @@ -20,12 +20,10 @@ import java.util.List; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.ResourceUnavailableException; -import com.cloud.network.Network; import com.cloud.network.RemoteAccessVpn; import com.cloud.network.Site2SiteVpnConnection; import com.cloud.network.VpcVirtualNetworkApplianceService; import com.cloud.network.VpnUser; -import com.cloud.network.vpc.NetworkACLItem; import com.cloud.network.vpc.PrivateGateway; import com.cloud.network.vpc.StaticRouteProfile; import com.cloud.vm.DomainRouterVO; @@ -33,18 +31,6 @@ import com.cloud.vm.DomainRouterVO; public interface VpcVirtualNetworkApplianceManager extends VirtualNetworkApplianceManager, VpcVirtualNetworkApplianceService { /** - * - * @param network - * @param rules - * @param routers - * @param privateGateway - * @return - * @throws ResourceUnavailableException - */ - boolean applyNetworkACLs(Network network, List<? extends NetworkACLItem> rules, List<? extends VirtualRouter> routers, boolean privateGateway) - throws ResourceUnavailableException; - - /** * @param gateway * @param router TODO * @return http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b97f2b05/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java index 5635b78..d2f6f5d 100644 --- a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java +++ b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java @@ -23,7 +23,6 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.Map.Entry; import javax.ejb.Local; import javax.inject.Inject; @@ -62,7 +61,6 @@ import com.cloud.network.Network; import com.cloud.network.Network.Provider; import com.cloud.network.Network.Service; import com.cloud.network.Networks.BroadcastDomainType; -import com.cloud.network.Networks.IsolationType; import com.cloud.network.Networks.TrafficType; import com.cloud.network.PublicIpAddress; import com.cloud.network.RemoteAccessVpn; @@ -364,125 +362,6 @@ public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplian } @Override - public boolean associatePublicIP(final Network network, final List<? extends PublicIpAddress> ipAddress, final List<? extends VirtualRouter> routers) - throws ResourceUnavailableException { - if (ipAddress == null || ipAddress.isEmpty()) { - s_logger.debug("No ip association rules to be applied for network " + network.getId()); - return true; - } - - //only one router is supported in VPC now - VirtualRouter router = routers.get(0); - - if (router.getVpcId() == null) { - return super.associatePublicIP(network, ipAddress, routers); - } - - Pair<Map<String, PublicIpAddress>, Map<String, PublicIpAddress>> nicsToChange = getNicsToChangeOnRouter(ipAddress, router); - Map<String, PublicIpAddress> nicsToPlug = nicsToChange.first(); - Map<String, PublicIpAddress> nicsToUnplug = nicsToChange.second(); - - //1) Unplug the nics - for (Entry<String, PublicIpAddress> entry : nicsToUnplug.entrySet()) { - Network publicNtwk = null; - try { - publicNtwk = _networkModel.getNetwork(entry.getValue().getNetworkId()); - URI broadcastUri = BroadcastDomainType.Vlan.toUri(entry.getKey()); - _itMgr.removeVmFromNetwork(router, publicNtwk, broadcastUri); - } catch (ConcurrentOperationException e) { - s_logger.warn("Failed to remove router " + router + " from vlan " + entry.getKey() + " in public network " + publicNtwk + " due to ", e); - return false; - } - } - - Commands netUsagecmds = new Commands(Command.OnError.Continue); - VpcVO vpc = _vpcDao.findById(router.getVpcId()); - - //2) Plug the nics - for (String vlanTag : nicsToPlug.keySet()) { - PublicIpAddress ip = nicsToPlug.get(vlanTag); - //have to plug the nic(s) - NicProfile defaultNic = new NicProfile(); - if (ip.isSourceNat()) { - defaultNic.setDefaultNic(true); - } - defaultNic.setIp4Address(ip.getAddress().addr()); - defaultNic.setGateway(ip.getGateway()); - defaultNic.setNetmask(ip.getNetmask()); - defaultNic.setMacAddress(ip.getMacAddress()); - defaultNic.setBroadcastType(BroadcastDomainType.Vlan); - defaultNic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(ip.getVlanTag())); - defaultNic.setIsolationUri(IsolationType.Vlan.toUri(ip.getVlanTag())); - - NicProfile publicNic = null; - Network publicNtwk = null; - try { - publicNtwk = _networkModel.getNetwork(ip.getNetworkId()); - publicNic = _itMgr.addVmToNetwork(router, publicNtwk, defaultNic); - } catch (ConcurrentOperationException e) { - s_logger.warn("Failed to add router " + router + " to vlan " + vlanTag + " in public network " + publicNtwk + " due to ", e); - } catch (InsufficientCapacityException e) { - s_logger.warn("Failed to add router " + router + " to vlan " + vlanTag + " in public network " + publicNtwk + " due to ", e); - } finally { - if (publicNic == null) { - s_logger.warn("Failed to add router " + router + " to vlan " + vlanTag + " in public network " + publicNtwk); - return false; - } - } - //Create network usage commands. Send commands to router after IPAssoc - NetworkUsageCommand netUsageCmd = - new NetworkUsageCommand(router.getPrivateIpAddress(), router.getInstanceName(), true, defaultNic.getIp4Address(), vpc.getCidr()); - netUsagecmds.addCommand(netUsageCmd); - UserStatisticsVO stats = - _userStatsDao.findBy(router.getAccountId(), router.getDataCenterId(), publicNtwk.getId(), publicNic.getIp4Address(), router.getId(), router.getType() - .toString()); - if (stats == null) { - stats = - new UserStatisticsVO(router.getAccountId(), router.getDataCenterId(), publicNic.getIp4Address(), router.getId(), router.getType().toString(), - publicNtwk.getId()); - _userStatsDao.persist(stats); - } - } - - //3) apply the ips - boolean result = applyRules(network, routers, "vpc ip association", false, null, false, new RuleApplier() { - @Override - public boolean execute(final Network network, final VirtualRouter router) throws ResourceUnavailableException { - Commands cmds = new Commands(Command.OnError.Continue); - Map<String, String> vlanMacAddress = new HashMap<String, String>(); - List<PublicIpAddress> ipsToSend = new ArrayList<PublicIpAddress>(); - for (PublicIpAddress ipAddr : ipAddress) { - String broadcastURI = BroadcastDomainType.Vlan.toUri(ipAddr.getVlanTag()).toString(); - Nic nic = _nicDao.findByNetworkIdInstanceIdAndBroadcastUri(ipAddr.getNetworkId(), router.getId(), broadcastURI); - - String macAddress = null; - if (nic == null) { - if (ipAddr.getState() != IpAddress.State.Releasing) { - throw new CloudRuntimeException("Unable to find the nic in network " + ipAddr.getNetworkId() + " to apply the ip address " + ipAddr + " for"); - } - s_logger.debug("Not sending release for ip address " + ipAddr + " as its nic is already gone from VPC router " + router); - } else { - macAddress = nic.getMacAddress(); - vlanMacAddress.put(BroadcastDomainType.getValue(BroadcastDomainType.fromString(ipAddr.getVlanTag())), macAddress); - ipsToSend.add(ipAddr); - } - } - if (!ipsToSend.isEmpty()) { - createVpcAssociatePublicIPCommands(router, ipsToSend, cmds, vlanMacAddress); - return sendCommandsToRouter(router, cmds); - } else { - return true; - } - } - }); - if (result && netUsagecmds.size() > 0) { - //After successful ipassoc, send commands to router - sendCommandsToRouter(router, netUsagecmds); - } - return result; - } - - @Override public boolean finalizeVirtualMachineProfile(final VirtualMachineProfile profile, final DeployDestination dest, final ReservationContext context) { DomainRouterVO vr = _routerDao.findById(profile.getId()); @@ -518,21 +397,6 @@ public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplian return super.finalizeVirtualMachineProfile(profile, dest, context); } - @Override - public boolean applyNetworkACLs(final Network network, final List<? extends NetworkACLItem> rules, final List<? extends VirtualRouter> routers, final boolean isPrivateGateway) - throws ResourceUnavailableException { - if (rules == null || rules.isEmpty()) { - s_logger.debug("No network ACLs to be applied for network " + network.getId()); - return true; - } - return applyRules(network, routers, "network acls", false, null, false, new RuleApplier() { - @Override - public boolean execute(final Network network, final VirtualRouter router) throws ResourceUnavailableException { - return sendNetworkACLs(router, rules, network.getId(), isPrivateGateway); - } - }); - } - protected boolean sendNetworkACLs(final VirtualRouter router, final List<? extends NetworkACLItem> rules, final long guestNetworkId, final boolean isPrivateGateway) throws ResourceUnavailableException { Commands cmds = new Commands(Command.OnError.Continue); http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b97f2b05/server/src/com/cloud/network/rules/NetworkAclsRules.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/network/rules/NetworkAclsRules.java b/server/src/com/cloud/network/rules/NetworkAclsRules.java index 3680fc0..4c0c71a 100644 --- a/server/src/com/cloud/network/rules/NetworkAclsRules.java +++ b/server/src/com/cloud/network/rules/NetworkAclsRules.java @@ -17,32 +17,77 @@ package com.cloud.network.rules; +import java.net.URI; +import java.util.ArrayList; import java.util.List; import org.apache.cloudstack.network.topology.NetworkTopologyVisitor; +import com.cloud.agent.api.routing.NetworkElementCommand; +import com.cloud.agent.api.routing.SetNetworkACLCommand; +import com.cloud.agent.api.to.NetworkACLTO; +import com.cloud.agent.manager.Commands; +import com.cloud.dc.DataCenterVO; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.Network; +import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.network.router.VirtualRouter; import com.cloud.network.vpc.NetworkACLItem; +import com.cloud.network.vpc.VpcGateway; public class NetworkAclsRules extends RuleApplier { - private final List<? extends NetworkACLItem> rules; + private final List<? extends NetworkACLItem> _rules; + private final boolean _isPrivateGateway; - public NetworkAclsRules(final Network network, final List<? extends NetworkACLItem> rules) { + public NetworkAclsRules(final Network network, final List<? extends NetworkACLItem> rules, final boolean isPrivateGateway) { super(network); - this.rules = rules; + _rules = rules; + _isPrivateGateway = isPrivateGateway; } @Override public boolean accept(final NetworkTopologyVisitor visitor, final VirtualRouter router) throws ResourceUnavailableException { - this._router = router; + _router = router; return visitor.visit(this); } public List<? extends NetworkACLItem> getRules() { - return rules; + return _rules; + } + + public boolean isPrivateGateway() { + return _isPrivateGateway; + } + + public void createNetworkACLsCommands(final List<? extends NetworkACLItem> rules, final VirtualRouter router, final Commands cmds, final long guestNetworkId, final boolean privateGateway) { + List<NetworkACLTO> rulesTO = new ArrayList<NetworkACLTO>(); + String guestVlan = null; + Network guestNtwk = _networkDao.findById(guestNetworkId); + URI uri = guestNtwk.getBroadcastUri(); + if (uri != null) { + guestVlan = BroadcastDomainType.getValue(uri); + } + + if (rules != null) { + for (NetworkACLItem rule : rules) { + NetworkACLTO ruleTO = new NetworkACLTO(rule, guestVlan, rule.getTrafficType()); + rulesTO.add(ruleTO); + } + } + + SetNetworkACLCommand cmd = new SetNetworkACLCommand(rulesTO, _networkHelper.getNicTO(router, guestNetworkId, null)); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId())); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, _routerControlHelper.getRouterIpInNetwork(guestNetworkId, router.getId())); + cmd.setAccessDetail(NetworkElementCommand.GUEST_VLAN_TAG, guestVlan); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); + DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId()); + cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); + if (privateGateway) { + cmd.setAccessDetail(NetworkElementCommand.VPC_PRIVATE_GATEWAY, String.valueOf(VpcGateway.Type.Private)); + } + + cmds.addCommand(cmd); } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b97f2b05/server/src/com/cloud/network/rules/NicPlugInOutRules.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/network/rules/NicPlugInOutRules.java b/server/src/com/cloud/network/rules/NicPlugInOutRules.java new file mode 100644 index 0000000..f4be96f --- /dev/null +++ b/server/src/com/cloud/network/rules/NicPlugInOutRules.java @@ -0,0 +1,202 @@ +// 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. + +package com.cloud.network.rules; + +import java.net.URI; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.apache.cloudstack.network.topology.NetworkTopologyVisitor; +import org.apache.log4j.Logger; + +import com.cloud.agent.api.Command; +import com.cloud.agent.api.NetworkUsageCommand; +import com.cloud.agent.manager.Commands; +import com.cloud.exception.ConcurrentOperationException; +import com.cloud.exception.InsufficientCapacityException; +import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.IpAddress; +import com.cloud.network.Network; +import com.cloud.network.Networks.BroadcastDomainType; +import com.cloud.network.Networks.IsolationType; +import com.cloud.network.PublicIpAddress; +import com.cloud.network.router.VirtualRouter; +import com.cloud.network.vpc.VpcVO; +import com.cloud.user.UserStatisticsVO; +import com.cloud.utils.Pair; +import com.cloud.vm.Nic; +import com.cloud.vm.NicProfile; +import com.cloud.vm.NicVO; + +public class NicPlugInOutRules extends RuleApplier { + + private static final Logger s_logger = Logger.getLogger(NicPlugInOutRules.class); + + private final List<? extends PublicIpAddress> _ipAddresses; + + private Commands _netUsageCommands; + + public NicPlugInOutRules(final Network network, final List<? extends PublicIpAddress> ipAddresses) { + super(network); + _ipAddresses = ipAddresses; + } + + @Override + public boolean accept(final NetworkTopologyVisitor visitor, final VirtualRouter router) throws ResourceUnavailableException { + + Pair<Map<String, PublicIpAddress>, Map<String, PublicIpAddress>> nicsToChange = getNicsToChangeOnRouter(_ipAddresses, router); + Map<String, PublicIpAddress> nicsToPlug = nicsToChange.first(); + Map<String, PublicIpAddress> nicsToUnplug = nicsToChange.second(); + + //1) Unplug the nics + for (Entry<String, PublicIpAddress> entry : nicsToUnplug.entrySet()) { + Network publicNtwk = null; + try { + publicNtwk = _networkModel.getNetwork(entry.getValue().getNetworkId()); + URI broadcastUri = BroadcastDomainType.Vlan.toUri(entry.getKey()); + _itMgr.removeVmFromNetwork(router, publicNtwk, broadcastUri); + } catch (ConcurrentOperationException e) { + s_logger.warn("Failed to remove router " + router + " from vlan " + entry.getKey() + " in public network " + publicNtwk + " due to ", e); + return false; + } + } + + _netUsageCommands = new Commands(Command.OnError.Continue); + VpcVO vpc = _vpcDao.findById(router.getVpcId()); + + //2) Plug the nics + for (String vlanTag : nicsToPlug.keySet()) { + PublicIpAddress ip = nicsToPlug.get(vlanTag); + //have to plug the nic(s) + NicProfile defaultNic = new NicProfile(); + if (ip.isSourceNat()) { + defaultNic.setDefaultNic(true); + } + defaultNic.setIp4Address(ip.getAddress().addr()); + defaultNic.setGateway(ip.getGateway()); + defaultNic.setNetmask(ip.getNetmask()); + defaultNic.setMacAddress(ip.getMacAddress()); + defaultNic.setBroadcastType(BroadcastDomainType.Vlan); + defaultNic.setBroadcastUri(BroadcastDomainType.Vlan.toUri(ip.getVlanTag())); + defaultNic.setIsolationUri(IsolationType.Vlan.toUri(ip.getVlanTag())); + + NicProfile publicNic = null; + Network publicNtwk = null; + try { + publicNtwk = _networkModel.getNetwork(ip.getNetworkId()); + publicNic = _itMgr.addVmToNetwork(router, publicNtwk, defaultNic); + } catch (ConcurrentOperationException e) { + s_logger.warn("Failed to add router " + router + " to vlan " + vlanTag + " in public network " + publicNtwk + " due to ", e); + } catch (InsufficientCapacityException e) { + s_logger.warn("Failed to add router " + router + " to vlan " + vlanTag + " in public network " + publicNtwk + " due to ", e); + } finally { + if (publicNic == null) { + s_logger.warn("Failed to add router " + router + " to vlan " + vlanTag + " in public network " + publicNtwk); + return false; + } + } + //Create network usage commands. Send commands to router after IPAssoc + NetworkUsageCommand netUsageCmd = + new NetworkUsageCommand(router.getPrivateIpAddress(), router.getInstanceName(), true, defaultNic.getIp4Address(), vpc.getCidr()); + _netUsageCommands.addCommand(netUsageCmd); + UserStatisticsVO stats = + _userStatsDao.findBy(router.getAccountId(), router.getDataCenterId(), publicNtwk.getId(), publicNic.getIp4Address(), router.getId(), router.getType() + .toString()); + if (stats == null) { + stats = + new UserStatisticsVO(router.getAccountId(), router.getDataCenterId(), publicNic.getIp4Address(), router.getId(), router.getType().toString(), + publicNtwk.getId()); + _userStatsDao.persist(stats); + } + } + + // Let the IpAssociationRule call the visitor fot the NicPlugInOutRule + return true; + } + + public List<? extends PublicIpAddress> getIpAddresses() { + return _ipAddresses; + } + + public Commands getNetUsageCommands() { + return _netUsageCommands; + } + + private Pair<Map<String, PublicIpAddress>, Map<String, PublicIpAddress>> getNicsToChangeOnRouter(final List<? extends PublicIpAddress> publicIps, + final VirtualRouter router) { + //1) check which nics need to be plugged/unplugged and plug/unplug them + + Map<String, PublicIpAddress> nicsToPlug = new HashMap<String, PublicIpAddress>(); + Map<String, PublicIpAddress> nicsToUnplug = new HashMap<String, PublicIpAddress>(); + + //find out nics to unplug + for (PublicIpAddress ip : publicIps) { + long publicNtwkId = ip.getNetworkId(); + + //if ip is not associated to any network, and there are no firewall rules, release it on the backend + if (!_vpcMgr.isIpAllocatedToVpc(ip)) { + ip.setState(IpAddress.State.Releasing); + } + + if (ip.getState() == IpAddress.State.Releasing) { + Nic nic = _nicDao.findByIp4AddressAndNetworkIdAndInstanceId(publicNtwkId, router.getId(), ip.getAddress().addr()); + if (nic != null) { + nicsToUnplug.put(ip.getVlanTag(), ip); + s_logger.debug("Need to unplug the nic for ip=" + ip + "; vlan=" + ip.getVlanTag() + " in public network id =" + publicNtwkId); + } + } + } + + //find out nics to plug + for (PublicIpAddress ip : publicIps) { + URI broadcastUri = BroadcastDomainType.Vlan.toUri(ip.getVlanTag()); + long publicNtwkId = ip.getNetworkId(); + + //if ip is not associated to any network, and there are no firewall rules, release it on the backend + if (!_vpcMgr.isIpAllocatedToVpc(ip)) { + ip.setState(IpAddress.State.Releasing); + } + + if (ip.getState() == IpAddress.State.Allocated || ip.getState() == IpAddress.State.Allocating) { + //nic has to be plugged only when there are no nics for this vlan tag exist on VR + Nic nic = _nicDao.findByNetworkIdInstanceIdAndBroadcastUri(publicNtwkId, router.getId(), broadcastUri.toString()); + + if (nic == null && nicsToPlug.get(ip.getVlanTag()) == null) { + nicsToPlug.put(ip.getVlanTag(), ip); + s_logger.debug("Need to plug the nic for ip=" + ip + "; vlan=" + ip.getVlanTag() + " in public network id =" + publicNtwkId); + } else { + PublicIpAddress nicToUnplug = nicsToUnplug.get(ip.getVlanTag()); + if (nicToUnplug != null) { + NicVO nicVO = _nicDao.findByIp4AddressAndNetworkIdAndInstanceId(publicNtwkId, router.getId(), nicToUnplug.getAddress().addr()); + nicVO.setIp4Address(ip.getAddress().addr()); + _nicDao.update(nicVO.getId(), nicVO); + s_logger.debug("Updated the nic " + nicVO + " with the new ip address " + ip.getAddress().addr()); + nicsToUnplug.remove(ip.getVlanTag()); + } + } + } + } + + Pair<Map<String, PublicIpAddress>, Map<String, PublicIpAddress>> nicsToChange = + new Pair<Map<String, PublicIpAddress>, Map<String, PublicIpAddress>>(nicsToPlug, nicsToUnplug); + + return nicsToChange; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b97f2b05/server/src/com/cloud/network/rules/RuleApplier.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/network/rules/RuleApplier.java b/server/src/com/cloud/network/rules/RuleApplier.java index e101a5b..cc29461 100644 --- a/server/src/com/cloud/network/rules/RuleApplier.java +++ b/server/src/com/cloud/network/rules/RuleApplier.java @@ -34,11 +34,15 @@ import com.cloud.network.dao.LoadBalancerDao; import com.cloud.network.dao.NetworkDao; import com.cloud.network.lb.LoadBalancingRulesManager; import com.cloud.network.router.NEWVirtualNetworkApplianceManager; +import com.cloud.network.router.NetworkGeneralHelper; import com.cloud.network.router.RouterControlHelper; import com.cloud.network.router.VirtualRouter; +import com.cloud.network.vpc.VpcManager; +import com.cloud.network.vpc.dao.VpcDao; import com.cloud.offerings.dao.NetworkOfferingDao; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.dao.VMTemplateDao; +import com.cloud.user.dao.UserStatisticsDao; import com.cloud.uservm.UserVm; import com.cloud.utils.StringUtils; import com.cloud.vm.NicVO; @@ -77,6 +81,12 @@ public abstract class RuleApplier { protected FirewallRulesDao _rulesDao; + protected UserStatisticsDao _userStatsDao; + + protected VpcDao _vpcDao; + + protected VpcManager _vpcMgr; + protected VirtualMachineManager _itMgr; protected Network _network; @@ -85,8 +95,10 @@ public abstract class RuleApplier { protected RouterControlHelper _routerControlHelper; + protected NetworkGeneralHelper _networkHelper; + public RuleApplier(final Network network) { - this._network = network; + _network = network; } public abstract boolean accept(NetworkTopologyVisitor visitor, VirtualRouter router) throws ResourceUnavailableException; http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b97f2b05/server/src/com/cloud/network/rules/SshKeyToRouterRules.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/network/rules/SshKeyToRouterRules.java b/server/src/com/cloud/network/rules/SshKeyToRouterRules.java index 14acaba..c88827a 100644 --- a/server/src/com/cloud/network/rules/SshKeyToRouterRules.java +++ b/server/src/com/cloud/network/rules/SshKeyToRouterRules.java @@ -80,7 +80,6 @@ public class SshKeyToRouterRules extends RuleApplier { cmds.addCommand("password", cmd); } - } public VirtualMachineProfile getProfile() { http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b97f2b05/server/src/com/cloud/network/rules/VirtualNetworkApplianceFactory.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/network/rules/VirtualNetworkApplianceFactory.java b/server/src/com/cloud/network/rules/VirtualNetworkApplianceFactory.java index f38ea4f..32f61ce 100644 --- a/server/src/com/cloud/network/rules/VirtualNetworkApplianceFactory.java +++ b/server/src/com/cloud/network/rules/VirtualNetworkApplianceFactory.java @@ -33,10 +33,15 @@ import com.cloud.network.dao.LoadBalancerDao; import com.cloud.network.dao.NetworkDao; import com.cloud.network.lb.LoadBalancingRule; import com.cloud.network.lb.LoadBalancingRulesManager; +import com.cloud.network.router.NetworkGeneralHelper; import com.cloud.network.router.RouterControlHelper; +import com.cloud.network.vpc.NetworkACLItem; +import com.cloud.network.vpc.VpcManager; +import com.cloud.network.vpc.dao.VpcDao; import com.cloud.offerings.dao.NetworkOfferingDao; import com.cloud.service.dao.ServiceOfferingDao; import com.cloud.storage.dao.VMTemplateDao; +import com.cloud.user.dao.UserStatisticsDao; import com.cloud.vm.NicProfile; import com.cloud.vm.VirtualMachineManager; import com.cloud.vm.VirtualMachineProfile; @@ -74,6 +79,15 @@ public class VirtualNetworkApplianceFactory { protected UserVmDao _userVmDao; @Inject + protected UserStatisticsDao _userStatsDao; + + @Inject + protected VpcDao _vpcDao; + + @Inject + protected VpcManager _vpcMgr; + + @Inject protected ServiceOfferingDao _serviceOfferingDao; @Inject @@ -91,6 +105,9 @@ public class VirtualNetworkApplianceFactory { @Inject protected RouterControlHelper _routerControlHelper; + @Inject + protected NetworkGeneralHelper _networkHelper; + public LoadBalancingRules createLoadBalancingRules(final Network network, final List<LoadBalancingRule> rules) { LoadBalancingRules lbRules = new LoadBalancingRules(network, rules); @@ -141,6 +158,16 @@ public class VirtualNetworkApplianceFactory { return ipAssociationRules; } + public VpcIpAssociationRules createVpcIpAssociationRules(final Network network, final List<? extends PublicIpAddress> ipAddresses, final NicPlugInOutRules nicPlugInOutRules) { + VpcIpAssociationRules ipAssociationRules = new VpcIpAssociationRules(network, ipAddresses, nicPlugInOutRules); + + initBeans(ipAssociationRules); + + ipAssociationRules._networkDao = _networkDao; + + return ipAssociationRules; + } + public VpnRules createVpnRules(final Network network, final List<? extends VpnUser> users) { VpnRules vpnRules = new VpnRules(network, users); @@ -205,4 +232,26 @@ public class VirtualNetworkApplianceFactory { return dhcpRules; } + + public NicPlugInOutRules createNicPluInOutRules(final Network network, final List<? extends PublicIpAddress> ipAddresses) { + NicPlugInOutRules nicPlug = new NicPlugInOutRules(network, ipAddresses); + + initBeans(nicPlug); + + nicPlug._vpcDao = _vpcDao; + nicPlug._userStatsDao = _userStatsDao; + nicPlug._vpcMgr = _vpcMgr; + + return nicPlug; + } + + public NetworkAclsRules createNetworkAclRules(final Network network, final List<? extends NetworkACLItem> rules, final boolean isPrivateGateway) { + NetworkAclsRules networkAclsRules = new NetworkAclsRules(network, rules, isPrivateGateway); + + initBeans(networkAclsRules); + + networkAclsRules._networkHelper = _networkHelper; + + return networkAclsRules; + } } \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cloudstack/blob/b97f2b05/server/src/com/cloud/network/rules/VpcIpAssociationRules.java ---------------------------------------------------------------------- diff --git a/server/src/com/cloud/network/rules/VpcIpAssociationRules.java b/server/src/com/cloud/network/rules/VpcIpAssociationRules.java index 5c0d6fe..bcda360 100644 --- a/server/src/com/cloud/network/rules/VpcIpAssociationRules.java +++ b/server/src/com/cloud/network/rules/VpcIpAssociationRules.java @@ -17,32 +17,158 @@ package com.cloud.network.rules; +import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import org.apache.cloudstack.network.topology.NetworkTopologyVisitor; +import org.apache.log4j.Logger; +import com.cloud.agent.api.routing.IpAssocVpcCommand; +import com.cloud.agent.api.routing.NetworkElementCommand; +import com.cloud.agent.api.routing.SetSourceNatCommand; +import com.cloud.agent.api.to.IpAddressTO; +import com.cloud.agent.manager.Commands; +import com.cloud.dc.DataCenterVO; import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.IpAddress; import com.cloud.network.Network; +import com.cloud.network.Networks.BroadcastDomainType; import com.cloud.network.PublicIpAddress; import com.cloud.network.router.VirtualRouter; +import com.cloud.utils.Pair; +import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.vm.Nic; public class VpcIpAssociationRules extends RuleApplier { + private static final Logger s_logger = Logger.getLogger(VpcIpAssociationRules.class); + private final List<? extends PublicIpAddress> _ipAddresses; - public VpcIpAssociationRules(final Network network, final List<? extends PublicIpAddress> ipAddresses) { + private final NicPlugInOutRules _nicPlugInOutRules; + + private Map<String, String> _vlanMacAddress; + + private List<PublicIpAddress> _ipsToSend; + + public VpcIpAssociationRules(final Network network, final List<? extends PublicIpAddress> ipAddresses, final NicPlugInOutRules nicPlugInOutRules) { super(network); _ipAddresses = ipAddresses; + _nicPlugInOutRules = nicPlugInOutRules; } @Override public boolean accept(final NetworkTopologyVisitor visitor, final VirtualRouter router) throws ResourceUnavailableException { _router = router; + _vlanMacAddress = new HashMap<String, String>(); + _ipsToSend = new ArrayList<PublicIpAddress>(); + + for (PublicIpAddress ipAddr : _ipAddresses) { + String broadcastURI = BroadcastDomainType.Vlan.toUri(ipAddr.getVlanTag()).toString(); + Nic nic = _nicDao.findByNetworkIdInstanceIdAndBroadcastUri(ipAddr.getNetworkId(), router.getId(), broadcastURI); + + String macAddress = null; + if (nic == null) { + if (ipAddr.getState() != IpAddress.State.Releasing) { + throw new CloudRuntimeException("Unable to find the nic in network " + ipAddr.getNetworkId() + " to apply the ip address " + ipAddr + " for"); + } + s_logger.debug("Not sending release for ip address " + ipAddr + " as its nic is already gone from VPC router " + router); + } else { + macAddress = nic.getMacAddress(); + _vlanMacAddress.put(BroadcastDomainType.getValue(BroadcastDomainType.fromString(ipAddr.getVlanTag())), macAddress); + _ipsToSend.add(ipAddr); + } + } + return visitor.visit(this); } public List<? extends PublicIpAddress> getIpAddresses() { return _ipAddresses; } + + public NicPlugInOutRules getNicPlugInOutRules() { + return _nicPlugInOutRules; + } + + public Map<String, String> getVlanMacAddress() { + return _vlanMacAddress; + } + + public List<PublicIpAddress> getIpsToSend() { + return _ipsToSend; + } + + public void createVpcAssociatePublicIPCommands(final VirtualRouter router, final List<? extends PublicIpAddress> ips, final Commands cmds, + final Map<String, String> vlanMacAddress) { + + Pair<IpAddressTO, Long> sourceNatIpAdd = null; + Boolean addSourceNat = null; + // Ensure that in multiple vlans case we first send all ip addresses of vlan1, then all ip addresses of vlan2, etc.. + Map<String, ArrayList<PublicIpAddress>> vlanIpMap = new HashMap<String, ArrayList<PublicIpAddress>>(); + for (final PublicIpAddress ipAddress : ips) { + String vlanTag = ipAddress.getVlanTag(); + ArrayList<PublicIpAddress> ipList = vlanIpMap.get(vlanTag); + if (ipList == null) { + ipList = new ArrayList<PublicIpAddress>(); + } + //VR doesn't support release for sourceNat IP address; so reset the state + if (ipAddress.isSourceNat() && ipAddress.getState() == IpAddress.State.Releasing) { + ipAddress.setState(IpAddress.State.Allocated); + } + ipList.add(ipAddress); + vlanIpMap.put(vlanTag, ipList); + } + + for (Map.Entry<String, ArrayList<PublicIpAddress>> vlanAndIp : vlanIpMap.entrySet()) { + List<PublicIpAddress> ipAddrList = vlanAndIp.getValue(); + + // Get network rate - required for IpAssoc + Integer networkRate = _networkModel.getNetworkRate(ipAddrList.get(0).getNetworkId(), router.getId()); + Network network = _networkModel.getNetwork(ipAddrList.get(0).getNetworkId()); + + IpAddressTO[] ipsToSend = new IpAddressTO[ipAddrList.size()]; + int i = 0; + + for (final PublicIpAddress ipAddr : ipAddrList) { + boolean add = (ipAddr.getState() == IpAddress.State.Releasing ? false : true); + + String macAddress = vlanMacAddress.get(BroadcastDomainType.getValue(BroadcastDomainType.fromString(ipAddr.getVlanTag()))); + + IpAddressTO ip = + new IpAddressTO(ipAddr.getAccountId(), ipAddr.getAddress().addr(), add, false, ipAddr.isSourceNat(), ipAddr.getVlanTag(), ipAddr.getGateway(), + ipAddr.getNetmask(), macAddress, networkRate, ipAddr.isOneToOneNat()); + + ip.setTrafficType(network.getTrafficType()); + ip.setNetworkName(_networkModel.getNetworkTag(router.getHypervisorType(), network)); + ipsToSend[i++] = ip; + if (ipAddr.isSourceNat()) { + sourceNatIpAdd = new Pair<IpAddressTO, Long>(ip, ipAddr.getNetworkId()); + addSourceNat = add; + } + } + IpAssocVpcCommand cmd = new IpAssocVpcCommand(ipsToSend); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId())); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, _routerControlHelper.getRouterIpInNetwork(ipAddrList.get(0).getNetworkId(), router.getId())); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); + DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId()); + cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); + + cmds.addCommand("IPAssocVpcCommand", cmd); + } + + //set source nat ip + if (sourceNatIpAdd != null) { + IpAddressTO sourceNatIp = sourceNatIpAdd.first(); + SetSourceNatCommand cmd = new SetSourceNatCommand(sourceNatIp, addSourceNat); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId())); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); + DataCenterVO dcVo = _dcDao.findById(router.getDataCenterId()); + cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); + cmds.addCommand("SetSourceNatCommand", cmd); + } + } } \ No newline at end of file