mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Merge pull request #1483 from remibergsma/pr1413-wilder-47
CLOUDSTACK-9287 - Fix unique mac address per rVPC routerThis is work by @wilderrodrigues, see PR #1413 It contains important fixes and I think it needs to be included so I send the PR again. * pr/1483: CLOUDSTACK-9287 - Improve test by checking if pvt gw is removed and fix typos CLOUDSTACK-9287 - Fix RVR public interface CLOUDSTACK-9287 - Add integration test to cover the private gateway related changes CLOUDSTACK-9287 - Refactor the interface state configuration CLOUDSTACK-9287 - Check if the nic profile has already been removed from a certain router CLOUDSTACK-9287 - Bring up the private gw interface on state change to master CLOUDSTACK-9287 - Make sure private gw interface is not used for default gw CLOUDSTACK-9287 - Add integration test to cover the private gw interface/mac address issues CLOUDSTACK-9287 - Put private gateway interface down on backup router CLOUDSTACK-9287 - Generate new mac address if router is redundant and nic profile exists Signed-off-by: Will Stevens <williamstevens@gmail.com>
This commit is contained in:
commit
309a60ea71
@ -24,18 +24,6 @@ import java.util.Set;
|
|||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import org.apache.cloudstack.api.command.admin.router.ConfigureOvsElementCmd;
|
|
||||||
import org.apache.cloudstack.api.command.admin.router.ConfigureVirtualRouterElementCmd;
|
|
||||||
import org.apache.cloudstack.api.command.admin.router.CreateVirtualRouterElementCmd;
|
|
||||||
import org.apache.cloudstack.api.command.admin.router.ListOvsElementsCmd;
|
|
||||||
import org.apache.cloudstack.api.command.admin.router.ListVirtualRouterElementsCmd;
|
|
||||||
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
|
||||||
import org.apache.cloudstack.network.topology.NetworkTopology;
|
|
||||||
import org.apache.cloudstack.network.topology.NetworkTopologyContext;
|
|
||||||
import org.apache.log4j.Logger;
|
|
||||||
import org.cloud.network.router.deployment.RouterDeploymentDefinition;
|
|
||||||
import org.cloud.network.router.deployment.RouterDeploymentDefinitionBuilder;
|
|
||||||
|
|
||||||
import com.cloud.agent.api.to.LoadBalancerTO;
|
import com.cloud.agent.api.to.LoadBalancerTO;
|
||||||
import com.cloud.configuration.ConfigurationManager;
|
import com.cloud.configuration.ConfigurationManager;
|
||||||
import com.cloud.dc.DataCenter;
|
import com.cloud.dc.DataCenter;
|
||||||
@ -107,6 +95,18 @@ import com.cloud.vm.dao.DomainRouterDao;
|
|||||||
import com.cloud.vm.dao.UserVmDao;
|
import com.cloud.vm.dao.UserVmDao;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.api.command.admin.router.ConfigureOvsElementCmd;
|
||||||
|
import org.apache.cloudstack.api.command.admin.router.ConfigureVirtualRouterElementCmd;
|
||||||
|
import org.apache.cloudstack.api.command.admin.router.CreateVirtualRouterElementCmd;
|
||||||
|
import org.apache.cloudstack.api.command.admin.router.ListOvsElementsCmd;
|
||||||
|
import org.apache.cloudstack.api.command.admin.router.ListVirtualRouterElementsCmd;
|
||||||
|
import org.apache.cloudstack.framework.config.dao.ConfigurationDao;
|
||||||
|
import org.apache.cloudstack.network.topology.NetworkTopology;
|
||||||
|
import org.apache.cloudstack.network.topology.NetworkTopologyContext;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.cloud.network.router.deployment.RouterDeploymentDefinition;
|
||||||
|
import org.cloud.network.router.deployment.RouterDeploymentDefinitionBuilder;
|
||||||
|
|
||||||
public class VirtualRouterElement extends AdapterBase implements VirtualRouterElementService, DhcpServiceProvider, UserDataServiceProvider, SourceNatServiceProvider,
|
public class VirtualRouterElement extends AdapterBase implements VirtualRouterElementService, DhcpServiceProvider, UserDataServiceProvider, SourceNatServiceProvider,
|
||||||
StaticNatServiceProvider, FirewallServiceProvider, LoadBalancingServiceProvider, PortForwardingServiceProvider, RemoteAccessVPNServiceProvider, IpDeployer,
|
StaticNatServiceProvider, FirewallServiceProvider, LoadBalancingServiceProvider, PortForwardingServiceProvider, RemoteAccessVPNServiceProvider, IpDeployer,
|
||||||
NetworkMigrationResponder, AggregatedCommandExecutor {
|
NetworkMigrationResponder, AggregatedCommandExecutor {
|
||||||
@ -153,6 +153,8 @@ NetworkMigrationResponder, AggregatedCommandExecutor {
|
|||||||
IPAddressDao _ipAddressDao;
|
IPAddressDao _ipAddressDao;
|
||||||
@Inject
|
@Inject
|
||||||
DataCenterDao _dcDao;
|
DataCenterDao _dcDao;
|
||||||
|
@Inject
|
||||||
|
NetworkModel _networkModel;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
NetworkTopologyContext networkTopologyContext;
|
NetworkTopologyContext networkTopologyContext;
|
||||||
|
|||||||
@ -25,13 +25,6 @@ import java.util.Set;
|
|||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import org.apache.cloudstack.network.topology.NetworkTopology;
|
|
||||||
import org.apache.log4j.Logger;
|
|
||||||
import org.cloud.network.router.deployment.RouterDeploymentDefinition;
|
|
||||||
import org.cloud.network.router.deployment.RouterDeploymentDefinitionBuilder;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
|
||||||
|
|
||||||
import com.cloud.dc.DataCenter;
|
import com.cloud.dc.DataCenter;
|
||||||
import com.cloud.dc.DataCenterVO;
|
import com.cloud.dc.DataCenterVO;
|
||||||
import com.cloud.deploy.DeployDestination;
|
import com.cloud.deploy.DeployDestination;
|
||||||
@ -79,6 +72,13 @@ import com.cloud.vm.VirtualMachine;
|
|||||||
import com.cloud.vm.VirtualMachineManager;
|
import com.cloud.vm.VirtualMachineManager;
|
||||||
import com.cloud.vm.VirtualMachineProfile;
|
import com.cloud.vm.VirtualMachineProfile;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.network.topology.NetworkTopology;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.cloud.network.router.deployment.RouterDeploymentDefinition;
|
||||||
|
import org.cloud.network.router.deployment.RouterDeploymentDefinitionBuilder;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
|
|
||||||
public class VpcVirtualRouterElement extends VirtualRouterElement implements VpcProvider, Site2SiteVpnServiceProvider, NetworkACLServiceProvider {
|
public class VpcVirtualRouterElement extends VirtualRouterElement implements VpcProvider, Site2SiteVpnServiceProvider, NetworkACLServiceProvider {
|
||||||
|
|
||||||
private static final Logger s_logger = Logger.getLogger(VpcVirtualRouterElement.class);
|
private static final Logger s_logger = Logger.getLogger(VpcVirtualRouterElement.class);
|
||||||
@ -466,7 +466,7 @@ public class VpcVirtualRouterElement extends VirtualRouterElement implements Vpc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result > 0 ? true : false;
|
return result == routers.size() ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -559,9 +559,16 @@ public class VpcVirtualRouterElement extends VirtualRouterElement implements Vpc
|
|||||||
final DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId());
|
final DataCenterVO dcVO = _dcDao.findById(network.getDataCenterId());
|
||||||
final NetworkTopology networkTopology = networkTopologyContext.retrieveNetworkTopology(dcVO);
|
final NetworkTopology networkTopology = networkTopologyContext.retrieveNetworkTopology(dcVO);
|
||||||
|
|
||||||
|
final Network privateNetwork = _networkModel.getNetwork(gateway.getNetworkId());
|
||||||
|
|
||||||
boolean result = true;
|
boolean result = true;
|
||||||
for (final DomainRouterVO domainRouterVO : routers) {
|
for (final DomainRouterVO domainRouterVO : routers) {
|
||||||
result = result && networkTopology.applyNetworkACLs(network, rules, domainRouterVO, isPrivateGateway);
|
final NicProfile nicProfile = _networkModel.getNicProfile(domainRouterVO, privateNetwork.getId(), null);
|
||||||
|
if (nicProfile != null) {
|
||||||
|
result = result && networkTopology.applyNetworkACLs(network, rules, domainRouterVO, isPrivateGateway);
|
||||||
|
} else {
|
||||||
|
s_logger.warn("Nic Profile for router '" + domainRouterVO + "' has already been removed. Router is redundant = " + domainRouterVO.getIsRedundantRouter());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -58,6 +58,7 @@ import com.cloud.agent.api.to.FirewallRuleTO;
|
|||||||
import com.cloud.agent.api.to.IpAddressTO;
|
import com.cloud.agent.api.to.IpAddressTO;
|
||||||
import com.cloud.agent.api.to.LoadBalancerTO;
|
import com.cloud.agent.api.to.LoadBalancerTO;
|
||||||
import com.cloud.agent.api.to.NetworkACLTO;
|
import com.cloud.agent.api.to.NetworkACLTO;
|
||||||
|
import com.cloud.agent.api.to.NicTO;
|
||||||
import com.cloud.agent.api.to.PortForwardingRuleTO;
|
import com.cloud.agent.api.to.PortForwardingRuleTO;
|
||||||
import com.cloud.agent.api.to.StaticNatRuleTO;
|
import com.cloud.agent.api.to.StaticNatRuleTO;
|
||||||
import com.cloud.agent.manager.Commands;
|
import com.cloud.agent.manager.Commands;
|
||||||
@ -504,7 +505,8 @@ public class CommandSetupHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final SetNetworkACLCommand cmd = new SetNetworkACLCommand(rulesTO, _networkHelper.getNicTO(router, guestNetworkId, null));
|
NicTO nicTO = _networkHelper.getNicTO(router, guestNetworkId, null);
|
||||||
|
final SetNetworkACLCommand cmd = new SetNetworkACLCommand(rulesTO, nicTO);
|
||||||
cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(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_GUEST_IP, _routerControlHelper.getRouterIpInNetwork(guestNetworkId, router.getId()));
|
||||||
cmd.setAccessDetail(NetworkElementCommand.GUEST_VLAN_TAG, guestVlan);
|
cmd.setAccessDetail(NetworkElementCommand.GUEST_VLAN_TAG, guestVlan);
|
||||||
|
|||||||
@ -85,6 +85,11 @@ public class NicProfileHelperImpl implements NicProfileHelper {
|
|||||||
new NicProfile(privateNic, privateNetwork, privateNic.getBroadcastUri(), privateNic.getIsolationUri(), _networkModel.getNetworkRate(
|
new NicProfile(privateNic, privateNetwork, privateNic.getBroadcastUri(), privateNic.getIsolationUri(), _networkModel.getNetworkRate(
|
||||||
privateNetwork.getId(), router.getId()), _networkModel.isSecurityGroupSupportedInNetwork(privateNetwork), _networkModel.getNetworkTag(
|
privateNetwork.getId(), router.getId()), _networkModel.isSecurityGroupSupportedInNetwork(privateNetwork), _networkModel.getNetworkTag(
|
||||||
router.getHypervisorType(), privateNetwork));
|
router.getHypervisorType(), privateNetwork));
|
||||||
|
|
||||||
|
if (router.getIsRedundantRouter()) {
|
||||||
|
String newMacAddress = NetUtils.long2Mac(NetUtils.createSequenceBasedMacAddress(ipVO.getMacAddress()));
|
||||||
|
privateNicProfile.setMacAddress(newMacAddress);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
final String netmask = NetUtils.getCidrNetmask(privateNetwork.getCidr());
|
final String netmask = NetUtils.getCidrNetmask(privateNetwork.getCidr());
|
||||||
final PrivateIpAddress ip =
|
final PrivateIpAddress ip =
|
||||||
|
|||||||
@ -26,9 +26,6 @@ import java.util.Map;
|
|||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.naming.ConfigurationException;
|
import javax.naming.ConfigurationException;
|
||||||
|
|
||||||
import org.apache.log4j.Logger;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import com.cloud.agent.api.Answer;
|
import com.cloud.agent.api.Answer;
|
||||||
import com.cloud.agent.api.Command;
|
import com.cloud.agent.api.Command;
|
||||||
import com.cloud.agent.api.Command.OnError;
|
import com.cloud.agent.api.Command.OnError;
|
||||||
@ -91,6 +88,9 @@ import com.cloud.vm.VirtualMachineProfile;
|
|||||||
import com.cloud.vm.VirtualMachineProfile.Param;
|
import com.cloud.vm.VirtualMachineProfile.Param;
|
||||||
import com.cloud.vm.dao.VMInstanceDao;
|
import com.cloud.vm.dao.VMInstanceDao;
|
||||||
|
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplianceManagerImpl implements VpcVirtualNetworkApplianceManager {
|
public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplianceManagerImpl implements VpcVirtualNetworkApplianceManager {
|
||||||
private static final Logger s_logger = Logger.getLogger(VpcVirtualNetworkApplianceManagerImpl.class);
|
private static final Logger s_logger = Logger.getLogger(VpcVirtualNetworkApplianceManagerImpl.class);
|
||||||
@ -531,16 +531,18 @@ public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplian
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean destroyPrivateGateway(final PrivateGateway gateway, final VirtualRouter router) throws ConcurrentOperationException, ResourceUnavailableException {
|
public boolean destroyPrivateGateway(final PrivateGateway gateway, final VirtualRouter router) throws ConcurrentOperationException, ResourceUnavailableException {
|
||||||
|
boolean result = true;
|
||||||
|
|
||||||
if (!_networkModel.isVmPartOfNetwork(router.getId(), gateway.getNetworkId())) {
|
if (!_networkModel.isVmPartOfNetwork(router.getId(), gateway.getNetworkId())) {
|
||||||
s_logger.debug("Router doesn't have nic for gateway " + gateway + " so no need to removed it");
|
s_logger.debug("Router doesn't have nic for gateway " + gateway + " so no need to removed it");
|
||||||
return true;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
final Network privateNetwork = _networkModel.getNetwork(gateway.getNetworkId());
|
final Network privateNetwork = _networkModel.getNetwork(gateway.getNetworkId());
|
||||||
|
final NicProfile nicProfile = _networkModel.getNicProfile(router, privateNetwork.getId(), null);
|
||||||
|
|
||||||
s_logger.debug("Releasing private ip for gateway " + gateway + " from " + router);
|
s_logger.debug("Releasing private ip for gateway " + gateway + " from " + router);
|
||||||
boolean result = setupVpcPrivateNetwork(router, false, _networkModel.getNicProfile(router, privateNetwork.getId(), null));
|
result = setupVpcPrivateNetwork(router, false, nicProfile);
|
||||||
if (!result) {
|
if (!result) {
|
||||||
s_logger.warn("Failed to release private ip for gateway " + gateway + " on router " + router);
|
s_logger.warn("Failed to release private ip for gateway " + gateway + " on router " + router);
|
||||||
return false;
|
return false;
|
||||||
@ -706,7 +708,7 @@ public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplian
|
|||||||
s_logger.error("Unable to start vpn: unable add users to vpn in zone " + router.getDataCenterId() + " for account " + vpn.getAccountId() + " on domR: "
|
s_logger.error("Unable to start vpn: unable add users to vpn in zone " + router.getDataCenterId() + " for account " + vpn.getAccountId() + " on domR: "
|
||||||
+ router.getInstanceName() + " due to " + answer.getDetails());
|
+ router.getInstanceName() + " due to " + answer.getDetails());
|
||||||
throw new ResourceUnavailableException("Unable to start vpn: Unable to add users to vpn in zone " + router.getDataCenterId() + " for account " + vpn.getAccountId()
|
throw new ResourceUnavailableException("Unable to start vpn: Unable to add users to vpn in zone " + router.getDataCenterId() + " for account " + vpn.getAccountId()
|
||||||
+ " on domR: " + router.getInstanceName() + " due to " + answer.getDetails(), DataCenter.class, router.getDataCenterId());
|
+ " on domR: " + router.getInstanceName() + " due to " + answer.getDetails(), DataCenter.class, router.getDataCenterId());
|
||||||
}
|
}
|
||||||
answer = cmds.getAnswer("startVpn");
|
answer = cmds.getAnswer("startVpn");
|
||||||
if (!answer.getResult()) {
|
if (!answer.getResult()) {
|
||||||
|
|||||||
@ -21,11 +21,6 @@ import java.util.List;
|
|||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import org.apache.cloudstack.context.CallContext;
|
|
||||||
import org.apache.cloudstack.framework.messagebus.MessageBus;
|
|
||||||
import org.apache.cloudstack.framework.messagebus.PublishScope;
|
|
||||||
import org.apache.log4j.Logger;
|
|
||||||
|
|
||||||
import com.cloud.configuration.ConfigurationManager;
|
import com.cloud.configuration.ConfigurationManager;
|
||||||
import com.cloud.event.ActionEvent;
|
import com.cloud.event.ActionEvent;
|
||||||
import com.cloud.event.EventTypes;
|
import com.cloud.event.EventTypes;
|
||||||
@ -52,6 +47,11 @@ import com.cloud.utils.db.TransactionCallback;
|
|||||||
import com.cloud.utils.db.TransactionStatus;
|
import com.cloud.utils.db.TransactionStatus;
|
||||||
import com.cloud.utils.exception.CloudRuntimeException;
|
import com.cloud.utils.exception.CloudRuntimeException;
|
||||||
|
|
||||||
|
import org.apache.cloudstack.context.CallContext;
|
||||||
|
import org.apache.cloudstack.framework.messagebus.MessageBus;
|
||||||
|
import org.apache.cloudstack.framework.messagebus.PublishScope;
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
public class NetworkACLManagerImpl extends ManagerBase implements NetworkACLManager {
|
public class NetworkACLManagerImpl extends ManagerBase implements NetworkACLManager {
|
||||||
private static final Logger s_logger = Logger.getLogger(NetworkACLManagerImpl.class);
|
private static final Logger s_logger = Logger.getLogger(NetworkACLManagerImpl.class);
|
||||||
|
|
||||||
@ -335,10 +335,10 @@ public class NetworkACLManagerImpl extends ManagerBase implements NetworkACLMana
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean revokeACLItemsForPrivateGw(final PrivateGateway gateway) throws ResourceUnavailableException {
|
public boolean revokeACLItemsForPrivateGw(final PrivateGateway gateway) throws ResourceUnavailableException {
|
||||||
|
final long networkACLId = gateway.getNetworkACLId();
|
||||||
final List<NetworkACLItemVO> aclItems = _networkACLItemDao.listByACL(gateway.getNetworkACLId());
|
final List<NetworkACLItemVO> aclItems = _networkACLItemDao.listByACL(networkACLId);
|
||||||
if (aclItems.isEmpty()) {
|
if (aclItems.isEmpty()) {
|
||||||
s_logger.debug("Found no network ACL Items for private gateway id=" + gateway.getId());
|
s_logger.debug("Found no network ACL Items for private gateway 'id=" + gateway.getId() + "'");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -19,11 +19,6 @@ package org.apache.cloudstack.network.topology;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.log4j.Logger;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import com.cloud.dc.DataCenter;
|
import com.cloud.dc.DataCenter;
|
||||||
import com.cloud.deploy.DeployDestination;
|
import com.cloud.deploy.DeployDestination;
|
||||||
import com.cloud.exception.ConcurrentOperationException;
|
import com.cloud.exception.ConcurrentOperationException;
|
||||||
@ -52,6 +47,11 @@ import com.cloud.vm.NicProfile;
|
|||||||
import com.cloud.vm.VirtualMachine.State;
|
import com.cloud.vm.VirtualMachine.State;
|
||||||
import com.cloud.vm.VirtualMachineProfile;
|
import com.cloud.vm.VirtualMachineProfile;
|
||||||
|
|
||||||
|
import org.apache.log4j.Logger;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class AdvancedNetworkTopology extends BasicNetworkTopology {
|
public class AdvancedNetworkTopology extends BasicNetworkTopology {
|
||||||
|
|
||||||
@ -223,6 +223,7 @@ public class AdvancedNetworkTopology extends BasicNetworkTopology {
|
|||||||
|
|
||||||
final NetworkAclsRules aclsRules = new NetworkAclsRules(network, rules, isPrivateGateway);
|
final NetworkAclsRules aclsRules = new NetworkAclsRules(network, rules, isPrivateGateway);
|
||||||
|
|
||||||
return applyRules(network, router, typeString, isPodLevelException, podId, failWhenDisconnect, new RuleApplierWrapper<RuleApplier>(aclsRules));
|
final boolean result = applyRules(network, router, typeString, isPodLevelException, podId, failWhenDisconnect, new RuleApplierWrapper<RuleApplier>(aclsRules));
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -733,34 +733,34 @@ class CsForwardingRules(CsDataBag):
|
|||||||
|
|
||||||
#return the VR guest interface ip
|
#return the VR guest interface ip
|
||||||
def getGuestIp(self):
|
def getGuestIp(self):
|
||||||
ipr = []
|
interfaces = []
|
||||||
ipAddr = None
|
ipAddr = None
|
||||||
for ip in self.config.address().get_ips():
|
for interface in self.config.address().get_interfaces():
|
||||||
if ip.is_guest():
|
if interface.is_guest():
|
||||||
ipr.append(ip)
|
interfaces.append(interface)
|
||||||
if len(ipr) > 0:
|
if len(interfaces) > 0:
|
||||||
ipAddr = sorted(ipr)[-1]
|
ipAddr = sorted(interfaces)[-1]
|
||||||
if ipAddr:
|
if ipAddr:
|
||||||
return ipAddr.get_ip()
|
return ipAddr.get_ip()
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def getDeviceByIp(self, ipa):
|
def getDeviceByIp(self, ipa):
|
||||||
for ip in self.config.address().get_ips():
|
for interface in self.config.address().get_interfaces():
|
||||||
if ip.ip_in_subnet(ipa):
|
if interface.ip_in_subnet(ipa):
|
||||||
return ip.get_device()
|
return interface.get_device()
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def getNetworkByIp(self, ipa):
|
def getNetworkByIp(self, ipa):
|
||||||
for ip in self.config.address().get_ips():
|
for interface in self.config.address().get_interfaces():
|
||||||
if ip.ip_in_subnet(ipa):
|
if interface.ip_in_subnet(ipa):
|
||||||
return ip.get_network()
|
return interface.get_network()
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def getGatewayByIp(self, ipa):
|
def getGatewayByIp(self, ipa):
|
||||||
for ip in self.config.address().get_ips():
|
for interface in self.config.address().get_interfaces():
|
||||||
if ip.ip_in_subnet(ipa):
|
if interface.ip_in_subnet(ipa):
|
||||||
return ip.get_gateway()
|
return interface.get_gateway()
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def portsToString(self, ports, delimiter):
|
def portsToString(self, ports, delimiter):
|
||||||
|
|||||||
@ -28,7 +28,6 @@ from CsRoute import CsRoute
|
|||||||
from CsRule import CsRule
|
from CsRule import CsRule
|
||||||
|
|
||||||
VRRP_TYPES = ['guest']
|
VRRP_TYPES = ['guest']
|
||||||
PUBLIC_INTERFACE = ['eth1']
|
|
||||||
|
|
||||||
class CsAddress(CsDataBag):
|
class CsAddress(CsDataBag):
|
||||||
|
|
||||||
@ -37,14 +36,14 @@ class CsAddress(CsDataBag):
|
|||||||
ip = CsIP(dev, self.config)
|
ip = CsIP(dev, self.config)
|
||||||
ip.compare(self.dbag)
|
ip.compare(self.dbag)
|
||||||
|
|
||||||
def get_ips(self):
|
def get_interfaces(self):
|
||||||
ret = []
|
interfaces = []
|
||||||
for dev in self.dbag:
|
for dev in self.dbag:
|
||||||
if dev == "id":
|
if dev == "id":
|
||||||
continue
|
continue
|
||||||
for ip in self.dbag[dev]:
|
for ip in self.dbag[dev]:
|
||||||
ret.append(CsInterface(ip, self.config))
|
interfaces.append(CsInterface(ip, self.config))
|
||||||
return ret
|
return interfaces
|
||||||
|
|
||||||
def get_guest_if(self):
|
def get_guest_if(self):
|
||||||
"""
|
"""
|
||||||
@ -52,13 +51,13 @@ class CsAddress(CsDataBag):
|
|||||||
"""
|
"""
|
||||||
guest_interface = None
|
guest_interface = None
|
||||||
lowest_device = 1000
|
lowest_device = 1000
|
||||||
for ip in self.get_ips():
|
for interface in self.get_interfaces():
|
||||||
if ip.is_guest() and ip.is_added():
|
if interface.is_guest() and interface.is_added():
|
||||||
device = ip.get_device()
|
device = interface.get_device()
|
||||||
device_suffix = int(''.join([digit for digit in device if digit.isdigit()]))
|
device_suffix = int(''.join([digit for digit in device if digit.isdigit()]))
|
||||||
if device_suffix < lowest_device:
|
if device_suffix < lowest_device:
|
||||||
lowest_device = device_suffix
|
lowest_device = device_suffix
|
||||||
guest_interface = ip
|
guest_interface = interface
|
||||||
logging.debug("Guest interface will be set on device '%s' and IP '%s'" % (guest_interface.get_device(), guest_interface.get_ip()))
|
logging.debug("Guest interface will be set on device '%s' and IP '%s'" % (guest_interface.get_device(), guest_interface.get_ip()))
|
||||||
return guest_interface
|
return guest_interface
|
||||||
|
|
||||||
@ -94,9 +93,9 @@ class CsAddress(CsDataBag):
|
|||||||
"""
|
"""
|
||||||
Return the address object that has the control interface
|
Return the address object that has the control interface
|
||||||
"""
|
"""
|
||||||
for ip in self.get_ips():
|
for interface in self.get_interfaces():
|
||||||
if ip.is_control():
|
if interface.is_control():
|
||||||
return ip
|
return interface
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def process(self):
|
def process(self):
|
||||||
@ -117,6 +116,7 @@ class CsAddress(CsDataBag):
|
|||||||
else:
|
else:
|
||||||
logging.info(
|
logging.info(
|
||||||
"Address %s on device %s not configured", ip.ip(), dev)
|
"Address %s on device %s not configured", ip.ip(), dev)
|
||||||
|
|
||||||
if CsDevice(dev, self.config).waitfordevice():
|
if CsDevice(dev, self.config).waitfordevice():
|
||||||
ip.configure(address)
|
ip.configure(address)
|
||||||
|
|
||||||
@ -276,7 +276,7 @@ class CsIP:
|
|||||||
try:
|
try:
|
||||||
logging.info("Configuring address %s on device %s", self.ip(), self.dev)
|
logging.info("Configuring address %s on device %s", self.ip(), self.dev)
|
||||||
cmd = "ip addr add dev %s %s brd +" % (self.dev, self.ip())
|
cmd = "ip addr add dev %s %s brd +" % (self.dev, self.ip())
|
||||||
subprocess.call(cmd, shell=True)
|
CsHelper.execute(cmd)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.info("Exception occurred ==> %s" % e)
|
logging.info("Exception occurred ==> %s" % e)
|
||||||
|
|
||||||
@ -289,24 +289,27 @@ class CsIP:
|
|||||||
route = CsRoute()
|
route = CsRoute()
|
||||||
if not self.get_type() in ["control"]:
|
if not self.get_type() in ["control"]:
|
||||||
route.add_table(self.dev)
|
route.add_table(self.dev)
|
||||||
|
|
||||||
CsRule(self.dev).addMark()
|
CsRule(self.dev).addMark()
|
||||||
self.check_is_up()
|
|
||||||
|
interfaces = [CsInterface(address, self.config)]
|
||||||
|
CsHelper.reconfigure_interfaces(self.cl, interfaces)
|
||||||
|
|
||||||
self.set_mark()
|
self.set_mark()
|
||||||
self.arpPing()
|
self.arpPing()
|
||||||
|
|
||||||
CsRpsrfs(self.dev).enable()
|
CsRpsrfs(self.dev).enable()
|
||||||
self.post_config_change("add")
|
self.post_config_change("add")
|
||||||
|
|
||||||
'''For isolated/redundant and dhcpsrvr routers, call this method after the post_config is complete '''
|
'''For isolated/redundant and dhcpsrvr routers, call this method after the post_config is complete '''
|
||||||
if not self.config.is_vpc():
|
if not self.config.is_vpc():
|
||||||
self.setup_router_control()
|
self.setup_router_control()
|
||||||
|
|
||||||
if self.config.is_vpc() or self.cl.is_redundant():
|
if self.config.is_vpc() or self.cl.is_redundant():
|
||||||
# The code looks redundant here, but we actually have to cater for routers and
|
# The code looks redundant here, but we actually have to cater for routers and
|
||||||
# VPC routers in a different manner. Please do not remove this block otherwise
|
# VPC routers in a different manner. Please do not remove this block otherwise
|
||||||
# The VPC default route will be broken.
|
# The VPC default route will be broken.
|
||||||
if self.get_type() in ["public"]:
|
if self.get_type() in ["public"] and address["device"] == CsHelper.PUBLIC_INTERFACES[self.cl.get_type()]:
|
||||||
gateway = str(address["gateway"])
|
gateway = str(address["gateway"])
|
||||||
route.add_defaultroute(gateway)
|
route.add_defaultroute(gateway)
|
||||||
else:
|
else:
|
||||||
@ -315,21 +318,6 @@ class CsIP:
|
|||||||
if(self.cl.get_gateway()):
|
if(self.cl.get_gateway()):
|
||||||
route.add_defaultroute(self.cl.get_gateway())
|
route.add_defaultroute(self.cl.get_gateway())
|
||||||
|
|
||||||
def check_is_up(self):
|
|
||||||
""" Ensure device is up """
|
|
||||||
cmd = "ip link show %s | grep 'state DOWN'" % self.getDevice()
|
|
||||||
for i in CsHelper.execute(cmd):
|
|
||||||
if " DOWN " in i:
|
|
||||||
cmd2 = "ip link set %s up" % self.getDevice()
|
|
||||||
# If redundant only bring up public interfaces that are not eth1.
|
|
||||||
# Reason: private gateways are public interfaces.
|
|
||||||
# master.py and keepalived will deal with eth1 public interface.
|
|
||||||
if self.cl.is_redundant() and (not self.is_public() or self.getDevice() not in PUBLIC_INTERFACE):
|
|
||||||
CsHelper.execute(cmd2)
|
|
||||||
# if not redundant bring everything up
|
|
||||||
if not self.cl.is_redundant():
|
|
||||||
CsHelper.execute(cmd2)
|
|
||||||
|
|
||||||
def set_mark(self):
|
def set_mark(self):
|
||||||
cmd = "-A PREROUTING -i %s -m state --state NEW -j CONNMARK --set-xmark %s/0xffffffff" % \
|
cmd = "-A PREROUTING -i %s -m state --state NEW -j CONNMARK --set-xmark %s/0xffffffff" % \
|
||||||
(self.getDevice(), self.dnum)
|
(self.getDevice(), self.dnum)
|
||||||
@ -356,12 +344,12 @@ class CsIP:
|
|||||||
def setup_router_control(self):
|
def setup_router_control(self):
|
||||||
if self.config.is_vpc():
|
if self.config.is_vpc():
|
||||||
return
|
return
|
||||||
|
|
||||||
self.fw.append(
|
self.fw.append(
|
||||||
["filter", "", "-A FW_OUTBOUND -m state --state RELATED,ESTABLISHED -j ACCEPT"])
|
["filter", "", "-A FW_OUTBOUND -m state --state RELATED,ESTABLISHED -j ACCEPT"])
|
||||||
self.fw.append(
|
self.fw.append(
|
||||||
["filter", "", "-A INPUT -i eth1 -p tcp -m tcp --dport 3922 -m state --state NEW,ESTABLISHED -j ACCEPT"])
|
["filter", "", "-A INPUT -i eth1 -p tcp -m tcp --dport 3922 -m state --state NEW,ESTABLISHED -j ACCEPT"])
|
||||||
|
|
||||||
self.fw.append(["filter", "", "-P INPUT DROP"])
|
self.fw.append(["filter", "", "-P INPUT DROP"])
|
||||||
self.fw.append(["filter", "", "-P FORWARD DROP"])
|
self.fw.append(["filter", "", "-P FORWARD DROP"])
|
||||||
|
|
||||||
|
|||||||
@ -27,6 +27,30 @@ import shutil
|
|||||||
from netaddr import *
|
from netaddr import *
|
||||||
from pprint import pprint
|
from pprint import pprint
|
||||||
|
|
||||||
|
PUBLIC_INTERFACES = {"router" : "eth2", "vpcrouter" : "eth1"}
|
||||||
|
|
||||||
|
STATE_COMMANDS = {"router" : "ip addr | grep eth0 | grep inet | wc -l | xargs bash -c 'if [ $0 == 2 ]; then echo \"MASTER\"; else echo \"BACKUP\"; fi'",
|
||||||
|
"vpcrouter" : "ip addr | grep eth1 | grep state | awk '{print $9;}' | xargs bash -c 'if [ $0 == \"UP\" ]; then echo \"MASTER\"; else echo \"BACKUP\"; fi'"}
|
||||||
|
|
||||||
|
def reconfigure_interfaces(router_config, interfaces):
|
||||||
|
for interface in interfaces:
|
||||||
|
cmd = "ip link show %s | grep 'state DOWN'" % interface.get_device()
|
||||||
|
for device in execute(cmd):
|
||||||
|
if " DOWN " in device:
|
||||||
|
cmd = "ip link set %s up" % interface.get_device()
|
||||||
|
# If redundant only bring up public interfaces that are not eth1.
|
||||||
|
# Reason: private gateways are public interfaces.
|
||||||
|
# master.py and keepalived will deal with eth1 public interface.
|
||||||
|
|
||||||
|
if router_config.is_redundant() and interface.is_public():
|
||||||
|
state_cmd = STATE_COMMANDS[router_config.get_type()]
|
||||||
|
logging.info("Check state command => %s" % state_cmd)
|
||||||
|
state = execute(state_cmd)[0]
|
||||||
|
logging.info("Route state => %s" % state)
|
||||||
|
if interface.get_device() != PUBLIC_INTERFACES[router_config.get_type()] and state == "MASTER":
|
||||||
|
execute(cmd)
|
||||||
|
else:
|
||||||
|
execute(cmd)
|
||||||
|
|
||||||
def is_mounted(name):
|
def is_mounted(name):
|
||||||
for i in execute("mount"):
|
for i in execute("mount"):
|
||||||
|
|||||||
@ -41,7 +41,6 @@ from CsRoute import CsRoute
|
|||||||
import socket
|
import socket
|
||||||
from time import sleep
|
from time import sleep
|
||||||
|
|
||||||
|
|
||||||
class CsRedundant(object):
|
class CsRedundant(object):
|
||||||
|
|
||||||
CS_RAMDISK_DIR = "/ramdisk"
|
CS_RAMDISK_DIR = "/ramdisk"
|
||||||
@ -88,7 +87,7 @@ class CsRedundant(object):
|
|||||||
self._redundant_off()
|
self._redundant_off()
|
||||||
return
|
return
|
||||||
|
|
||||||
interfaces = [interface for interface in self.address.get_ips() if interface.is_guest()]
|
interfaces = [interface for interface in self.address.get_interfaces() if interface.is_guest()]
|
||||||
isDeviceReady = False
|
isDeviceReady = False
|
||||||
dev = ''
|
dev = ''
|
||||||
for interface in interfaces:
|
for interface in interfaces:
|
||||||
@ -228,9 +227,9 @@ class CsRedundant(object):
|
|||||||
self.set_lock()
|
self.set_lock()
|
||||||
logging.info("Router switched to fault mode")
|
logging.info("Router switched to fault mode")
|
||||||
|
|
||||||
ips = [ip for ip in self.address.get_ips() if ip.is_public()]
|
interfaces = [interface for interface in self.address.get_interfaces() if interface.is_public()]
|
||||||
for ip in ips:
|
for interface in interfaces:
|
||||||
CsHelper.execute("ifconfig %s down" % ip.get_device())
|
CsHelper.execute("ifconfig %s down" % interface.get_device())
|
||||||
|
|
||||||
cmd = "%s -C %s" % (self.CONNTRACKD_BIN, self.CONNTRACKD_CONF)
|
cmd = "%s -C %s" % (self.CONNTRACKD_BIN, self.CONNTRACKD_CONF)
|
||||||
CsHelper.execute("%s -s" % cmd)
|
CsHelper.execute("%s -s" % cmd)
|
||||||
@ -238,15 +237,18 @@ class CsRedundant(object):
|
|||||||
CsHelper.service("xl2tpd", "stop")
|
CsHelper.service("xl2tpd", "stop")
|
||||||
CsHelper.service("dnsmasq", "stop")
|
CsHelper.service("dnsmasq", "stop")
|
||||||
|
|
||||||
ips = [ip for ip in self.address.get_ips() if ip.needs_vrrp()]
|
interfaces = [interface for interface in self.address.get_interfaces() if interface.needs_vrrp()]
|
||||||
for ip in ips:
|
for interface in interfaces:
|
||||||
CsPasswdSvc(ip.get_gateway()).stop()
|
CsPasswdSvc(interface.get_gateway()).stop()
|
||||||
|
|
||||||
self.cl.set_fault_state()
|
self.cl.set_fault_state()
|
||||||
self.cl.save()
|
self.cl.save()
|
||||||
self.release_lock()
|
self.release_lock()
|
||||||
logging.info("Router switched to fault mode")
|
logging.info("Router switched to fault mode")
|
||||||
|
|
||||||
|
interfaces = [interface for interface in self.address.get_interfaces() if interface.is_public()]
|
||||||
|
CsHelper.reconfigure_interfaces(self.cl, interfaces)
|
||||||
|
|
||||||
def set_backup(self):
|
def set_backup(self):
|
||||||
""" Set the current router to backup """
|
""" Set the current router to backup """
|
||||||
if not self.cl.is_redundant():
|
if not self.cl.is_redundant():
|
||||||
@ -257,28 +259,31 @@ class CsRedundant(object):
|
|||||||
logging.debug("Setting router to backup")
|
logging.debug("Setting router to backup")
|
||||||
|
|
||||||
dev = ''
|
dev = ''
|
||||||
ips = [ip for ip in self.address.get_ips() if ip.is_public()]
|
interfaces = [interface for interface in self.address.get_interfaces() if interface.is_public()]
|
||||||
for ip in ips:
|
for interface in interfaces:
|
||||||
if dev == ip.get_device():
|
if dev == interface.get_device():
|
||||||
continue
|
continue
|
||||||
logging.info("Bringing public interface %s down" % ip.get_device())
|
logging.info("Bringing public interface %s down" % interface.get_device())
|
||||||
cmd2 = "ip link set %s down" % ip.get_device()
|
cmd2 = "ip link set %s down" % interface.get_device()
|
||||||
CsHelper.execute(cmd2)
|
CsHelper.execute(cmd2)
|
||||||
dev = ip.get_device()
|
dev = interface.get_device()
|
||||||
|
|
||||||
cmd = "%s -C %s" % (self.CONNTRACKD_BIN, self.CONNTRACKD_CONF)
|
cmd = "%s -C %s" % (self.CONNTRACKD_BIN, self.CONNTRACKD_CONF)
|
||||||
CsHelper.execute("%s -d" % cmd)
|
CsHelper.execute("%s -d" % cmd)
|
||||||
CsHelper.service("ipsec", "stop")
|
CsHelper.service("ipsec", "stop")
|
||||||
CsHelper.service("xl2tpd", "stop")
|
CsHelper.service("xl2tpd", "stop")
|
||||||
|
|
||||||
ips = [ip for ip in self.address.get_ips() if ip.needs_vrrp()]
|
interfaces = [interface for interface in self.address.get_interfaces() if interface.needs_vrrp()]
|
||||||
for ip in ips:
|
for interface in interfaces:
|
||||||
CsPasswdSvc(ip.get_gateway()).stop()
|
CsPasswdSvc(interface.get_gateway()).stop()
|
||||||
CsHelper.service("dnsmasq", "stop")
|
CsHelper.service("dnsmasq", "stop")
|
||||||
|
|
||||||
self.cl.set_master_state(False)
|
self.cl.set_master_state(False)
|
||||||
self.cl.save()
|
self.cl.save()
|
||||||
self.release_lock()
|
self.release_lock()
|
||||||
|
|
||||||
|
interfaces = [interface for interface in self.address.get_interfaces() if interface.is_public()]
|
||||||
|
CsHelper.reconfigure_interfaces(self.cl, interfaces)
|
||||||
logging.info("Router switched to backup mode")
|
logging.info("Router switched to backup mode")
|
||||||
|
|
||||||
def set_master(self):
|
def set_master(self):
|
||||||
@ -291,12 +296,12 @@ class CsRedundant(object):
|
|||||||
logging.debug("Setting router to master")
|
logging.debug("Setting router to master")
|
||||||
|
|
||||||
dev = ''
|
dev = ''
|
||||||
ips = [ip for ip in self.address.get_ips() if ip.is_public()]
|
interfaces = [interface for interface in self.address.get_interfaces() if interface.is_public()]
|
||||||
route = CsRoute()
|
route = CsRoute()
|
||||||
for ip in ips:
|
for interface in interfaces:
|
||||||
if dev == ip.get_device():
|
if dev == interface.get_device():
|
||||||
continue
|
continue
|
||||||
dev = ip.get_device()
|
dev = interface.get_device()
|
||||||
logging.info("Will proceed configuring device ==> %s" % dev)
|
logging.info("Will proceed configuring device ==> %s" % dev)
|
||||||
cmd2 = "ip link set %s up" % dev
|
cmd2 = "ip link set %s up" % dev
|
||||||
if CsDevice(dev, self.config).waitfordevice():
|
if CsDevice(dev, self.config).waitfordevice():
|
||||||
@ -304,9 +309,10 @@ class CsRedundant(object):
|
|||||||
logging.info("Bringing public interface %s up" % dev)
|
logging.info("Bringing public interface %s up" % dev)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
gateway = ip.get_gateway()
|
gateway = interface.get_gateway()
|
||||||
logging.info("Adding gateway ==> %s to device ==> %s" % (gateway, dev))
|
logging.info("Adding gateway ==> %s to device ==> %s" % (gateway, dev))
|
||||||
route.add_defaultroute(gateway)
|
if dev == CsHelper.PUBLIC_INTERFACES[self.cl.get_type()]:
|
||||||
|
route.add_defaultroute(gateway)
|
||||||
except:
|
except:
|
||||||
logging.error("ERROR getting gateway from device %s" % dev)
|
logging.error("ERROR getting gateway from device %s" % dev)
|
||||||
else:
|
else:
|
||||||
@ -320,14 +326,17 @@ class CsRedundant(object):
|
|||||||
CsHelper.execute("%s -B" % cmd)
|
CsHelper.execute("%s -B" % cmd)
|
||||||
CsHelper.service("ipsec", "restart")
|
CsHelper.service("ipsec", "restart")
|
||||||
CsHelper.service("xl2tpd", "restart")
|
CsHelper.service("xl2tpd", "restart")
|
||||||
ads = [o for o in self.address.get_ips() if o.needs_vrrp()]
|
interfaces = [interface for interface in self.address.get_interfaces() if interface.needs_vrrp()]
|
||||||
for o in ads:
|
for interface in interfaces:
|
||||||
CsPasswdSvc(o.get_gateway()).restart()
|
CsPasswdSvc(interface.get_gateway()).restart()
|
||||||
|
|
||||||
CsHelper.service("dnsmasq", "restart")
|
CsHelper.service("dnsmasq", "restart")
|
||||||
self.cl.set_master_state(True)
|
self.cl.set_master_state(True)
|
||||||
self.cl.save()
|
self.cl.save()
|
||||||
self.release_lock()
|
self.release_lock()
|
||||||
|
|
||||||
|
interfaces = [interface for interface in self.address.get_interfaces() if interface.is_public()]
|
||||||
|
CsHelper.reconfigure_interfaces(self.cl, interfaces)
|
||||||
logging.info("Router switched to master mode")
|
logging.info("Router switched to master mode")
|
||||||
|
|
||||||
def _collect_ignore_ips(self):
|
def _collect_ignore_ips(self):
|
||||||
@ -353,23 +362,14 @@ class CsRedundant(object):
|
|||||||
that could function as a router and VPC router at the same time
|
that could function as a router and VPC router at the same time
|
||||||
"""
|
"""
|
||||||
lines = []
|
lines = []
|
||||||
for ip in self.address.get_ips():
|
for interface in self.address.get_interfaces():
|
||||||
if ip.needs_vrrp():
|
if interface.needs_vrrp():
|
||||||
cmdline=self.config.get_cmdline_instance()
|
cmdline=self.config.get_cmdline_instance()
|
||||||
if not ip.is_added():
|
if not interface.is_added():
|
||||||
continue
|
continue
|
||||||
if(cmdline.get_type()=='router'):
|
if(cmdline.get_type()=='router'):
|
||||||
str = " %s brd %s dev %s\n" % (cmdline.get_guest_gw(), ip.get_broadcast(), ip.get_device())
|
str = " %s brd %s dev %s\n" % (cmdline.get_guest_gw(), interface.get_broadcast(), interface.get_device())
|
||||||
else:
|
else:
|
||||||
str = " %s brd %s dev %s\n" % (ip.get_gateway_cidr(), ip.get_broadcast(), ip.get_device())
|
str = " %s brd %s dev %s\n" % (interface.get_gateway_cidr(), interface.get_broadcast(), interface.get_device())
|
||||||
lines.append(str)
|
lines.append(str)
|
||||||
return lines
|
return lines
|
||||||
|
|
||||||
def check_is_up(self, device):
|
|
||||||
""" Ensure device is up """
|
|
||||||
cmd = "ip link show %s | grep 'state DOWN'" % device
|
|
||||||
|
|
||||||
for i in CsHelper.execute(cmd):
|
|
||||||
if " DOWN " in i:
|
|
||||||
cmd2 = "ip link set %s up" % device
|
|
||||||
CsHelper.execute(cmd2)
|
|
||||||
|
|||||||
@ -25,6 +25,7 @@ from marvin.lib.base import *
|
|||||||
from marvin.lib.common import *
|
from marvin.lib.common import *
|
||||||
from nose.plugins.attrib import attr
|
from nose.plugins.attrib import attr
|
||||||
|
|
||||||
|
import time
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
class Services:
|
class Services:
|
||||||
@ -33,6 +34,13 @@ class Services:
|
|||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.services = {
|
self.services = {
|
||||||
|
"configurableData": {
|
||||||
|
"host": {
|
||||||
|
"password": "password",
|
||||||
|
"username": "root",
|
||||||
|
"port": 22
|
||||||
|
}
|
||||||
|
},
|
||||||
"account": {
|
"account": {
|
||||||
"email": "test@test.com",
|
"email": "test@test.com",
|
||||||
"firstname": "Test",
|
"firstname": "Test",
|
||||||
@ -187,7 +195,8 @@ class TestPrivateGwACL(cloudstackTestCase):
|
|||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.apiclient = self.testClient.getApiClient()
|
self.apiclient = self.testClient.getApiClient()
|
||||||
|
self.hypervisor = self.testClient.getHypervisorInfo()
|
||||||
|
|
||||||
self.logger.debug("Creating Admin Account for Domain ID ==> %s" % self.domain.id)
|
self.logger.debug("Creating Admin Account for Domain ID ==> %s" % self.domain.id)
|
||||||
self.account = Account.create(
|
self.account = Account.create(
|
||||||
self.apiclient,
|
self.apiclient,
|
||||||
@ -224,9 +233,9 @@ class TestPrivateGwACL(cloudstackTestCase):
|
|||||||
vpc_off.update(self.apiclient, state='Enabled')
|
vpc_off.update(self.apiclient, state='Enabled')
|
||||||
|
|
||||||
vpc = self.createVPC(vpc_off)
|
vpc = self.createVPC(vpc_off)
|
||||||
|
|
||||||
self.cleanup = [vpc, vpc_off, self.account]
|
self.cleanup = [vpc, vpc_off, self.account]
|
||||||
|
|
||||||
physical_networks = get_physical_networks(self.apiclient, self.zone.id)
|
physical_networks = get_physical_networks(self.apiclient, self.zone.id)
|
||||||
if not physical_networks:
|
if not physical_networks:
|
||||||
self.fail("No Physical Networks found!")
|
self.fail("No Physical Networks found!")
|
||||||
@ -262,7 +271,7 @@ class TestPrivateGwACL(cloudstackTestCase):
|
|||||||
self.logger.debug("Enabling the VPC offering created")
|
self.logger.debug("Enabling the VPC offering created")
|
||||||
vpc_off.update(self.apiclient, state='Enabled')
|
vpc_off.update(self.apiclient, state='Enabled')
|
||||||
|
|
||||||
self.performVPCTests(vpc_off, True)
|
self.performVPCTests(vpc_off, restart_with_cleanup = True)
|
||||||
|
|
||||||
@attr(tags=["advanced"], required_hardware="true")
|
@attr(tags=["advanced"], required_hardware="true")
|
||||||
def test_04_rvpc_privategw_static_routes(self):
|
def test_04_rvpc_privategw_static_routes(self):
|
||||||
@ -276,6 +285,18 @@ class TestPrivateGwACL(cloudstackTestCase):
|
|||||||
|
|
||||||
self.performVPCTests(vpc_off)
|
self.performVPCTests(vpc_off)
|
||||||
|
|
||||||
|
@attr(tags=["advanced"], required_hardware="true")
|
||||||
|
def _test_05_rvpc_privategw_check_interface(self):
|
||||||
|
self.logger.debug("Creating a Redundant VPC offering..")
|
||||||
|
vpc_off = VpcOffering.create(
|
||||||
|
self.apiclient,
|
||||||
|
self.services["redundant_vpc_offering"])
|
||||||
|
|
||||||
|
self.logger.debug("Enabling the Redundant VPC offering created")
|
||||||
|
vpc_off.update(self.apiclient, state='Enabled')
|
||||||
|
|
||||||
|
self.performPrivateGWInterfaceTests(vpc_off)
|
||||||
|
|
||||||
def performVPCTests(self, vpc_off, restart_with_cleanup = False):
|
def performVPCTests(self, vpc_off, restart_with_cleanup = False):
|
||||||
self.logger.debug("Creating VPCs with offering ID %s" % vpc_off.id)
|
self.logger.debug("Creating VPCs with offering ID %s" % vpc_off.id)
|
||||||
vpc_1 = self.createVPC(vpc_off, cidr = '10.0.1.0/24')
|
vpc_1 = self.createVPC(vpc_off, cidr = '10.0.1.0/24')
|
||||||
@ -298,7 +319,7 @@ class TestPrivateGwACL(cloudstackTestCase):
|
|||||||
|
|
||||||
self.cleanup.insert(0, vm1)
|
self.cleanup.insert(0, vm1)
|
||||||
self.cleanup.insert(0, vm2)
|
self.cleanup.insert(0, vm2)
|
||||||
|
|
||||||
acl1 = self.createACL(vpc_1)
|
acl1 = self.createACL(vpc_1)
|
||||||
self.createACLItem(acl1.id, cidr = "0.0.0.0/0")
|
self.createACLItem(acl1.id, cidr = "0.0.0.0/0")
|
||||||
privateGw_1 = self.createPvtGw(vpc_1, "10.0.3.100", "10.0.3.101", acl1.id, vlan_1)
|
privateGw_1 = self.createPvtGw(vpc_1, "10.0.3.100", "10.0.3.101", acl1.id, vlan_1)
|
||||||
@ -321,15 +342,117 @@ class TestPrivateGwACL(cloudstackTestCase):
|
|||||||
nat_rule_1 = self.create_natrule(vpc_1, vm1, public_ip_1, network_1)
|
nat_rule_1 = self.create_natrule(vpc_1, vm1, public_ip_1, network_1)
|
||||||
nat_rule_2 = self.create_natrule(vpc_2, vm2, public_ip_2, network_2)
|
nat_rule_2 = self.create_natrule(vpc_2, vm2, public_ip_2, network_2)
|
||||||
|
|
||||||
self.check_pvt_gw_connectivity(vm1, public_ip_1, vm2.nic[0].ipaddress)
|
self.check_pvt_gw_connectivity(vm1, public_ip_1, [vm2.nic[0].ipaddress, vm1.nic[0].ipaddress])
|
||||||
self.check_pvt_gw_connectivity(vm2, public_ip_2, vm1.nic[0].ipaddress)
|
|
||||||
|
|
||||||
if restart_with_cleanup:
|
if restart_with_cleanup:
|
||||||
self.reboot_vpc_with_cleanup(vpc_1, True)
|
self.reboot_vpc_with_cleanup(vpc_1, cleanup = restart_with_cleanup)
|
||||||
self.reboot_vpc_with_cleanup(vpc_2, True)
|
self.reboot_vpc_with_cleanup(vpc_2, cleanup = restart_with_cleanup)
|
||||||
|
|
||||||
self.check_pvt_gw_connectivity(vm1, public_ip_1, vm2.nic[0].ipaddress)
|
self.check_pvt_gw_connectivity(vm1, public_ip_1, [vm2.nic[0].ipaddress, vm1.nic[0].ipaddress])
|
||||||
self.check_pvt_gw_connectivity(vm2, public_ip_2, vm1.nic[0].ipaddress)
|
|
||||||
|
def performPrivateGWInterfaceTests(self, vpc_off):
|
||||||
|
self.logger.debug("Creating VPCs with offering ID %s" % vpc_off.id)
|
||||||
|
vpc_1 = self.createVPC(vpc_off, cidr = '10.0.0.0/16')
|
||||||
|
|
||||||
|
self.cleanup = [vpc_1, vpc_off, self.account]
|
||||||
|
|
||||||
|
physical_networks = get_physical_networks(self.apiclient, self.zone.id)
|
||||||
|
if not physical_networks:
|
||||||
|
self.fail("No Physical Networks found!")
|
||||||
|
|
||||||
|
vlans = physical_networks[0].vlan.split('-')
|
||||||
|
vlan_1 = int(vlans[0])
|
||||||
|
|
||||||
|
net_offering_no_lb = "network_offering_no_lb"
|
||||||
|
|
||||||
|
network_1 = self.createNetwork(vpc_1, gateway = '10.0.0.1')
|
||||||
|
network_2 = self.createNetwork(vpc_1, net_offering = net_offering_no_lb, gateway = '10.0.1.1')
|
||||||
|
network_3 = self.createNetwork(vpc_1, net_offering = net_offering_no_lb, gateway = '10.0.2.1')
|
||||||
|
network_4 = self.createNetwork(vpc_1, net_offering = net_offering_no_lb, gateway = '10.0.3.1')
|
||||||
|
|
||||||
|
vm1 = self.createVM(network_1)
|
||||||
|
vm2 = self.createVM(network_2)
|
||||||
|
vm3 = self.createVM(network_3)
|
||||||
|
vm4 = self.createVM(network_4)
|
||||||
|
|
||||||
|
self.cleanup.insert(0, vm1)
|
||||||
|
self.cleanup.insert(0, vm2)
|
||||||
|
self.cleanup.insert(0, vm3)
|
||||||
|
self.cleanup.insert(0, vm4)
|
||||||
|
|
||||||
|
acl1 = self.createACL(vpc_1)
|
||||||
|
self.createACLItem(acl1.id, cidr = "0.0.0.0/0")
|
||||||
|
privateGw_1 = self.createPvtGw(vpc_1, "10.1.0.100", "10.1.0.101", acl1.id, vlan_1)
|
||||||
|
self.replacePvtGwACL(acl1.id, privateGw_1.id)
|
||||||
|
|
||||||
|
self.replaceNetworkAcl(acl1.id, network_1)
|
||||||
|
self.replaceNetworkAcl(acl1.id, network_2)
|
||||||
|
self.replaceNetworkAcl(acl1.id, network_3)
|
||||||
|
self.replaceNetworkAcl(acl1.id, network_4)
|
||||||
|
|
||||||
|
public_ip_1 = self.acquire_publicip(vpc_1, network_1)
|
||||||
|
nat_rule_1 = self.create_natrule(vpc_1, vm1, public_ip_1, network_1)
|
||||||
|
|
||||||
|
self.check_private_gateway_interfaces()
|
||||||
|
|
||||||
|
self.check_pvt_gw_connectivity(vm1, public_ip_1, [vm2.nic[0].ipaddress, vm3.nic[0].ipaddress, vm4.nic[0].ipaddress])
|
||||||
|
|
||||||
|
self.reboot_vpc_with_cleanup(vpc_1, cleanup = True)
|
||||||
|
self.check_routers_state()
|
||||||
|
|
||||||
|
self.check_pvt_gw_connectivity(vm1, public_ip_1, [vm2.nic[0].ipaddress, vm3.nic[0].ipaddress, vm4.nic[0].ipaddress])
|
||||||
|
|
||||||
|
self.stop_router_by_type("MASTER")
|
||||||
|
self.check_routers_state()
|
||||||
|
|
||||||
|
self.check_private_gateway_interfaces()
|
||||||
|
self.check_pvt_gw_connectivity(vm1, public_ip_1, [vm2.nic[0].ipaddress, vm3.nic[0].ipaddress, vm4.nic[0].ipaddress])
|
||||||
|
|
||||||
|
self.start_routers()
|
||||||
|
self.check_routers_state()
|
||||||
|
self.check_private_gateway_interfaces()
|
||||||
|
self.check_pvt_gw_connectivity(vm1, public_ip_1, [vm2.nic[0].ipaddress, vm3.nic[0].ipaddress, vm4.nic[0].ipaddress])
|
||||||
|
|
||||||
|
self.deletePvtGw(privateGw_1.id)
|
||||||
|
self.check_private_gateway_interfaces(status_to_check = "DOWN")
|
||||||
|
|
||||||
|
def query_routers(self):
|
||||||
|
routers = list_routers(self.apiclient,
|
||||||
|
account=self.account.name,
|
||||||
|
domainid=self.account.domainid)
|
||||||
|
|
||||||
|
self.assertEqual(isinstance(routers, list), True,
|
||||||
|
"Check for list routers response return valid data")
|
||||||
|
|
||||||
|
self.assertEqual(len(routers), 2,
|
||||||
|
"Check for list routers size returned '%s' instead of 2" % len(routers))
|
||||||
|
|
||||||
|
return routers
|
||||||
|
|
||||||
|
def stop_router_by_type(self, redundant_state):
|
||||||
|
self.logger.debug('Stopping %s router' % redundant_state)
|
||||||
|
routers = self.query_routers()
|
||||||
|
for router in routers:
|
||||||
|
if router.redundantstate == redundant_state:
|
||||||
|
self.stop_router(router)
|
||||||
|
break
|
||||||
|
|
||||||
|
def start_routers(self):
|
||||||
|
self.logger.debug('Starting stopped routers')
|
||||||
|
routers = self.query_routers()
|
||||||
|
for router in routers:
|
||||||
|
self.logger.debug('Router %s has state %s' % (router.id, router.state))
|
||||||
|
if router.state == "Stopped":
|
||||||
|
self.logger.debug('Starting stopped router %s' % router.id)
|
||||||
|
cmd = startRouter.startRouterCmd()
|
||||||
|
cmd.id = router.id
|
||||||
|
self.apiclient.startRouter(cmd)
|
||||||
|
|
||||||
|
def stop_router(self, router):
|
||||||
|
self.logger.debug('Stopping router %s' % router.id)
|
||||||
|
cmd = stopRouter.stopRouterCmd()
|
||||||
|
cmd.id = router.id
|
||||||
|
self.apiclient.stopRouter(cmd)
|
||||||
|
|
||||||
def createVPC(self, vpc_offering, cidr = '10.1.1.1/16'):
|
def createVPC(self, vpc_offering, cidr = '10.1.1.1/16'):
|
||||||
try:
|
try:
|
||||||
@ -412,10 +535,10 @@ class TestPrivateGwACL(cloudstackTestCase):
|
|||||||
except Exception, e:
|
except Exception, e:
|
||||||
self.fail('Unable to create ACL Item due to %s ' % e)
|
self.fail('Unable to create ACL Item due to %s ' % e)
|
||||||
|
|
||||||
def createNetwork(self, vpc, gateway = '10.1.1.1'):
|
def createNetwork(self, vpc, net_offering = "network_offering", gateway = '10.1.1.1'):
|
||||||
try:
|
try:
|
||||||
self.logger.debug('Create NetworkOffering')
|
self.logger.debug('Create NetworkOffering')
|
||||||
net_offerring = self.services["network_offering"]
|
net_offerring = self.services[net_offering]
|
||||||
net_offerring["name"] = "NET_OFF-%s" % gateway
|
net_offerring["name"] = "NET_OFF-%s" % gateway
|
||||||
nw_off = NetworkOffering.create(
|
nw_off = NetworkOffering.create(
|
||||||
self.apiclient,
|
self.apiclient,
|
||||||
@ -467,14 +590,27 @@ class TestPrivateGwACL(cloudstackTestCase):
|
|||||||
createPrivateGatewayCmd.aclid = aclId
|
createPrivateGatewayCmd.aclid = aclId
|
||||||
|
|
||||||
try:
|
try:
|
||||||
privateGw = self.apiclient.createPrivateGateway(createPrivateGatewayCmd)
|
privateGw = self.apiclient.createPrivateGateway(createPrivateGatewayCmd)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.fail("Failed to create Private Gateway ==> %s" % e)
|
self.fail("Failed to create Private Gateway ==> %s" % e)
|
||||||
|
|
||||||
self.assertIsNotNone(privateGw.id, "Failed to create ACL.")
|
self.assertIsNotNone(privateGw.id, "Failed to create Private Gateway.")
|
||||||
|
|
||||||
return privateGw
|
return privateGw
|
||||||
|
|
||||||
|
def deletePvtGw(self, private_gw_id):
|
||||||
|
deletePrivateGatewayCmd = deletePrivateGateway.deletePrivateGatewayCmd()
|
||||||
|
deletePrivateGatewayCmd.id = private_gw_id
|
||||||
|
|
||||||
|
privateGwResponse = None
|
||||||
|
try:
|
||||||
|
privateGwResponse = self.apiclient.deletePrivateGateway(deletePrivateGatewayCmd)
|
||||||
|
except Exception as e:
|
||||||
|
self.fail("Failed to create Private Gateway ==> %s" % e)
|
||||||
|
|
||||||
|
self.assertIsNotNone(privateGwResponse, "Failed to Delete Private Gateway.")
|
||||||
|
self.assertTrue(privateGwResponse.success, "Failed to Delete Private Gateway.")
|
||||||
|
|
||||||
def replaceNetworkAcl(self, aclId, network):
|
def replaceNetworkAcl(self, aclId, network):
|
||||||
self.logger.debug("Replacing Network ACL with ACL ID ==> %s" % aclId)
|
self.logger.debug("Replacing Network ACL with ACL ID ==> %s" % aclId)
|
||||||
|
|
||||||
@ -531,33 +667,42 @@ class TestPrivateGwACL(cloudstackTestCase):
|
|||||||
traffictype='Ingress'
|
traffictype='Ingress'
|
||||||
)
|
)
|
||||||
self.logger.debug('nwacl_nat=%s' % nwacl_nat.__dict__)
|
self.logger.debug('nwacl_nat=%s' % nwacl_nat.__dict__)
|
||||||
|
|
||||||
return nat_rule
|
return nat_rule
|
||||||
|
|
||||||
def check_pvt_gw_connectivity(self, virtual_machine, public_ip, vm_ip):
|
def check_pvt_gw_connectivity(self, virtual_machine, public_ip, vms_ips):
|
||||||
ssh_command = "ping -c 3 %s" % vm_ip
|
sleep_time = 5
|
||||||
|
succeeded_pings = 0
|
||||||
|
minimum_vms_to_pass = 2
|
||||||
|
for vm_ip in vms_ips:
|
||||||
|
ssh_command = "ping -c 3 %s" % vm_ip
|
||||||
|
|
||||||
# Should be able to SSH VM
|
# Should be able to SSH VM
|
||||||
result = 'failed'
|
result = 'failed'
|
||||||
try:
|
try:
|
||||||
self.logger.debug("SSH into VM: %s" % public_ip.ipaddress.ipaddress)
|
self.logger.debug("SSH into VM: %s" % public_ip.ipaddress.ipaddress)
|
||||||
|
|
||||||
ssh = virtual_machine.get_ssh_client(ipaddress=public_ip.ipaddress.ipaddress)
|
|
||||||
|
|
||||||
self.logger.debug("Ping to VM inside another VPC")
|
ssh = virtual_machine.get_ssh_client(ipaddress=public_ip.ipaddress.ipaddress)
|
||||||
result = str(ssh.execute(ssh_command))
|
|
||||||
|
|
||||||
self.logger.debug("SSH result: %s; COUNT is ==> %s" % (result, result.count("3 packets received")))
|
self.logger.debug("Sleeping for %s seconds in order to get the firewall applied..." % sleep_time)
|
||||||
except Exception as e:
|
time.sleep(sleep_time)
|
||||||
self.fail("SSH Access failed for %s: %s" % \
|
sleep_time += sleep_time
|
||||||
(vmObj.get_ip(), e)
|
|
||||||
)
|
|
||||||
|
|
||||||
self.assertEqual(
|
self.logger.debug("Ping to VM inside another Network Tier")
|
||||||
result.count("3 packets received"),
|
result = str(ssh.execute(ssh_command))
|
||||||
1,
|
|
||||||
"Ping to outside world from VM should be successful"
|
self.logger.debug("SSH result: %s; COUNT is ==> %s" % (result, result.count("3 packets received")))
|
||||||
)
|
except Exception as e:
|
||||||
|
self.fail("SSH Access failed for %s: %s" % \
|
||||||
|
(virtual_machine, e)
|
||||||
|
)
|
||||||
|
|
||||||
|
succeeded_pings += result.count("3 packets received")
|
||||||
|
|
||||||
|
|
||||||
|
self.assertTrue(succeeded_pings >= minimum_vms_to_pass,
|
||||||
|
"Ping to VM on Network Tier N from VM in Network Tier A should be successful at least for 2 out of 3 VMs"
|
||||||
|
)
|
||||||
|
|
||||||
def reboot_vpc_with_cleanup(self, vpc, cleanup = True):
|
def reboot_vpc_with_cleanup(self, vpc, cleanup = True):
|
||||||
self.logger.debug("Restarting VPC %s with cleanup" % vpc.id)
|
self.logger.debug("Restarting VPC %s with cleanup" % vpc.id)
|
||||||
@ -569,3 +714,120 @@ class TestPrivateGwACL(cloudstackTestCase):
|
|||||||
cmd.makeredundant = False
|
cmd.makeredundant = False
|
||||||
self.api_client.restartVPC(cmd)
|
self.api_client.restartVPC(cmd)
|
||||||
|
|
||||||
|
def check_private_gateway_interfaces(self, status_to_check = "UP"):
|
||||||
|
routers = self.query_routers()
|
||||||
|
|
||||||
|
state_holder = {routers[0].linklocalip : {"state" : None, "mac" : None},
|
||||||
|
routers[1].linklocalip : {"state" : None, "mac" : None}}
|
||||||
|
state = None
|
||||||
|
mac = None
|
||||||
|
for router in routers:
|
||||||
|
hosts = list_hosts(
|
||||||
|
self.apiclient,
|
||||||
|
zoneid=router.zoneid,
|
||||||
|
type='Routing',
|
||||||
|
state='Up',
|
||||||
|
id=router.hostid)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
isinstance(hosts, list),
|
||||||
|
True,
|
||||||
|
"Check for list hosts response return valid data")
|
||||||
|
|
||||||
|
host = hosts[0]
|
||||||
|
host.user = self.services["configurableData"]["host"]["username"]
|
||||||
|
host.passwd = self.services["configurableData"]["host"]["password"]
|
||||||
|
host.port = self.services["configurableData"]["host"]["port"]
|
||||||
|
|
||||||
|
try:
|
||||||
|
state = get_process_status(
|
||||||
|
host.ipaddress,
|
||||||
|
host.port,
|
||||||
|
host.user,
|
||||||
|
host.passwd,
|
||||||
|
router.linklocalip,
|
||||||
|
"ip addr | grep eth6 | grep state | awk '{print $9;}'")
|
||||||
|
|
||||||
|
mac = get_process_status(
|
||||||
|
host.ipaddress,
|
||||||
|
host.port,
|
||||||
|
host.user,
|
||||||
|
host.passwd,
|
||||||
|
router.linklocalip,
|
||||||
|
"ip addr | grep link/ether | awk '{print $2;}' | sed -n 7p")
|
||||||
|
except KeyError:
|
||||||
|
self.skipTest("Provide a marvin config file with host credentials to run %s" % self._testMethodName)
|
||||||
|
|
||||||
|
state = str(state[0])
|
||||||
|
mac = str(mac[0])
|
||||||
|
|
||||||
|
self.logger.debug("Result from the Router on IP '%s' is -> state: '%s', mac: '%s'" % (router.linklocalip, state, mac))
|
||||||
|
state_holder[router.linklocalip]["state"] = str(state)
|
||||||
|
state_holder[router.linklocalip]["mac"] = str(mac)
|
||||||
|
|
||||||
|
|
||||||
|
if status_to_check == "UP":
|
||||||
|
check_state = state_holder[routers[0].linklocalip]["state"].count(state_holder[routers[1].linklocalip]["state"])
|
||||||
|
check_mac = state_holder[routers[0].linklocalip]["mac"].count(state_holder[routers[1].linklocalip]["mac"])
|
||||||
|
|
||||||
|
self.assertTrue(check_state == 0, "Routers private gateway interface should not be on the same state!")
|
||||||
|
self.assertTrue(check_mac == 0, "Routers private gateway interface should not have the same mac address!")
|
||||||
|
else:
|
||||||
|
self.assertTrue(check_state == 1, "Routers private gateway interface should should have been removed!")
|
||||||
|
|
||||||
|
def check_routers_state(self, status_to_check="MASTER", expected_count=1):
|
||||||
|
routers = self.query_routers()
|
||||||
|
|
||||||
|
vals = ["MASTER", "BACKUP", "UNKNOWN"]
|
||||||
|
cnts = [0, 0, 0]
|
||||||
|
|
||||||
|
result = "UNKNOWN"
|
||||||
|
for router in routers:
|
||||||
|
if router.state == "Running":
|
||||||
|
hosts = list_hosts(
|
||||||
|
self.apiclient,
|
||||||
|
zoneid=router.zoneid,
|
||||||
|
type='Routing',
|
||||||
|
state='Up',
|
||||||
|
id=router.hostid
|
||||||
|
)
|
||||||
|
self.assertEqual(
|
||||||
|
isinstance(hosts, list),
|
||||||
|
True,
|
||||||
|
"Check list host returns a valid list"
|
||||||
|
)
|
||||||
|
host = hosts[0]
|
||||||
|
|
||||||
|
if self.hypervisor.lower() in ('vmware', 'hyperv'):
|
||||||
|
result = str(get_process_status(
|
||||||
|
self.apiclient.connection.mgtSvr,
|
||||||
|
22,
|
||||||
|
self.apiclient.connection.user,
|
||||||
|
self.apiclient.connection.passwd,
|
||||||
|
router.linklocalip,
|
||||||
|
"sh /opt/cloud/bin/checkrouter.sh ",
|
||||||
|
hypervisor=self.hypervisor
|
||||||
|
))
|
||||||
|
else:
|
||||||
|
try:
|
||||||
|
host.user, host.passwd = get_host_credentials(
|
||||||
|
self.config, host.ipaddress)
|
||||||
|
result = str(get_process_status(
|
||||||
|
host.ipaddress,
|
||||||
|
22,
|
||||||
|
host.user,
|
||||||
|
host.passwd,
|
||||||
|
router.linklocalip,
|
||||||
|
"sh /opt/cloud/bin/checkrouter.sh "
|
||||||
|
))
|
||||||
|
|
||||||
|
except KeyError:
|
||||||
|
self.skipTest(
|
||||||
|
"Marvin configuration has no host credentials to\
|
||||||
|
check router services")
|
||||||
|
|
||||||
|
if result.count(status_to_check) == 1:
|
||||||
|
cnts[vals.index(status_to_check)] += 1
|
||||||
|
|
||||||
|
if cnts[vals.index(status_to_check)] != expected_count:
|
||||||
|
self.fail("Expected '%s' routers at state '%s', but found '%s'!" % (expected_count, status_to_check, cnts[vals.index(status_to_check)]))
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user