diff --git a/build/replace.properties b/build/replace.properties index 0e24f684211..792fe32a394 100644 --- a/build/replace.properties +++ b/build/replace.properties @@ -20,7 +20,7 @@ DBPW=cloud DBROOTPW= MSLOG=vmops.log APISERVERLOG=api.log -DBHOST=localhost +DBHOST=178.237.34.126 AGENTLOGDIR=logs AGENTLOG=logs/agent.log MSMNTDIR=/mnt diff --git a/server/src/com/cloud/network/element/VirtualRouterElement.java b/server/src/com/cloud/network/element/VirtualRouterElement.java index 8ac3d230ed1..1e112a1ef96 100755 --- a/server/src/com/cloud/network/element/VirtualRouterElement.java +++ b/server/src/com/cloud/network/element/VirtualRouterElement.java @@ -246,25 +246,28 @@ NetworkMigrationResponder, AggregatedCommandExecutor { } @Override - public boolean applyFWRules(final Network config, final List rules) throws ResourceUnavailableException { - if (canHandle(config, Service.Firewall)) { - List routers = _routerDao.listByNetworkAndRole(config.getId(), Role.VIRTUAL_ROUTER); + public boolean applyFWRules(final Network network, final List rules) throws ResourceUnavailableException { + if (canHandle(network, Service.Firewall)) { + List 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; } if (rules != null && rules.size() == 1) { // for VR no need to add default egress rule to DENY traffic - if (rules.get(0).getTrafficType() == FirewallRule.TrafficType.Egress && rules.get(0).getType() == FirewallRule.FirewallRuleType.System && - !_networkMdl.getNetworkEgressDefaultPolicy(config.getId())) { + if (rules.get(0).getTrafficType() == FirewallRule.TrafficType.Egress && rules.get(0).getType() == FirewallRule.FirewallRuleType.System + && !_networkMdl.getNetworkEgressDefaultPolicy(network.getId())) { return true; } } - if (!_routerMgr.applyFirewallRules(config, rules, routers)) { - throw new CloudRuntimeException("Failed to apply firewall rules in network " + config.getId()); + DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId()); + NetworkTopology networkTopology = NetworkTopologyContext.getInstance().retrieveNetworkTopology(dcVO); + + if (!networkTopology.applyFirewallRules(network, rules, routers)) { + throw new CloudRuntimeException("Failed to apply firewall rules in network " + network.getId()); } else { return true; } diff --git a/server/src/com/cloud/network/rules/FirewallRules.java b/server/src/com/cloud/network/rules/FirewallRules.java index 7dd51ebb38b..64b36edebdf 100644 --- a/server/src/com/cloud/network/rules/FirewallRules.java +++ b/server/src/com/cloud/network/rules/FirewallRules.java @@ -20,36 +20,42 @@ package com.cloud.network.rules; import java.util.ArrayList; import java.util.List; -import javax.inject.Inject; - +import com.cloud.agent.api.routing.LoadBalancerConfigCommand; +import com.cloud.agent.api.routing.NetworkElementCommand; +import com.cloud.agent.api.routing.SetFirewallRulesCommand; +import com.cloud.agent.api.routing.SetPortForwardingRulesCommand; +import com.cloud.agent.api.routing.SetPortForwardingRulesVpcCommand; +import com.cloud.agent.api.routing.SetStaticNatRulesCommand; +import com.cloud.agent.api.to.FirewallRuleTO; +import com.cloud.agent.api.to.LoadBalancerTO; +import com.cloud.agent.api.to.PortForwardingRuleTO; +import com.cloud.agent.api.to.StaticNatRuleTO; +import com.cloud.agent.manager.Commands; +import com.cloud.configuration.Config; +import com.cloud.dc.DataCenterVO; import com.cloud.exception.ResourceUnavailableException; +import com.cloud.network.IpAddress; import com.cloud.network.Network; -import com.cloud.network.NetworkModel; -import com.cloud.network.dao.LoadBalancerDao; import com.cloud.network.dao.LoadBalancerVO; +import com.cloud.network.dao.NetworkVO; import com.cloud.network.lb.LoadBalancingRule; import com.cloud.network.lb.LoadBalancingRule.LbDestination; import com.cloud.network.lb.LoadBalancingRule.LbHealthCheckPolicy; import com.cloud.network.lb.LoadBalancingRule.LbSslCert; import com.cloud.network.lb.LoadBalancingRule.LbStickinessPolicy; -import com.cloud.network.lb.LoadBalancingRulesManager; import com.cloud.network.router.VirtualRouter; import com.cloud.network.rules.FirewallRule.Purpose; import com.cloud.network.rules.LoadBalancerContainer.Scheme; import com.cloud.network.topology.NetworkTopologyVisitor; +import com.cloud.offering.NetworkOffering; +import com.cloud.offerings.NetworkOfferingVO; import com.cloud.utils.net.Ip; +import com.cloud.vm.DomainRouterVO; +import com.cloud.vm.Nic; +import com.cloud.vm.NicProfile; public class FirewallRules extends RuleApplier { - @Inject - NetworkModel _networkModel; - - @Inject - LoadBalancingRulesManager _lbMgr; - - @Inject - LoadBalancerDao _loadBalancerDao; - private final List rules; private List loadbalancingRules; @@ -68,14 +74,14 @@ public class FirewallRules extends RuleApplier { if (purpose == Purpose.LoadBalancing) { // for load balancer we have to resend all lb rules for the network - final List lbs = _loadBalancerDao.listByNetworkIdAndScheme(network.getId(), Scheme.Public); + final List lbs = loadBalancerDao.listByNetworkIdAndScheme(network.getId(), Scheme.Public); loadbalancingRules = new ArrayList(); for (final LoadBalancerVO lb : lbs) { - final List dstList = _lbMgr.getExistingDestinations(lb.getId()); - final List policyList = _lbMgr.getStickinessPolicies(lb.getId()); - final List hcPolicyList = _lbMgr.getHealthCheckPolicies(lb.getId()); - final LbSslCert sslCert = _lbMgr.getLbSslCert(lb.getId()); - final Ip sourceIp = _networkModel.getPublicIpAddress(lb.getSourceIpAddressId()).getAddress(); + final List dstList = lbMgr.getExistingDestinations(lb.getId()); + final List policyList = lbMgr.getStickinessPolicies(lb.getId()); + final List 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()); loadbalancingRules.add(loadBalancing); @@ -96,4 +102,150 @@ public class FirewallRules extends RuleApplier { public Purpose getPurpose() { return purpose; } + + public void createApplyLoadBalancingRulesCommands(final List rules, final VirtualRouter router, final Commands cmds, final long guestNetworkId) { + + final LoadBalancerTO[] lbs = new LoadBalancerTO[rules.size()]; + int i = 0; + // We don't support VR to be inline currently + final boolean inline = false; + for (final LoadBalancingRule rule : rules) { + final boolean revoked = (rule.getState().equals(FirewallRule.State.Revoke)); + final String protocol = rule.getProtocol(); + final String algorithm = rule.getAlgorithm(); + final String uuid = rule.getUuid(); + + final String srcIp = rule.getSourceIp().addr(); + final int srcPort = rule.getSourcePortStart(); + final List destinations = rule.getDestinations(); + final List stickinessPolicies = rule.getStickinessPolicies(); + final LoadBalancerTO lb = new LoadBalancerTO(uuid, srcIp, srcPort, protocol, algorithm, revoked, false, inline, destinations, stickinessPolicies); + lbs[i++] = lb; + } + String routerPublicIp = null; + + if (router instanceof DomainRouterVO) { + final DomainRouterVO domr = routerDao.findById(router.getId()); + routerPublicIp = domr.getPublicIpAddress(); + } + + final Network guestNetwork = networkModel.getNetwork(guestNetworkId); + final Nic nic = nicDao.findByNtwkIdAndInstanceId(guestNetwork.getId(), router.getId()); + final NicProfile nicProfile = + new NicProfile(nic, guestNetwork, nic.getBroadcastUri(), nic.getIsolationUri(), networkModel.getNetworkRate(guestNetwork.getId(), router.getId()), + networkModel.isSecurityGroupSupportedInNetwork(guestNetwork), networkModel.getNetworkTag(router.getHypervisorType(), guestNetwork)); + final NetworkOffering offering = networkOfferingDao.findById(guestNetwork.getNetworkOfferingId()); + String maxconn = null; + if (offering.getConcurrentConnections() == null) { + maxconn = configDao.getValue(Config.NetworkLBHaproxyMaxConn.key()); + } else { + maxconn = offering.getConcurrentConnections().toString(); + } + + final LoadBalancerConfigCommand cmd = + new LoadBalancerConfigCommand(lbs, routerPublicIp, routerControlHelper.getRouterIpInNetwork(guestNetworkId, router.getId()), router.getPrivateIpAddress(), itMgr.toNicTO( + nicProfile, router.getHypervisorType()), router.getVpcId(), maxconn, offering.isKeepAliveEnabled()); + + cmd.lbStatsVisibility = configDao.getValue(Config.NetworkLBHaproxyStatsVisbility.key()); + cmd.lbStatsUri = configDao.getValue(Config.NetworkLBHaproxyStatsUri.key()); + cmd.lbStatsAuth = configDao.getValue(Config.NetworkLBHaproxyStatsAuth.key()); + cmd.lbStatsPort = configDao.getValue(Config.NetworkLBHaproxyStatsPort.key()); + + cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, routerControlHelper.getRouterControlIp(router.getId())); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, routerControlHelper.getRouterIpInNetwork(guestNetworkId, router.getId())); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); + final DataCenterVO dcVo = dcDao.findById(router.getDataCenterId()); + cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); + cmds.addCommand(cmd); + + } + + public void createApplyPortForwardingRulesCommands(final List rules, final VirtualRouter router, final Commands cmds, final long guestNetworkId) { + List rulesTO = new ArrayList(); + if (rules != null) { + for (final PortForwardingRule rule : rules) { + final IpAddress sourceIp = networkModel.getIp(rule.getSourceIpAddressId()); + final PortForwardingRuleTO ruleTO = new PortForwardingRuleTO(rule, null, sourceIp.getAddress().addr()); + rulesTO.add(ruleTO); + } + } + + SetPortForwardingRulesCommand cmd = null; + + if (router.getVpcId() != null) { + cmd = new SetPortForwardingRulesVpcCommand(rulesTO); + } else { + cmd = new SetPortForwardingRulesCommand(rulesTO); + } + + cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, routerControlHelper.getRouterControlIp(router.getId())); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, routerControlHelper.getRouterIpInNetwork(guestNetworkId, router.getId())); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); + final DataCenterVO dcVo = dcDao.findById(router.getDataCenterId()); + cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); + + cmds.addCommand(cmd); + } + + public void createApplyStaticNatRulesCommands(final List rules, final VirtualRouter router, final Commands cmds, final long guestNetworkId) { + List rulesTO = new ArrayList(); + if (rules != null) { + for (final StaticNatRule rule : rules) { + final IpAddress sourceIp = networkModel.getIp(rule.getSourceIpAddressId()); + final StaticNatRuleTO ruleTO = new StaticNatRuleTO(rule, null, sourceIp.getAddress().addr(), rule.getDestIpAddress()); + rulesTO.add(ruleTO); + } + } + + final SetStaticNatRulesCommand cmd = new SetStaticNatRulesCommand(rulesTO, router.getVpcId()); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, routerControlHelper.getRouterControlIp(router.getId())); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, routerControlHelper.getRouterIpInNetwork(guestNetworkId, router.getId())); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); + final DataCenterVO dcVo = dcDao.findById(router.getDataCenterId()); + cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); + cmds.addCommand(cmd); + } + + public void createApplyFirewallRulesCommands(final List rules, final VirtualRouter router, final Commands cmds, final long guestNetworkId) { + List rulesTO = new ArrayList(); + String systemRule = null; + Boolean defaultEgressPolicy = false; + if (rules != null) { + if (rules.size() > 0) { + if (rules.get(0).getTrafficType() == FirewallRule.TrafficType.Egress && rules.get(0).getType() == FirewallRule.FirewallRuleType.System) { + systemRule = String.valueOf(FirewallRule.FirewallRuleType.System); + } + } + for (final FirewallRule rule : rules) { + rulesDao.loadSourceCidrs((FirewallRuleVO)rule); + final FirewallRule.TrafficType traffictype = rule.getTrafficType(); + if (traffictype == FirewallRule.TrafficType.Ingress) { + final IpAddress sourceIp = networkModel.getIp(rule.getSourceIpAddressId()); + final FirewallRuleTO ruleTO = new FirewallRuleTO(rule, null, sourceIp.getAddress().addr(), Purpose.Firewall, traffictype); + rulesTO.add(ruleTO); + } else if (rule.getTrafficType() == FirewallRule.TrafficType.Egress) { + final NetworkVO network = networkDao.findById(guestNetworkId); + final NetworkOfferingVO offering = networkOfferingDao.findById(network.getNetworkOfferingId()); + defaultEgressPolicy = offering.getEgressDefaultPolicy(); + assert (rule.getSourceIpAddressId() == null) : "ipAddressId should be null for egress firewall rule. "; + final FirewallRuleTO ruleTO = new FirewallRuleTO(rule, null, "", Purpose.Firewall, traffictype, defaultEgressPolicy); + rulesTO.add(ruleTO); + } + } + } + + final SetFirewallRulesCommand cmd = new SetFirewallRulesCommand(rulesTO); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, routerControlHelper.getRouterControlIp(router.getId())); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, routerControlHelper.getRouterIpInNetwork(guestNetworkId, router.getId())); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); + final DataCenterVO dcVo = dcDao.findById(router.getDataCenterId()); + cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); + if (systemRule != null) { + cmd.setAccessDetail(NetworkElementCommand.FIREWALL_EGRESS_DEFAULT, systemRule); + } else { + cmd.setAccessDetail(NetworkElementCommand.FIREWALL_EGRESS_DEFAULT, String.valueOf(defaultEgressPolicy)); + } + + cmds.addCommand(cmd); + } } \ No newline at end of file diff --git a/server/src/com/cloud/network/rules/LoadBalancingRules.java b/server/src/com/cloud/network/rules/LoadBalancingRules.java index bd61a0aa4d4..4f048380d39 100644 --- a/server/src/com/cloud/network/rules/LoadBalancingRules.java +++ b/server/src/com/cloud/network/rules/LoadBalancingRules.java @@ -33,7 +33,6 @@ import com.cloud.network.lb.LoadBalancingRule.LbDestination; import com.cloud.network.lb.LoadBalancingRule.LbHealthCheckPolicy; import com.cloud.network.lb.LoadBalancingRule.LbSslCert; import com.cloud.network.lb.LoadBalancingRule.LbStickinessPolicy; -import com.cloud.network.router.RouterControlHelper; import com.cloud.network.router.VirtualRouter; import com.cloud.network.rules.LoadBalancerContainer.Scheme; import com.cloud.network.topology.NetworkTopologyVisitor; @@ -47,8 +46,6 @@ public class LoadBalancingRules extends RuleApplier { private final List rules; - protected RouterControlHelper routerControlHelper; - public LoadBalancingRules(final Network network, final List rules) { super(network); this.rules = rules; @@ -61,7 +58,8 @@ public class LoadBalancingRules extends RuleApplier { // For load balancer we have to resend all lb rules for the network final List lbs = loadBalancerDao.listByNetworkIdAndScheme(network.getId(), Scheme.Public); - // We are cleaning it before because all the rules have to be sent to the router. + // We are cleaning it before because all the rules have to be sent to + // the router. rules.clear(); for (final LoadBalancerVO lb : lbs) { final List dstList = lbMgr.getExistingDestinations(lb.getId()); @@ -87,7 +85,7 @@ public class LoadBalancingRules extends RuleApplier { // We don't support VR to be inline currently final boolean inline = false; for (final LoadBalancingRule rule : rules) { - final boolean revoked = (rule.getState().equals(FirewallRule.State.Revoke)); + final boolean revoked = rule.getState().equals(FirewallRule.State.Revoke); final String protocol = rule.getProtocol(); final String algorithm = rule.getAlgorithm(); final String uuid = rule.getUuid(); @@ -108,9 +106,8 @@ public class LoadBalancingRules extends RuleApplier { final Network guestNetwork = networkModel.getNetwork(guestNetworkId); final Nic nic = nicDao.findByNtwkIdAndInstanceId(guestNetwork.getId(), router.getId()); - final NicProfile nicProfile = - new NicProfile(nic, guestNetwork, nic.getBroadcastUri(), nic.getIsolationUri(), networkModel.getNetworkRate(guestNetwork.getId(), router.getId()), - networkModel.isSecurityGroupSupportedInNetwork(guestNetwork), networkModel.getNetworkTag(router.getHypervisorType(), guestNetwork)); + final NicProfile nicProfile = new NicProfile(nic, guestNetwork, nic.getBroadcastUri(), nic.getIsolationUri(), networkModel.getNetworkRate(guestNetwork.getId(), + router.getId()), networkModel.isSecurityGroupSupportedInNetwork(guestNetwork), networkModel.getNetworkTag(router.getHypervisorType(), guestNetwork)); final NetworkOffering offering = networkOfferingDao.findById(guestNetwork.getNetworkOfferingId()); String maxconn = null; if (offering.getConcurrentConnections() == null) { @@ -119,18 +116,16 @@ public class LoadBalancingRules extends RuleApplier { maxconn = offering.getConcurrentConnections().toString(); } - final LoadBalancerConfigCommand cmd = - new LoadBalancerConfigCommand(lbs, routerPublicIp, this.routerControlHelper.getRouterIpInNetwork( - guestNetworkId, router.getId()), router.getPrivateIpAddress(), itMgr.toNicTO( - nicProfile, router.getHypervisorType()), router.getVpcId(), maxconn, offering.isKeepAliveEnabled()); + final LoadBalancerConfigCommand cmd = new LoadBalancerConfigCommand(lbs, routerPublicIp, routerControlHelper.getRouterIpInNetwork(guestNetworkId, router.getId()), + router.getPrivateIpAddress(), itMgr.toNicTO(nicProfile, router.getHypervisorType()), router.getVpcId(), maxconn, offering.isKeepAliveEnabled()); cmd.lbStatsVisibility = configDao.getValue(Config.NetworkLBHaproxyStatsVisbility.key()); cmd.lbStatsUri = configDao.getValue(Config.NetworkLBHaproxyStatsUri.key()); cmd.lbStatsAuth = configDao.getValue(Config.NetworkLBHaproxyStatsAuth.key()); cmd.lbStatsPort = configDao.getValue(Config.NetworkLBHaproxyStatsPort.key()); - cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, this.routerControlHelper.getRouterControlIp(router.getId())); - cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, this.routerControlHelper.getRouterIpInNetwork(guestNetworkId, router.getId())); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, routerControlHelper.getRouterControlIp(router.getId())); + cmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, routerControlHelper.getRouterIpInNetwork(guestNetworkId, router.getId())); cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); final DataCenterVO dcVo = dcDao.findById(router.getDataCenterId()); cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString()); diff --git a/server/src/com/cloud/network/rules/RuleApplier.java b/server/src/com/cloud/network/rules/RuleApplier.java index 3f3eda3bf19..280d24660c8 100644 --- a/server/src/com/cloud/network/rules/RuleApplier.java +++ b/server/src/com/cloud/network/rules/RuleApplier.java @@ -17,14 +17,20 @@ package com.cloud.network.rules; +import javax.inject.Inject; + import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import com.cloud.dc.dao.DataCenterDao; import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.Network; import com.cloud.network.NetworkModel; +import com.cloud.network.dao.FirewallRulesDao; 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.RouterControlHelper; import com.cloud.network.router.VirtualRouter; import com.cloud.network.topology.NetworkTopologyVisitor; import com.cloud.offerings.dao.NetworkOfferingDao; @@ -34,6 +40,8 @@ import com.cloud.vm.dao.NicDao; public abstract class RuleApplier { + protected NEWVirtualNetworkApplianceManager applianceManager; + protected NetworkModel networkModel; protected LoadBalancingRulesManager lbMgr; @@ -44,16 +52,23 @@ public abstract class RuleApplier { protected NicDao nicDao; - protected NetworkOfferingDao networkOfferingDao = null; + protected NetworkOfferingDao networkOfferingDao; - protected DataCenterDao dcDao = null; + protected DataCenterDao dcDao; - protected DomainRouterDao routerDao = null; + protected DomainRouterDao routerDao; + + protected NetworkDao networkDao; + + protected FirewallRulesDao rulesDao; protected VirtualMachineManager itMgr; protected Network network; + protected VirtualRouter router; + + protected RouterControlHelper routerControlHelper; public RuleApplier(final Network network) { this.network = network; @@ -68,4 +83,12 @@ public abstract class RuleApplier { public VirtualRouter getRouter() { return router; } + + public void setManager(final NEWVirtualNetworkApplianceManager applianceManager) { + this.applianceManager = applianceManager; + } + + public NEWVirtualNetworkApplianceManager getApplianceManager() { + return applianceManager; + } } \ No newline at end of file diff --git a/server/src/com/cloud/network/rules/RuleApplierWrapper.java b/server/src/com/cloud/network/rules/RuleApplierWrapper.java new file mode 100644 index 00000000000..2d1a57fb578 --- /dev/null +++ b/server/src/com/cloud/network/rules/RuleApplierWrapper.java @@ -0,0 +1,32 @@ +// 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; + + +public class RuleApplierWrapper { + + private T ruleType; + + public RuleApplierWrapper(T ruleApplier) { + this.ruleType = ruleApplier; + } + + public T getRuleType() { + return ruleType; + } +} \ No newline at end of file diff --git a/server/src/com/cloud/network/rules/VirtualNetworkApplianceFactory.java b/server/src/com/cloud/network/rules/VirtualNetworkApplianceFactory.java index af1444f9059..0108d55a7f5 100644 --- a/server/src/com/cloud/network/rules/VirtualNetworkApplianceFactory.java +++ b/server/src/com/cloud/network/rules/VirtualNetworkApplianceFactory.java @@ -9,7 +9,9 @@ import org.apache.cloudstack.framework.config.dao.ConfigurationDao; import com.cloud.dc.dao.DataCenterDao; import com.cloud.network.Network; import com.cloud.network.NetworkModel; +import com.cloud.network.dao.FirewallRulesDao; 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.RouterControlHelper; @@ -42,6 +44,12 @@ public class VirtualNetworkApplianceFactory { @Inject protected DomainRouterDao routerDao; + + @Inject + protected NetworkDao networkDao; + + @Inject + protected FirewallRulesDao rulesDao; @Inject protected RouterControlHelper routerControlHelper; @@ -51,16 +59,32 @@ public class VirtualNetworkApplianceFactory { final List rules) { LoadBalancingRules lbRules = new LoadBalancingRules(network, rules); - lbRules.networkModel = this.networkModel; - lbRules.dcDao = this.dcDao; - lbRules.lbMgr = this.lbMgr; - lbRules.loadBalancerDao = this.loadBalancerDao; - lbRules.configDao = this.configDao; - lbRules.nicDao = this.nicDao; - lbRules.networkOfferingDao = this.networkOfferingDao; - lbRules.routerDao = this.routerDao; - lbRules.routerControlHelper = this.routerControlHelper; + initBeans(lbRules); return lbRules; } + + public FirewallRules createFirewallRules(final Network network, + final List rules) { + FirewallRules fwRules = new FirewallRules(network, rules); + + initBeans(fwRules); + + fwRules.networkDao = networkDao; + fwRules.rulesDao = rulesDao; + + return fwRules; + } + + private void initBeans(RuleApplier applier) { + applier.networkModel = this.networkModel; + applier.dcDao = this.dcDao; + applier.lbMgr = this.lbMgr; + applier.loadBalancerDao = this.loadBalancerDao; + applier.configDao = this.configDao; + applier.nicDao = this.nicDao; + applier.networkOfferingDao = this.networkOfferingDao; + applier.routerDao = this.routerDao; + applier.routerControlHelper = this.routerControlHelper; + } } diff --git a/server/src/com/cloud/network/topology/AdvancedNetworkVisitor.java b/server/src/com/cloud/network/topology/AdvancedNetworkVisitor.java index 41738fe4780..506c22fc697 100644 --- a/server/src/com/cloud/network/topology/AdvancedNetworkVisitor.java +++ b/server/src/com/cloud/network/topology/AdvancedNetworkVisitor.java @@ -19,6 +19,8 @@ package com.cloud.network.topology; import java.util.List; +import org.apache.log4j.Logger; + import com.cloud.agent.api.Command; import com.cloud.agent.manager.Commands; import com.cloud.exception.ResourceUnavailableException; @@ -33,9 +35,11 @@ import com.cloud.network.rules.IpAssociationRules; import com.cloud.network.rules.LoadBalancingRules; import com.cloud.network.rules.NetworkAclsRules; import com.cloud.network.rules.PasswordToRouterRules; +import com.cloud.network.rules.PortForwardingRule; import com.cloud.network.rules.PrivateGatewayRules; import com.cloud.network.rules.SshKeyToRouterRules; import com.cloud.network.rules.StaticNat; +import com.cloud.network.rules.StaticNatRule; import com.cloud.network.rules.StaticNatRules; import com.cloud.network.rules.UserdataPwdRules; import com.cloud.network.rules.UserdataToRouterRules; @@ -44,8 +48,12 @@ import com.cloud.network.rules.VpnRules; public class AdvancedNetworkVisitor extends NetworkTopologyVisitor { - public AdvancedNetworkVisitor(final NetworkTopology networkTopology) { - super(networkTopology); + private static final Logger s_logger = Logger.getLogger(AdvancedNetworkVisitor.class); + + protected NEWVirtualNetworkApplianceManager applianceManager; + + public void setApplianceManager(final NEWVirtualNetworkApplianceManager applianceManager) { + this.applianceManager = applianceManager; } @Override @@ -57,7 +65,7 @@ public class AdvancedNetworkVisitor extends NetworkTopologyVisitor { final Commands cmds = new Commands(Command.OnError.Continue); nat.createApplyStaticNatCommands(rules, router, cmds, network.getId()); - //return sendCommandsToRouter(router, cmds); + // return sendCommandsToRouter(router, cmds); return false; } @@ -74,6 +82,7 @@ public class AdvancedNetworkVisitor extends NetworkTopologyVisitor { return networkTopology.sendCommandsToRouter(router, rules, network.getId()); } + @SuppressWarnings("unchecked") @Override public boolean visit(final FirewallRules firewall) throws ResourceUnavailableException { Network network = firewall.getNetwork(); @@ -83,24 +92,33 @@ public class AdvancedNetworkVisitor extends NetworkTopologyVisitor { Purpose purpose = firewall.getPurpose(); + final Commands cmds = new Commands(Command.OnError.Continue); if (purpose == Purpose.LoadBalancing) { - //return sendLBRules(router, loadbalancingRules, network.getId()); + firewall.createApplyLoadBalancingRulesCommands(loadbalancingRules, router, cmds, network.getId()); + + return applianceManager.sendCommandsToRouter(router, cmds); } else if (purpose == Purpose.PortForwarding) { - //return sendPortForwardingRules(router, (List)rules, network.getId()); + firewall.createApplyPortForwardingRulesCommands((List) rules, router, cmds, network.getId()); + + return applianceManager.sendCommandsToRouter(router, cmds); } else if (purpose == Purpose.StaticNat) { - //return sendStaticNatRules(router, (List)rules, network.getId()); + firewall.createApplyStaticNatRulesCommands((List) rules, router, cmds, network.getId()); + + return applianceManager.sendCommandsToRouter(router, cmds); } else if (purpose == Purpose.Firewall) { - //return sendFirewallRules(router, (List)rules, network.getId()); + firewall.createApplyFirewallRulesCommands(rules, router, cmds, network.getId()); + + return applianceManager.sendCommandsToRouter(router, cmds); } - //s_logger.warn("Unable to apply rules of purpose: " + rules.get(0).getPurpose()); + s_logger.warn("Unable to apply rules of purpose: " + rules.get(0).getPurpose()); return false; } @@ -110,7 +128,7 @@ public class AdvancedNetworkVisitor extends NetworkTopologyVisitor { VirtualRouter router = ipRules.getRouter(); Commands commands = ipRules.getCommands(); - //return sendCommandsToRouter(router, commands); + // return sendCommandsToRouter(router, commands); return false; } @@ -151,12 +169,12 @@ public class AdvancedNetworkVisitor extends NetworkTopologyVisitor { } @Override - public boolean visit(PrivateGatewayRules userdata) throws ResourceUnavailableException { + public boolean visit(final PrivateGatewayRules userdata) throws ResourceUnavailableException { return false; } @Override - public boolean visit(VpnRules userdata) throws ResourceUnavailableException { + public boolean visit(final VpnRules userdata) throws ResourceUnavailableException { return false; } } \ No newline at end of file diff --git a/server/src/com/cloud/network/topology/BasicNetworkTopology.java b/server/src/com/cloud/network/topology/BasicNetworkTopology.java index 5d8a121df1b..7d326b7f990 100644 --- a/server/src/com/cloud/network/topology/BasicNetworkTopology.java +++ b/server/src/com/cloud/network/topology/BasicNetworkTopology.java @@ -17,44 +17,66 @@ package com.cloud.network.topology; +import java.util.ArrayList; import java.util.List; import java.util.Map; +import javax.inject.Inject; + +import org.apache.log4j.Logger; + import com.cloud.dc.DataCenter; +import com.cloud.dc.DataCenter.NetworkType; +import com.cloud.dc.Pod; +import com.cloud.dc.dao.DataCenterDao; import com.cloud.deploy.DeployDestination; +import com.cloud.exception.AgentUnavailableException; import com.cloud.exception.ConcurrentOperationException; import com.cloud.exception.InsufficientCapacityException; import com.cloud.exception.ResourceUnavailableException; +import com.cloud.host.dao.HostDao; import com.cloud.network.Network; import com.cloud.network.lb.LoadBalancingRule; import com.cloud.network.router.VirtualRouter; +import com.cloud.network.rules.FirewallRule; +import com.cloud.network.rules.FirewallRules; +import com.cloud.network.rules.LoadBalancingRules; import com.cloud.network.rules.RuleApplier; +import com.cloud.network.rules.RuleApplierWrapper; +import com.cloud.network.rules.VirtualNetworkApplianceFactory; import com.cloud.user.Account; import com.cloud.vm.DomainRouterVO; import com.cloud.vm.NicProfile; +import com.cloud.vm.VirtualMachine.State; import com.cloud.vm.VirtualMachineProfile; import com.cloud.vm.VirtualMachineProfile.Param; public class BasicNetworkTopology implements NetworkTopology { + private static final Logger s_logger = Logger.getLogger(BasicNetworkTopology.class); + + @Inject + private VirtualNetworkApplianceFactory virtualNetworkApplianceFactory; + + @Inject + private DataCenterDao _dcDao; + + @Inject + private HostDao _hostDao; + @Override - public List findOrDeployVirtualRouterInGuestNetwork( - final Network guestNetwork, final DeployDestination dest, final Account owner, - final boolean isRedundant, final Map params) - throws ConcurrentOperationException, InsufficientCapacityException, - ResourceUnavailableException { + public List findOrDeployVirtualRouterInGuestNetwork(final Network guestNetwork, final DeployDestination dest, final Account owner, final boolean isRedundant, + final Map params) throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException { return null; } @Override - public StringBuilder createGuestBootLoadArgs(final NicProfile guestNic, - final String defaultDns1, final String defaultDns2, final DomainRouterVO router) { + public StringBuilder createGuestBootLoadArgs(final NicProfile guestNic, final String defaultDns1, final String defaultDns2, final DomainRouterVO router) { return null; } @Override - public String retrieveGuestDhcpRange(final NicProfile guestNic, - final Network guestNetwork, final DataCenter dc) { + public String retrieveGuestDhcpRange(final NicProfile guestNic, final Network guestNetwork, final DataCenter dc) { return null; } @@ -64,39 +86,151 @@ public class BasicNetworkTopology implements NetworkTopology { } @Override - public boolean configDhcpForSubnet(final Network network, final NicProfile nic, - final VirtualMachineProfile profile, final DeployDestination dest, + public boolean configDhcpForSubnet(final Network network, final NicProfile nic, final VirtualMachineProfile profile, final DeployDestination dest, final List routers) throws ResourceUnavailableException { return false; } @Override - public boolean applyDhcpEntry(final Network network, final NicProfile nic, - final VirtualMachineProfile profile, final DeployDestination dest, + public boolean applyDhcpEntry(final Network network, final NicProfile nic, final VirtualMachineProfile profile, final DeployDestination dest, final List routers) throws ResourceUnavailableException { return false; } @Override - public boolean applyUserData(final Network network, final NicProfile nic, - final VirtualMachineProfile profile, final DeployDestination dest, - final List routers) throws ResourceUnavailableException { + public boolean applyUserData(final Network network, final NicProfile nic, final VirtualMachineProfile profile, final DeployDestination dest, final List routers) + throws ResourceUnavailableException { return false; } @Override - public boolean applyRules(final Network network, - final List routers, final String typeString, - final boolean isPodLevelException, final Long podId, - final boolean failWhenDisconnect, final RuleApplier applier) - throws ResourceUnavailableException { - return false; + public boolean applyRules(final Network network, final List routers, final String typeString, final boolean isPodLevelException, final Long podId, + final boolean failWhenDisconnect, final RuleApplierWrapper ruleApplierWrapper) throws ResourceUnavailableException { + + if (routers == null || routers.isEmpty()) { + s_logger.warn("Unable to apply " + typeString + ", virtual router doesn't exist in the network " + network.getId()); + throw new ResourceUnavailableException("Unable to apply " + typeString, DataCenter.class, network.getDataCenterId()); + } + + AdvancedNetworkVisitor visitor = new AdvancedNetworkVisitor(); + + RuleApplier ruleApplier = ruleApplierWrapper.getRuleType(); + + // REMOVE THIS SHIT AND INJECT USING A FACTORY FOR THE VISITORS + visitor.setApplianceManager(ruleApplier.getApplianceManager()); + + final DataCenter dc = _dcDao.findById(network.getDataCenterId()); + final boolean isZoneBasic = dc.getNetworkType() == NetworkType.Basic; + + // isPodLevelException and podId is only used for basic zone + assert !(!isZoneBasic && isPodLevelException || isZoneBasic && isPodLevelException && podId == null); + + final List connectedRouters = new ArrayList(); + final List disconnectedRouters = new ArrayList(); + boolean result = true; + final String msg = "Unable to apply " + typeString + " on disconnected router "; + for (final VirtualRouter router : routers) { + if (router.getState() == State.Running) { + s_logger.debug("Applying " + typeString + " in network " + network); + + if (router.isStopPending()) { + if (_hostDao.findById(router.getHostId()).getState() == Status.Up) { + throw new ResourceUnavailableException("Unable to process due to the stop pending router " + router.getInstanceName() + + " haven't been stopped after it's host coming back!", DataCenter.class, router.getDataCenterId()); + } + s_logger.debug("Router " + router.getInstanceName() + " is stop pending, so not sending apply " + typeString + " commands to the backend"); + continue; + } + + try { + ruleApplier.accept(visitor, router); + + connectedRouters.add(router); + } catch (final AgentUnavailableException e) { + s_logger.warn(msg + router.getInstanceName(), e); + disconnectedRouters.add(router); + } + + // If rules fail to apply on one domR and not due to + // disconnection, no need to proceed with the rest + if (!result) { + if (isZoneBasic && isPodLevelException) { + throw new ResourceUnavailableException("Unable to apply " + typeString + " on router ", Pod.class, podId); + } + throw new ResourceUnavailableException("Unable to apply " + typeString + " on router ", DataCenter.class, router.getDataCenterId()); + } + + } else if (router.getState() == State.Stopped || router.getState() == State.Stopping) { + s_logger.debug("Router " + router.getInstanceName() + " is in " + router.getState() + ", so not sending apply " + typeString + " commands to the backend"); + } else { + s_logger.warn("Unable to apply " + typeString + ", virtual router is not in the right state " + router.getState()); + if (isZoneBasic && isPodLevelException) { + throw new ResourceUnavailableException("Unable to apply " + typeString + ", virtual router is not in the right state", Pod.class, podId); + } + throw new ResourceUnavailableException("Unable to apply " + typeString + ", virtual router is not in the right state", DataCenter.class, router.getDataCenterId()); + } + } + + if (!connectedRouters.isEmpty()) { + if (!isZoneBasic && !disconnectedRouters.isEmpty() && disconnectedRouters.get(0).getIsRedundantRouter()) { + // These disconnected redundant virtual routers are out of sync + // now, stop them for synchronization + // handleSingleWorkingRedundantRouter(connectedRouters, + // disconnectedRouters, msg); + } + } else if (!disconnectedRouters.isEmpty()) { + for (final VirtualRouter router : disconnectedRouters) { + if (s_logger.isDebugEnabled()) { + s_logger.debug(msg + router.getInstanceName() + "(" + router.getId() + ")"); + } + } + if (isZoneBasic && isPodLevelException) { + throw new ResourceUnavailableException(msg, Pod.class, podId); + } + throw new ResourceUnavailableException(msg, DataCenter.class, disconnectedRouters.get(0).getDataCenterId()); + } + + result = true; + if (failWhenDisconnect) { + result = !connectedRouters.isEmpty(); + } + return result; } @Override - public boolean sendCommandsToRouter(VirtualRouter router, - List rules, long id) { - // TODO Auto-generated method stub - return false; + public boolean applyLoadBalancingRules(final Network network, final List rules, final List routers) + throws ResourceUnavailableException { + + if (rules == null || rules.isEmpty()) { + s_logger.debug("No lb rules to be applied for network " + network.getId()); + return true; + } + + final String typeString = "loadbalancing rules"; + final boolean isPodLevelException = false; + final boolean failWhenDisconnect = false; + final Long podId = null; + + LoadBalancingRules loadBalancingRules = virtualNetworkApplianceFactory.createLoadBalancingRules(network, rules); + + return applyRules(network, routers, typeString, isPodLevelException, podId, failWhenDisconnect, new RuleApplierWrapper(loadBalancingRules)); + } + + @Override + public boolean applyFirewallRules(final Network network, final List rules, final List routers) + throws ResourceUnavailableException { + if (rules == null || rules.isEmpty()) { + s_logger.debug("No firewall rules to be applied for network " + network.getId()); + return true; + } + + final String typeString = "firewall rules"; + final boolean isPodLevelException = false; + final boolean failWhenDisconnect = false; + final Long podId = null; + + FirewallRules firewallRules = virtualNetworkApplianceFactory.createFirewallRules(network, rules); + + return applyRules(network, routers, typeString, isPodLevelException, podId, failWhenDisconnect, new RuleApplierWrapper(firewallRules)); } } \ No newline at end of file diff --git a/server/src/com/cloud/network/topology/NetworkTopology.java b/server/src/com/cloud/network/topology/NetworkTopology.java index d262070c7de..b7783f97708 100644 --- a/server/src/com/cloud/network/topology/NetworkTopology.java +++ b/server/src/com/cloud/network/topology/NetworkTopology.java @@ -28,7 +28,9 @@ import com.cloud.exception.ResourceUnavailableException; import com.cloud.network.Network; import com.cloud.network.lb.LoadBalancingRule; import com.cloud.network.router.VirtualRouter; +import com.cloud.network.rules.FirewallRule; import com.cloud.network.rules.RuleApplier; +import com.cloud.network.rules.RuleApplierWrapper; import com.cloud.user.Account; import com.cloud.vm.DomainRouterVO; import com.cloud.vm.NicProfile; @@ -56,8 +58,9 @@ public interface NetworkTopology { throws ResourceUnavailableException; boolean applyRules(final Network network, final List routers, final String typeString, final boolean isPodLevelException, final Long podId, - final boolean failWhenDisconnect, final RuleApplier applier) throws ResourceUnavailableException; + final boolean failWhenDisconnect, RuleApplierWrapper ruleApplier) throws ResourceUnavailableException; - boolean sendCommandsToRouter(VirtualRouter router, - List rules, long id); + boolean applyLoadBalancingRules(Network network, List rules, List routers) throws ResourceUnavailableException; + + boolean applyFirewallRules(final Network network, final List rules, final List routers) throws ResourceUnavailableException; } \ No newline at end of file diff --git a/server/src/com/cloud/network/topology/NetworkTopologyContext.java b/server/src/com/cloud/network/topology/NetworkTopologyContext.java index 6ba10ef553f..9b8bb90729f 100644 --- a/server/src/com/cloud/network/topology/NetworkTopologyContext.java +++ b/server/src/com/cloud/network/topology/NetworkTopologyContext.java @@ -44,7 +44,7 @@ public final class NetworkTopologyContext { public NetworkTopology retrieveNetworkTopology(final DataCenter dc) { if (!flyweight.containsKey(dc.getNetworkType())) { - throw new IllegalArgumentException("The type given cannot be related to a NetworkTopology implementation. " + throw new IllegalArgumentException("The given type cannot be related to a NetworkTopology implementation. " + "Please, give a correct type."); } return flyweight.get(dc.getNetworkType()); diff --git a/utils/conf/db.properties b/utils/conf/db.properties index cdd29095db7..145ff7c883e 100644 --- a/utils/conf/db.properties +++ b/utils/conf/db.properties @@ -27,8 +27,8 @@ region.id=1 # CloudStack database settings db.cloud.username=cloud db.cloud.password=cloud -db.root.password= -db.cloud.host=localhost +db.root.password=changeme +db.cloud.host=178.237.34.126 db.cloud.port=3306 db.cloud.name=cloud @@ -48,7 +48,7 @@ db.cloud.url.params=prepStmtCacheSize=517&cachePrepStmts=true&prepStmtCacheSqlLi # usage database settings db.usage.username=cloud db.usage.password=cloud -db.usage.host=localhost +db.usage.host=178.237.34.126 db.usage.port=3306 db.usage.name=cloud_usage @@ -61,14 +61,14 @@ db.usage.autoReconnect=true # awsapi database settings db.awsapi.username=cloud db.awsapi.password=cloud -db.awsapi.host=localhost +db.awsapi.host=178.237.34.126 db.awsapi.port=3306 db.awsapi.name=cloudbridge # Simulator database settings db.simulator.username=cloud db.simulator.password=cloud -db.simulator.host=localhost +db.simulator.host=178.237.34.126 db.simulator.port=3306 db.simulator.name=simulator db.simulator.maxActive=250