mirror of https://github.com/apache/cloudstack.git
Fix vpcid
This commit is contained in:
parent
0cc39bb570
commit
27e53953ac
|
|
@ -69,7 +69,9 @@ public interface FirewallRule extends ControlledEntity, Identity, InternalIdenti
|
|||
|
||||
State getState();
|
||||
|
||||
long getNetworkId();
|
||||
Long getNetworkId();
|
||||
|
||||
Long getVpcId();
|
||||
|
||||
Long getSourceIpAddressId();
|
||||
|
||||
|
|
|
|||
|
|
@ -212,7 +212,7 @@ public class CreateEgressFirewallRuleCmd extends BaseAsyncCreateCmd implements F
|
|||
}
|
||||
|
||||
@Override
|
||||
public long getNetworkId() {
|
||||
public Long getNetworkId() {
|
||||
return networkId;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -223,13 +223,9 @@ public class CreateFirewallRuleCmd extends BaseAsyncCreateCmd implements Firewal
|
|||
}
|
||||
|
||||
@Override
|
||||
public long getNetworkId() {
|
||||
IpAddress ip = _entityMgr.findById(IpAddress.class, getIpAddressId());
|
||||
Long ntwkId = null;
|
||||
|
||||
if (ip.getAssociatedWithNetworkId() != null) {
|
||||
ntwkId = ip.getAssociatedWithNetworkId();
|
||||
}
|
||||
public Long getNetworkId() {
|
||||
IpAddress ip = getIp();
|
||||
Long ntwkId = isVpcIp(ip) ? getVpcNetworkIdForFirewallRule(ip) : getIsolatedNetworkIdForFirewallRule(ip);
|
||||
|
||||
if (ntwkId == null) {
|
||||
throw new InvalidParameterValueException("Unable to create firewall rule for the IP address ID=" + ipAddressId +
|
||||
|
|
@ -238,6 +234,12 @@ public class CreateFirewallRuleCmd extends BaseAsyncCreateCmd implements Firewal
|
|||
return ntwkId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getVpcId() {
|
||||
IpAddress ip = getIp();
|
||||
return isVpcIp(ip) ? ip.getVpcId() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getEntityOwnerId() {
|
||||
Account account = CallContext.current().getCallingAccount();
|
||||
|
|
@ -300,7 +302,21 @@ public class CreateFirewallRuleCmd extends BaseAsyncCreateCmd implements Firewal
|
|||
|
||||
@Override
|
||||
public Long getSyncObjId() {
|
||||
return getIp().getAssociatedWithNetworkId();
|
||||
Long syncObjId = getIp().getAssociatedWithNetworkId();
|
||||
return syncObjId != null ? syncObjId : getNetworkId();
|
||||
}
|
||||
|
||||
private boolean isVpcIp(IpAddress ip) {
|
||||
return ip.getVpcId() != null;
|
||||
}
|
||||
|
||||
private Long getIsolatedNetworkIdForFirewallRule(IpAddress ip) {
|
||||
return ip.getAssociatedWithNetworkId();
|
||||
}
|
||||
|
||||
private Long getVpcNetworkIdForFirewallRule(IpAddress ip) {
|
||||
// VPC flow is independent from tier association; manager resolves execution network.
|
||||
return ip.getNetworkId();
|
||||
}
|
||||
|
||||
private IpAddress getIp() {
|
||||
|
|
@ -311,6 +327,7 @@ public class CreateFirewallRuleCmd extends BaseAsyncCreateCmd implements Firewal
|
|||
return ip;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Integer getIcmpCode() {
|
||||
if (icmpCode != null) {
|
||||
|
|
|
|||
|
|
@ -176,7 +176,7 @@ public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements P
|
|||
}
|
||||
}
|
||||
|
||||
private Long getVpcId() {
|
||||
public Long getVpcId() {
|
||||
if (ipAddressId != null) {
|
||||
IpAddress ipAddr = _networkService.getIp(ipAddressId);
|
||||
if (ipAddr == null || !ipAddr.readyToUse()) {
|
||||
|
|
@ -275,7 +275,7 @@ public class CreatePortForwardingRuleCmd extends BaseAsyncCreateCmd implements P
|
|||
}
|
||||
|
||||
@Override
|
||||
public long getNetworkId() {
|
||||
public Long getNetworkId() {
|
||||
IpAddress ip = _entityMgr.findById(IpAddress.class, getIpAddressId());
|
||||
Long ntwkId = _networkService.getPreferredNetworkIdForPublicIpRuleAssignment(ip, networkId);
|
||||
if (ntwkId == null) {
|
||||
|
|
|
|||
|
|
@ -229,8 +229,13 @@ public class CreateIpForwardingRuleCmd extends BaseAsyncCreateCmd implements Sta
|
|||
}
|
||||
|
||||
@Override
|
||||
public long getNetworkId() {
|
||||
return -1;
|
||||
public Long getNetworkId() {
|
||||
return -1L;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getVpcId() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -21,10 +21,15 @@ import java.util.Arrays;
|
|||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.cloud.network.IpAddress;
|
||||
import com.cloud.network.NetworkService;
|
||||
import com.cloud.utils.db.EntityManager;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
|
|
@ -33,6 +38,12 @@ import com.cloud.utils.net.NetUtils;
|
|||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class CreateFirewallRuleCmdTest {
|
||||
|
||||
@Mock
|
||||
private EntityManager entityManager;
|
||||
|
||||
@Mock
|
||||
private NetworkService networkService;
|
||||
|
||||
private void validateAllIp4Cidr(final CreateFirewallRuleCmd cmd) {
|
||||
Assert.assertTrue(CollectionUtils.isNotEmpty(cmd.getSourceCidrList()));
|
||||
Assert.assertEquals(1, cmd.getSourceCidrList().size());
|
||||
|
|
@ -88,4 +99,22 @@ public class CreateFirewallRuleCmdTest {
|
|||
Assert.assertEquals(2, cmd.getSourceCidrList().size());
|
||||
Assert.assertEquals(cidr, cmd.getSourceCidrList().get(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetNetworkIdVpcWithoutAssociatedNetworkUsesVpcFallbackAndSyncObjId() {
|
||||
final CreateFirewallRuleCmd cmd = new CreateFirewallRuleCmd();
|
||||
final IpAddress ip = Mockito.mock(IpAddress.class);
|
||||
|
||||
cmd._entityMgr = entityManager;
|
||||
cmd._networkService = networkService;
|
||||
ReflectionTestUtils.setField(cmd, "ipAddressId", 42L);
|
||||
|
||||
Mockito.when(networkService.getIp(42L)).thenReturn(ip);
|
||||
Mockito.when(ip.getAssociatedWithNetworkId()).thenReturn(null);
|
||||
Mockito.when(ip.getVpcId()).thenReturn(100L);
|
||||
Mockito.when(ip.getNetworkId()).thenReturn(2L);
|
||||
|
||||
Assert.assertEquals(Long.valueOf(2L), cmd.getNetworkId());
|
||||
Assert.assertEquals(Long.valueOf(2L), cmd.getSyncObjId());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -80,10 +80,15 @@ public class StaticNatRuleImpl implements StaticNatRule {
|
|||
}
|
||||
|
||||
@Override
|
||||
public long getNetworkId() {
|
||||
public Long getNetworkId() {
|
||||
return networkId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getVpcId() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getId() {
|
||||
return id;
|
||||
|
|
|
|||
|
|
@ -85,6 +85,9 @@ public class FirewallRuleVO implements FirewallRule {
|
|||
@Column(name = "network_id")
|
||||
Long networkId;
|
||||
|
||||
@Column(name = "vpc_id")
|
||||
Long vpcId;
|
||||
|
||||
@Column(name = "icmp_code")
|
||||
Integer icmpCode;
|
||||
|
||||
|
|
@ -190,10 +193,18 @@ public class FirewallRuleVO implements FirewallRule {
|
|||
}
|
||||
|
||||
@Override
|
||||
public long getNetworkId() {
|
||||
public Long getNetworkId() {
|
||||
return networkId;
|
||||
}
|
||||
|
||||
public Long getVpcId() {
|
||||
return vpcId;
|
||||
}
|
||||
|
||||
public void setVpcId(Long vpcId) {
|
||||
this.vpcId = vpcId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FirewallRuleType getType() {
|
||||
return type;
|
||||
|
|
@ -207,7 +218,7 @@ public class FirewallRuleVO implements FirewallRule {
|
|||
uuid = UUID.randomUUID().toString();
|
||||
}
|
||||
|
||||
public FirewallRuleVO(String xId, Long ipAddressId, Integer portStart, Integer portEnd, String protocol, long networkId, long accountId, long domainId,
|
||||
public FirewallRuleVO(String xId, Long ipAddressId, Integer portStart, Integer portEnd, String protocol, Long networkId, long accountId, long domainId,
|
||||
Purpose purpose, List<String> sourceCidrs, Integer icmpCode, Integer icmpType, Long related, TrafficType trafficType) {
|
||||
this.xId = xId;
|
||||
if (xId == null) {
|
||||
|
|
@ -251,7 +262,7 @@ public class FirewallRuleVO implements FirewallRule {
|
|||
}
|
||||
|
||||
|
||||
public FirewallRuleVO(String xId, Long ipAddressId, Integer portStart, Integer portEnd, String protocol, long networkId, long accountId, long domainId,
|
||||
public FirewallRuleVO(String xId, Long ipAddressId, Integer portStart, Integer portEnd, String protocol, Long networkId, long accountId, long domainId,
|
||||
Purpose purpose, List<String> sourceCidrs, List<String> destCidrs, Integer icmpCode, Integer icmpType, Long related, TrafficType trafficType) {
|
||||
this(xId,ipAddressId, portStart, portEnd, protocol, networkId, accountId, domainId, purpose, sourceCidrs, icmpCode, icmpType, related, trafficType);
|
||||
this.destinationCidrs = destCidrs;
|
||||
|
|
|
|||
|
|
@ -2957,8 +2957,13 @@ public class ApiResponseHelper implements ResponseGenerator, ResourceIdSupport {
|
|||
}
|
||||
}
|
||||
|
||||
Network network = ApiDBUtils.findNetworkById(fwRule.getNetworkId());
|
||||
response.setNetworkId(network.getUuid());
|
||||
Long networkId = fwRule.getNetworkId();
|
||||
if (networkId != null) {
|
||||
Network network = ApiDBUtils.findNetworkById(networkId);
|
||||
if (network != null) {
|
||||
response.setNetworkId(network.getUuid());
|
||||
}
|
||||
}
|
||||
|
||||
FirewallRule.State state = fwRule.getState();
|
||||
String stateToSet = state.toString();
|
||||
|
|
|
|||
|
|
@ -656,28 +656,60 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
|
|||
}
|
||||
|
||||
boolean success = true;
|
||||
Network network = _networksDao.findById(rules.get(0).getNetworkId());
|
||||
FirewallRuleVO.TrafficType trafficType = rules.get(0).getTrafficType();
|
||||
FirewallRule firstRule = rules.get(0);
|
||||
Long networkId = firstRule.getNetworkId();
|
||||
Long vpcId = firstRule.getVpcId();
|
||||
FirewallRuleVO.TrafficType trafficType = firstRule.getTrafficType();
|
||||
List<PublicIp> publicIps = new ArrayList<PublicIp>();
|
||||
|
||||
if (!(rules.get(0).getPurpose() == FirewallRule.Purpose.Firewall && trafficType == FirewallRule.TrafficType.Egress)) {
|
||||
// get the list of public ip's owned by the network
|
||||
List<IPAddressVO> userIps = _ipAddressDao.listByAssociatedNetwork(network.getId(), null);
|
||||
if (userIps != null && !userIps.isEmpty()) {
|
||||
for (IPAddressVO userIp : userIps) {
|
||||
PublicIp publicIp = PublicIp.createFromAddrAndVlan(userIp, _vlanDao.findById(userIp.getVlanId()));
|
||||
publicIps.add(publicIp);
|
||||
// For VPC firewall rules the networkId on the rule is null; resolve via VPC.
|
||||
Network network;
|
||||
if (networkId != null) {
|
||||
network = _networksDao.findById(networkId);
|
||||
} else if (vpcId != null) {
|
||||
List<? extends Network> vpcNetworks = _vpcMgr.getVpcNetworks(vpcId);
|
||||
network = (vpcNetworks != null && !vpcNetworks.isEmpty()) ? _networksDao.findById(vpcNetworks.get(0).getId()) : null;
|
||||
} else {
|
||||
network = null;
|
||||
}
|
||||
|
||||
if (network == null) {
|
||||
logger.warn("Unable to resolve network for firewall rules (networkId={}, vpcId={}); skipping IP association", networkId, vpcId);
|
||||
} else if (!(firstRule.getPurpose() == FirewallRule.Purpose.Firewall && trafficType == FirewallRule.TrafficType.Egress)) {
|
||||
// For VPC ingress rules, collect public IPs tied to the VPC rather than network association
|
||||
if (vpcId != null && networkId == null) {
|
||||
List<IPAddressVO> vpcIps = _ipAddressDao.listByAssociatedVpc(vpcId, null);
|
||||
if (vpcIps != null) {
|
||||
for (IPAddressVO userIp : vpcIps) {
|
||||
PublicIp publicIp = PublicIp.createFromAddrAndVlan(userIp, _vlanDao.findById(userIp.getVlanId()));
|
||||
publicIps.add(publicIp);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// get the list of public ip's owned by the network
|
||||
List<IPAddressVO> userIps = _ipAddressDao.listByAssociatedNetwork(network.getId(), null);
|
||||
if (userIps != null && !userIps.isEmpty()) {
|
||||
for (IPAddressVO userIp : userIps) {
|
||||
PublicIp publicIp = PublicIp.createFromAddrAndVlan(userIp, _vlanDao.findById(userIp.getVlanId()));
|
||||
publicIps.add(publicIp);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// rules can not programmed unless IP is associated with network service provider, so run IP assoication for
|
||||
|
||||
// rules can not programmed unless IP is associated with network service provider, so run IP association for
|
||||
// the network so as to ensure IP is associated before applying rules (in add state)
|
||||
if (checkIfIpAssocRequired(network, false, publicIps)) {
|
||||
if (network != null && checkIfIpAssocRequired(network, false, publicIps)) {
|
||||
applyIpAssociations(network, false, continueOnError, publicIps);
|
||||
}
|
||||
|
||||
try {
|
||||
applier.applyRules(network, purpose, rules);
|
||||
if (network != null) {
|
||||
applier.applyRules(network, purpose, rules);
|
||||
} else {
|
||||
logger.warn("Skipping applyRules: no network resolved for rules (vpcId={})", vpcId);
|
||||
success = false;
|
||||
}
|
||||
} catch (ResourceUnavailableException e) {
|
||||
if (!continueOnError) {
|
||||
throw e;
|
||||
|
|
@ -688,7 +720,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
|
|||
|
||||
// if there are no active rules associated with a public IP, then public IP need not be associated with a provider.
|
||||
// This IPAssoc ensures, public IP is dis-associated after last active rule is revoked.
|
||||
if (checkIfIpAssocRequired(network, true, publicIps)) {
|
||||
if (network != null && checkIfIpAssocRequired(network, true, publicIps)) {
|
||||
applyIpAssociations(network, true, continueOnError, publicIps);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -104,9 +104,11 @@ import com.cloud.network.rules.FirewallRuleVO;
|
|||
import com.cloud.network.rules.dao.PortForwardingRulesDao;
|
||||
import com.cloud.network.vpc.Vpc;
|
||||
import com.cloud.network.vpc.VpcGatewayVO;
|
||||
import com.cloud.network.vpc.VpcOfferingServiceMapVO;
|
||||
import com.cloud.network.vpc.dao.PrivateIpDao;
|
||||
import com.cloud.network.vpc.dao.VpcDao;
|
||||
import com.cloud.network.vpc.dao.VpcGatewayDao;
|
||||
import com.cloud.network.vpc.dao.VpcOfferingServiceMapDao;
|
||||
import com.cloud.offering.NetworkOffering;
|
||||
import com.cloud.offering.NetworkOffering.Detail;
|
||||
import com.cloud.offerings.NetworkOfferingServiceMapVO;
|
||||
|
|
@ -183,6 +185,8 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel, Confi
|
|||
NetworkPermissionDao _networkPermissionDao;
|
||||
@Inject
|
||||
VpcDao vpcDao;
|
||||
@Inject
|
||||
VpcOfferingServiceMapDao _vpcOffSvcMapDao;
|
||||
|
||||
private List<NetworkElement> networkElements;
|
||||
|
||||
|
|
@ -457,12 +461,16 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel, Confi
|
|||
// We only support one provider for one service now
|
||||
Map<Service, Set<Provider>> serviceToProviders = getServiceProvidersMap(networkId);
|
||||
// Since IP already has service to bind with, the oldProvider can't be null
|
||||
Set<Provider> newProviders = serviceToProviders.get(service);
|
||||
Set<Provider> newProviders = getProvidersForServiceWithVpcFallback(serviceToProviders, service, publicIp.getVpcId());
|
||||
if (newProviders == null || newProviders.isEmpty()) {
|
||||
throw new InvalidParameterValueException("There is no new provider for IP " + publicIp.getAddress() + " of service " + service.getName() + "!");
|
||||
}
|
||||
Provider newProvider = (Provider)newProviders.toArray()[0];
|
||||
Set<Provider> oldProviders = serviceToProviders.get(services.toArray()[0]);
|
||||
Service existingService = (Service) services.toArray()[0];
|
||||
Set<Provider> oldProviders = getProvidersForServiceWithVpcFallback(serviceToProviders, existingService, publicIp.getVpcId());
|
||||
if (oldProviders == null || oldProviders.isEmpty()) {
|
||||
throw new InvalidParameterValueException("There is no existing provider for IP " + publicIp.getAddress() + " of service " + existingService.getName() + "!");
|
||||
}
|
||||
Provider oldProvider = (Provider)oldProviders.toArray()[0];
|
||||
Network network = _networksDao.findById(networkId);
|
||||
NetworkElement oldElement = getElementImplementingProvider(oldProvider.getName());
|
||||
|
|
@ -477,6 +485,35 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel, Confi
|
|||
return true;
|
||||
}
|
||||
|
||||
private Set<Provider> getProvidersForServiceWithVpcFallback(Map<Service, Set<Provider>> serviceToProviders, Service service, Long vpcId) {
|
||||
Set<Provider> providers = serviceToProviders.get(service);
|
||||
if (providers != null && !providers.isEmpty()) {
|
||||
return providers;
|
||||
}
|
||||
|
||||
if (vpcId == null || service != Service.Firewall) {
|
||||
return providers;
|
||||
}
|
||||
|
||||
Set<Provider> vpcProviders = new HashSet<Provider>();
|
||||
Vpc vpc = vpcDao.findById(vpcId);
|
||||
if (vpc == null) {
|
||||
return vpcProviders;
|
||||
}
|
||||
|
||||
List<VpcOfferingServiceMapVO> offeringProviders = _vpcOffSvcMapDao.listProvidersForServiceForVpcOffering(vpc.getVpcOfferingId(), Service.Firewall);
|
||||
if (offeringProviders != null) {
|
||||
for (VpcOfferingServiceMapVO offeringProvider : offeringProviders) {
|
||||
Provider provider = Provider.getProvider(offeringProvider.getProvider());
|
||||
if (provider != null) {
|
||||
vpcProviders.add(provider);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return vpcProviders;
|
||||
}
|
||||
|
||||
Map<Provider, Set<Service>> getProviderServicesMap(long networkId) {
|
||||
Map<Provider, Set<Service>> map = new HashMap<Provider, Set<Service>>();
|
||||
List<NetworkServiceMapVO> nsms = _ntwkSrvcDao.getServicesInNetwork(networkId);
|
||||
|
|
|
|||
|
|
@ -139,7 +139,13 @@ public class VpcVirtualRouterElement extends VirtualRouterElement implements Vpc
|
|||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!_networkMdl.isProviderSupportServiceInNetwork(network.getId(), service, getProvider())) {
|
||||
boolean supportsService;
|
||||
if (service == Service.Firewall) {
|
||||
supportsService = _vpcMgr.isProviderSupportServiceInVpc(network.getVpcId(), service, getProvider());
|
||||
} else {
|
||||
supportsService = _networkMdl.isProviderSupportServiceInNetwork(network.getId(), service, getProvider());
|
||||
}
|
||||
if (!supportsService) {
|
||||
logger.trace("Element " + getProvider().getName() + " doesn't support service " + service.getName() + " in the network " + network);
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -198,25 +198,62 @@ public class FirewallManagerImpl extends ManagerBase implements FirewallService,
|
|||
if (sourceCidrs != null && !sourceCidrs.isEmpty())
|
||||
Collections.replaceAll(sourceCidrs, "0.0.0.0/0", network.getCidr());
|
||||
|
||||
return createFirewallRule(null, caller, rule.getXid(), rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol(), sourceCidrs, rule.getDestinationCidrList(),
|
||||
rule.getIcmpCode(), rule.getIcmpType(), null, rule.getType(), rule.getNetworkId(), rule.getTrafficType(), rule.isDisplay());
|
||||
return createFirewallRuleForNonVPC(null, caller, rule.getXid(), rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol(), sourceCidrs,
|
||||
rule.getDestinationCidrList(), rule.getIcmpCode(), rule.getIcmpType(), null, rule.getType(), rule.getNetworkId(), rule.getTrafficType(), rule.isDisplay());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ActionEvent(eventType = EventTypes.EVENT_FIREWALL_OPEN, eventDescription = "creating firewall rule", create = true)
|
||||
public FirewallRule createIngressFirewallRule(FirewallRule rule) throws NetworkRuleConflictException {
|
||||
Account caller = CallContext.current().getCallingAccount();
|
||||
Account caller = CallContext.current().getCallingAccount();
|
||||
Long sourceIpAddressId = rule.getSourceIpAddressId();
|
||||
IPAddressVO sourceIp = getSourceIpForIngressRule(sourceIpAddressId);
|
||||
|
||||
return createFirewallRule(sourceIpAddressId, caller, rule.getXid(), rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol(),
|
||||
rule.getSourceCidrList(), null, rule.getIcmpCode(), rule.getIcmpType(), null, rule.getType(), rule.getNetworkId(), rule.getTrafficType(), rule.isDisplay());
|
||||
if (sourceIp.getVpcId() != null) {
|
||||
return createIngressFirewallRuleForVpcIp(rule, caller, sourceIp);
|
||||
}
|
||||
return createIngressFirewallRuleForIsolatedIp(rule, caller, sourceIp);
|
||||
}
|
||||
|
||||
protected IPAddressVO getSourceIpForIngressRule(Long sourceIpAddressId) {
|
||||
if (sourceIpAddressId == null) {
|
||||
return null;
|
||||
}
|
||||
return _ipAddressDao.findById(sourceIpAddressId);
|
||||
}
|
||||
|
||||
protected FirewallRule createIngressFirewallRuleForIsolatedIp(FirewallRule rule, Account caller, IPAddressVO sourceIp)
|
||||
throws NetworkRuleConflictException {
|
||||
return createFirewallRuleForNonVPC(rule.getSourceIpAddressId(), caller, rule.getXid(), rule.getSourcePortStart(), rule.getSourcePortEnd(),
|
||||
rule.getProtocol(), rule.getSourceCidrList(), null, rule.getIcmpCode(), rule.getIcmpType(), null, rule.getType(),
|
||||
rule.getNetworkId(), rule.getTrafficType(), rule.isDisplay());
|
||||
}
|
||||
|
||||
protected FirewallRule createIngressFirewallRuleForVpcIp(FirewallRule rule, Account caller, IPAddressVO sourceIp)
|
||||
throws NetworkRuleConflictException {
|
||||
Long vpcId = sourceIp != null ? sourceIp.getVpcId() : null;
|
||||
return createFirewallRuleForVpc(rule.getSourceIpAddressId(), caller, rule.getXid(), rule.getSourcePortStart(), rule.getSourcePortEnd(),
|
||||
rule.getProtocol(), rule.getSourceCidrList(), null, rule.getIcmpCode(), rule.getIcmpType(), null, rule.getType(),
|
||||
vpcId, rule.getTrafficType(), rule.isDisplay());
|
||||
}
|
||||
|
||||
//Destination CIDR capability is currently implemented for egress rules only. For others, the field is passed as null.
|
||||
@DB
|
||||
protected FirewallRule createFirewallRule(final Long ipAddrId, Account caller, final String xId, final Integer portStart, final Integer portEnd, final String protocol,
|
||||
final List<String> sourceCidrList, final List<String> destCidrList, final Integer icmpCode, final Integer icmpType, final Long relatedRuleId,
|
||||
final FirewallRule.FirewallRuleType type, final Long networkId, final FirewallRule.TrafficType trafficType, final Boolean forDisplay) throws NetworkRuleConflictException {
|
||||
final FirewallRule.FirewallRuleType type, final Long networkId, final Long vpcId, final FirewallRule.TrafficType trafficType, final Boolean forDisplay) throws NetworkRuleConflictException {
|
||||
if (vpcId != null) {
|
||||
return createFirewallRuleForVpc(ipAddrId, caller, xId, portStart, portEnd, protocol, sourceCidrList, destCidrList, icmpCode, icmpType, relatedRuleId,
|
||||
type, vpcId, trafficType, forDisplay);
|
||||
}
|
||||
return createFirewallRuleForNonVPC(ipAddrId, caller, xId, portStart, portEnd, protocol, sourceCidrList, destCidrList, icmpCode, icmpType, relatedRuleId,
|
||||
type, networkId, trafficType, forDisplay);
|
||||
}
|
||||
|
||||
@DB
|
||||
protected FirewallRule createFirewallRuleForNonVPC(final Long ipAddrId, Account caller, final String xId, final Integer portStart, final Integer portEnd, final String protocol,
|
||||
final List<String> sourceCidrList, final List<String> destCidrList, final Integer icmpCode, final Integer icmpType, final Long relatedRuleId,
|
||||
final FirewallRule.FirewallRuleType type, final Long networkId, final FirewallRule.TrafficType trafficType, final Boolean forDisplay) throws NetworkRuleConflictException {
|
||||
IPAddressVO ipAddress = null;
|
||||
try {
|
||||
// Validate ip address
|
||||
|
|
@ -283,6 +320,158 @@ public class FirewallManagerImpl extends ManagerBase implements FirewallService,
|
|||
}
|
||||
}
|
||||
|
||||
@DB
|
||||
protected FirewallRule createFirewallRuleForVpc(final Long ipAddrId, Account caller, final String xId, final Integer portStart, final Integer portEnd, final String protocol,
|
||||
final List<String> sourceCidrList, final List<String> destCidrList, final Integer icmpCode, final Integer icmpType,
|
||||
final Long relatedRuleId, final FirewallRuleType type, final Long vpcId,
|
||||
final FirewallRule.TrafficType trafficType, final Boolean forDisplay) throws NetworkRuleConflictException {
|
||||
IPAddressVO ipAddress = null;
|
||||
try {
|
||||
Long resolvedVpcId = vpcId;
|
||||
if (ipAddrId != null) {
|
||||
ipAddress = _ipAddressDao.acquireInLockTable(ipAddrId);
|
||||
if (ipAddress == null) {
|
||||
throw new InvalidParameterValueException("Unable to create firewall rule; " + "couldn't locate IP address by id in the system");
|
||||
}
|
||||
resolvedVpcId = resolvedVpcId != null ? resolvedVpcId : ipAddress.getVpcId();
|
||||
}
|
||||
|
||||
if (resolvedVpcId == null) {
|
||||
throw new InvalidParameterValueException("Unable to create VPC firewall rule; couldn't locate VPC id");
|
||||
}
|
||||
|
||||
validateFirewallRuleForVpc(caller, ipAddress, portStart, portEnd, protocol, Purpose.Firewall, type, resolvedVpcId, trafficType);
|
||||
|
||||
if (!protocol.equalsIgnoreCase(NetUtils.ICMP_PROTO) && (icmpCode != null || icmpType != null)) {
|
||||
throw new InvalidParameterValueException("Can specify icmpCode and icmpType for ICMP protocol only");
|
||||
}
|
||||
|
||||
if (protocol.equalsIgnoreCase(NetUtils.ICMP_PROTO) && (portStart != null || portEnd != null)) {
|
||||
throw new InvalidParameterValueException("Can't specify start/end port when protocol is ICMP");
|
||||
}
|
||||
|
||||
Long accountId = null;
|
||||
Long domainId = null;
|
||||
|
||||
if (ipAddress != null) {
|
||||
accountId = ipAddress.getAllocatedToAccountId();
|
||||
domainId = ipAddress.getAllocatedInDomainId();
|
||||
} else {
|
||||
Vpc vpc = _vpcMgr.getActiveVpc(resolvedVpcId);
|
||||
if (vpc == null) {
|
||||
throw new InvalidParameterValueException("Unable to create VPC firewall rule; couldn't locate VPC by id=" + resolvedVpcId);
|
||||
}
|
||||
accountId = vpc.getAccountId();
|
||||
domainId = vpc.getDomainId();
|
||||
}
|
||||
|
||||
final Long accountIdFinal = accountId;
|
||||
final Long domainIdFinal = domainId;
|
||||
final Long resolvedNetworkIdFinal = null;
|
||||
final Long resolvedVpcIdFinal = resolvedVpcId;
|
||||
return Transaction.execute((TransactionCallbackWithException<FirewallRuleVO, NetworkRuleConflictException>) status -> {
|
||||
FirewallRuleVO newRule = new FirewallRuleVO(xId, ipAddrId, portStart, portEnd, protocol.toLowerCase(), resolvedNetworkIdFinal, accountIdFinal, domainIdFinal, Purpose.Firewall,
|
||||
sourceCidrList, destCidrList, icmpCode, icmpType, relatedRuleId, trafficType);
|
||||
newRule.setVpcId(resolvedVpcIdFinal);
|
||||
newRule.setType(type);
|
||||
if (forDisplay != null) {
|
||||
newRule.setDisplay(forDisplay);
|
||||
}
|
||||
newRule = _firewallDao.persist(newRule);
|
||||
|
||||
if (type == FirewallRuleType.User)
|
||||
detectRulesConflict(newRule);
|
||||
|
||||
if (!_firewallDao.setStateToAdd(newRule)) {
|
||||
throw new CloudRuntimeException("Unable to update the state to add for " + newRule);
|
||||
}
|
||||
CallContext.current().setEventDetails("Rule ID: " + newRule.getUuid());
|
||||
CallContext.current().putContextParameter(FirewallRule.class, newRule.getId());
|
||||
|
||||
return newRule;
|
||||
});
|
||||
} finally {
|
||||
if (ipAddrId != null) {
|
||||
_ipAddressDao.releaseFromLockTable(ipAddrId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void validateFirewallRuleForVpc(Account caller, IPAddressVO ipAddress, Integer portStart, Integer portEnd, String proto, Purpose purpose,
|
||||
FirewallRuleType type, Long vpcId, FirewallRule.TrafficType trafficType) {
|
||||
if (portStart != null && !NetUtils.isValidPort(portStart)) {
|
||||
throw new InvalidParameterValueException("publicPort is an invalid value: " + portStart);
|
||||
}
|
||||
if (portEnd != null && !NetUtils.isValidPort(portEnd)) {
|
||||
throw new InvalidParameterValueException("Public port range is an invalid value: " + portEnd);
|
||||
}
|
||||
if (portStart != null && portEnd != null && portStart > portEnd) {
|
||||
throw new InvalidParameterValueException("Start port can't be bigger than end port");
|
||||
}
|
||||
|
||||
if (ipAddress == null && type == FirewallRuleType.System) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (vpcId == null) {
|
||||
throw new InvalidParameterValueException("Unable to retrieve VPC id to validate the rule");
|
||||
}
|
||||
|
||||
if (ipAddress != null) {
|
||||
_accountMgr.checkAccess(caller, null, true, ipAddress);
|
||||
}
|
||||
|
||||
Vpc vpc = _vpcMgr.getActiveVpc(vpcId);
|
||||
if (vpc == null) {
|
||||
throw new InvalidParameterValueException("Unable to retrieve VPC to validate the rule by id=" + vpcId);
|
||||
}
|
||||
|
||||
Map<Network.Capability, String> caps = null;
|
||||
if (purpose == Purpose.Firewall) {
|
||||
caps = getFirewallServiceCapabilitiesForVpc(vpcId);
|
||||
}
|
||||
|
||||
if (caps != null) {
|
||||
String supportedTrafficTypes = null;
|
||||
if (purpose == FirewallRule.Purpose.Firewall) {
|
||||
supportedTrafficTypes = caps.get(Capability.SupportedTrafficDirection).toLowerCase();
|
||||
}
|
||||
|
||||
String supportedProtocols;
|
||||
if (purpose == FirewallRule.Purpose.Firewall && trafficType == FirewallRule.TrafficType.Egress) {
|
||||
supportedProtocols = caps.get(Capability.SupportedEgressProtocols).toLowerCase();
|
||||
} else {
|
||||
supportedProtocols = caps.get(Capability.SupportedProtocols).toLowerCase();
|
||||
}
|
||||
|
||||
if (!supportedProtocols.contains(proto.toLowerCase())) {
|
||||
throw new InvalidParameterValueException("Protocol " + proto + " is not supported in VPC " + vpcId);
|
||||
} else if (proto.equalsIgnoreCase(NetUtils.ICMP_PROTO) && purpose != Purpose.Firewall) {
|
||||
throw new InvalidParameterValueException("Protocol " + proto + " is currently supported only for rules with purpose " + Purpose.Firewall);
|
||||
} else if (purpose == Purpose.Firewall && !supportedTrafficTypes.contains(trafficType.toString().toLowerCase())) {
|
||||
throw new InvalidParameterValueException(String.format("Traffic Type %s is currently supported by Firewall in VPC %s", trafficType, vpc.getUuid()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected Map<Network.Capability, String> getFirewallServiceCapabilitiesForVpc(Long vpcId) {
|
||||
for (FirewallServiceProvider fwElement : _firewallElements) {
|
||||
Network.Provider provider = fwElement.getProvider();
|
||||
if (_vpcMgr.isProviderSupportServiceInVpc(vpcId, Service.Firewall, provider)) {
|
||||
Map<Service, Map<Capability, String>> capabilities = fwElement.getCapabilities();
|
||||
if (capabilities != null && capabilities.get(Service.Firewall) != null) {
|
||||
return capabilities.get(Service.Firewall);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected Long resolveIsolatedFirewallRuleNetworkId(IPAddressVO ipAddress, Long networkId) {
|
||||
_networkModel.checkIpForService(ipAddress, Service.Firewall, networkId);
|
||||
return ipAddress.getAssociatedWithNetworkId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pair<List<? extends FirewallRule>, Integer> listFirewallRules(IListFirewallRulesCmd cmd) {
|
||||
Long ipId = cmd.getIpAddressId();
|
||||
|
|
@ -399,9 +588,16 @@ public class FirewallManagerImpl extends ManagerBase implements FirewallService,
|
|||
assert (rules.size() >= 1);
|
||||
}
|
||||
|
||||
NetworkVO newRuleNetwork = getNewRuleNetwork(newRule);
|
||||
boolean newRuleIsOnVpcNetwork = newRuleNetwork.getVpcId() != null;
|
||||
boolean vpcConserveModeEnabled = _vpcMgr.isNetworkOnVpcEnabledConserveMode(newRuleNetwork);
|
||||
Long newRuleVpcId = newRule.getVpcId();
|
||||
boolean newRuleIsVpc = newRuleVpcId != null;
|
||||
NetworkVO newRuleNetwork = null;
|
||||
boolean newRuleIsOnVpcNetwork = false;
|
||||
boolean vpcConserveModeEnabled = false;
|
||||
if (!newRuleIsVpc) {
|
||||
newRuleNetwork = getNewRuleNetwork(newRule);
|
||||
newRuleIsOnVpcNetwork = newRuleNetwork.getVpcId() != null;
|
||||
vpcConserveModeEnabled = newRuleIsOnVpcNetwork && _vpcMgr.isNetworkOnVpcEnabledConserveMode(newRuleNetwork);
|
||||
}
|
||||
|
||||
for (FirewallRuleVO rule : rules) {
|
||||
if (rule.getId() == newRule.getId()) {
|
||||
|
|
@ -452,8 +648,8 @@ public class FirewallManagerImpl extends ManagerBase implements FirewallService,
|
|||
|
||||
// Checking if the rule applied is to the same network that is passed in the rule.
|
||||
// (except for VPCs with conserve mode = true)
|
||||
if ((!newRuleIsOnVpcNetwork || !vpcConserveModeEnabled)
|
||||
&& rule.getNetworkId() != newRule.getNetworkId() && rule.getState() != State.Revoke) {
|
||||
if (!newRuleIsVpc && (!newRuleIsOnVpcNetwork || !vpcConserveModeEnabled)
|
||||
&& !Objects.equals(rule.getNetworkId(), newRule.getNetworkId()) && rule.getState() != State.Revoke) {
|
||||
String errMsg = String.format("New rule is for a different network than what's specified in rule %s", rule.getXid());
|
||||
if (newRuleIsOnVpcNetwork) {
|
||||
Vpc vpc = _vpcMgr.getActiveVpc(newRuleNetwork.getVpcId());
|
||||
|
|
@ -575,11 +771,9 @@ public class FirewallManagerImpl extends ManagerBase implements FirewallService,
|
|||
}
|
||||
|
||||
if (ipAddress != null) {
|
||||
if (ipAddress.getAssociatedWithNetworkId() == null) {
|
||||
throw new InvalidParameterValueException("Unable to create firewall rule ; ip with specified id is not associated with any network");
|
||||
} else {
|
||||
networkId = ipAddress.getAssociatedWithNetworkId();
|
||||
}
|
||||
networkId = isVpcIpAddress(ipAddress)
|
||||
? validateFirewallRuleForVpcIp(ipAddress, networkId)
|
||||
: validateFirewallRuleForIsolatedIp(ipAddress);
|
||||
|
||||
// Validate ip address
|
||||
_accountMgr.checkAccess(caller, null, true, ipAddress);
|
||||
|
|
@ -610,7 +804,7 @@ public class FirewallManagerImpl extends ManagerBase implements FirewallService,
|
|||
if (routedIpv4Manager.isVirtualRouterGateway(network)) {
|
||||
throw new CloudRuntimeException("Unable to create routing firewall rule. Please use routing firewall API instead.");
|
||||
}
|
||||
caps = _networkModel.getNetworkServiceCapabilities(network.getId(), Service.Firewall);
|
||||
caps = getFirewallServiceCapabilities(network);
|
||||
}
|
||||
|
||||
if (caps != null) {
|
||||
|
|
@ -637,6 +831,41 @@ public class FirewallManagerImpl extends ManagerBase implements FirewallService,
|
|||
|
||||
}
|
||||
|
||||
protected boolean isVpcIpAddress(IPAddressVO ipAddress) {
|
||||
return ipAddress.getVpcId() != null;
|
||||
}
|
||||
|
||||
protected Long validateFirewallRuleForIsolatedIp(IPAddressVO ipAddress) {
|
||||
if (ipAddress.getAssociatedWithNetworkId() == null) {
|
||||
throw new InvalidParameterValueException("Unable to create firewall rule ; ip with specified id is not associated with any network");
|
||||
}
|
||||
return ipAddress.getAssociatedWithNetworkId();
|
||||
}
|
||||
|
||||
protected Long validateFirewallRuleForVpcIp(IPAddressVO ipAddress, Long networkId) {
|
||||
if (networkId == null) {
|
||||
throw new InvalidParameterValueException("Unable to retrieve network id to validate the rule");
|
||||
}
|
||||
return networkId;
|
||||
}
|
||||
|
||||
protected Map<Network.Capability, String> getFirewallServiceCapabilities(Network network) {
|
||||
if (network.getVpcId() == null) {
|
||||
return _networkModel.getNetworkServiceCapabilities(network.getId(), Service.Firewall);
|
||||
}
|
||||
|
||||
for (FirewallServiceProvider fwElement : _firewallElements) {
|
||||
Network.Provider provider = fwElement.getProvider();
|
||||
if (_vpcMgr.isProviderSupportServiceInVpc(network.getVpcId(), Service.Firewall, provider)) {
|
||||
Map<Service, Map<Capability, String>> capabilities = fwElement.getCapabilities();
|
||||
if (capabilities != null && capabilities.get(Service.Firewall) != null) {
|
||||
return capabilities.get(Service.Firewall);
|
||||
}
|
||||
}
|
||||
}
|
||||
return _networkModel.getNetworkServiceCapabilities(network.getId(), Service.Firewall);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applyRules(List<? extends FirewallRule> rules, boolean continueOnError, boolean updateRulesInDB) throws ResourceUnavailableException {
|
||||
boolean success = true;
|
||||
|
|
@ -784,8 +1013,10 @@ public class FirewallManagerImpl extends ManagerBase implements FirewallService,
|
|||
|
||||
for (FirewallRuleVO rule : rules) {
|
||||
// validate rule - for NSX
|
||||
long networkId = rule.getNetworkId();
|
||||
validateNsxConstraints(networkId, rule);
|
||||
Long networkId = rule.getNetworkId();
|
||||
if (networkId != null) {
|
||||
validateNsxConstraints(networkId, rule);
|
||||
}
|
||||
// load cidrs if any
|
||||
rule.setSourceCidrList(_firewallCidrsDao.getSourceCidrs(rule.getId()));
|
||||
rule.setDestinationCidrsList(_firewallDcidrsDao.getDestCidrs(rule.getId()));
|
||||
|
|
@ -1045,7 +1276,7 @@ public class FirewallManagerImpl extends ManagerBase implements FirewallService,
|
|||
List<String> oneCidr = new ArrayList<String>();
|
||||
oneCidr.add(NetUtils.ALL_IP4_CIDRS);
|
||||
return createFirewallRule(ipAddrId, caller, null, startPort, endPort, protocol, oneCidr, null, icmpCode, icmpType, relatedRuleId, FirewallRule.FirewallRuleType.User,
|
||||
networkId, FirewallRule.TrafficType.Ingress, true);
|
||||
networkId, null, FirewallRule.TrafficType.Ingress, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -1160,7 +1391,7 @@ public class FirewallManagerImpl extends ManagerBase implements FirewallService,
|
|||
_firewallDao.loadSourceCidrs(rule);
|
||||
}
|
||||
createFirewallRule(ip.getId(), acct, rule.getXid(), rule.getSourcePortStart(), rule.getSourcePortEnd(), rule.getProtocol(), rule.getSourceCidrList(),null,
|
||||
rule.getIcmpCode(), rule.getIcmpType(), rule.getRelated(), FirewallRuleType.System, rule.getNetworkId(), rule.getTrafficType(), true);
|
||||
rule.getIcmpCode(), rule.getIcmpType(), rule.getRelated(), FirewallRuleType.System, rule.getNetworkId(), rule.getVpcId(), rule.getTrafficType(), true);
|
||||
} catch (Exception e) {
|
||||
logger.debug("Failed to add system wide firewall rule, due to:" + e.toString());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,10 +19,13 @@ package com.cloud.network.element;
|
|||
import com.cloud.dc.DataCenterVO;
|
||||
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.RemoteAccessVpn;
|
||||
import com.cloud.network.VpnUser;
|
||||
import com.cloud.network.router.VpcVirtualNetworkApplianceManagerImpl;
|
||||
import com.cloud.network.vpc.Vpc;
|
||||
import com.cloud.network.vpc.VpcManager;
|
||||
import com.cloud.network.vpc.dao.VpcDao;
|
||||
import com.cloud.utils.db.EntityManager;
|
||||
import com.cloud.vm.DomainRouterVO;
|
||||
|
|
@ -43,7 +46,9 @@ import java.util.List;
|
|||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
|
@ -60,6 +65,12 @@ public class VpcVirtualRouterElementTest {
|
|||
@Mock
|
||||
EntityManager _entityMgr;
|
||||
|
||||
@Mock
|
||||
NetworkModel _networkMdl;
|
||||
|
||||
@Mock
|
||||
VpcManager _vpcMgr;
|
||||
|
||||
@Mock
|
||||
NetworkTopologyContext networkTopologyContext;
|
||||
|
||||
|
|
@ -188,4 +199,18 @@ public class VpcVirtualRouterElementTest {
|
|||
|
||||
verify(remoteAccessVpn, times(1)).getVpcId();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCanHandleFirewallUsesVpcCapability() {
|
||||
final Network network = Mockito.mock(Network.class);
|
||||
|
||||
when(_networkMdl.getPhysicalNetworkId(network)).thenReturn(1L);
|
||||
when(network.getVpcId()).thenReturn(100L);
|
||||
when(_networkMdl.isProviderEnabledInPhysicalNetwork(1L, Network.Provider.VPCVirtualRouter.getName())).thenReturn(true);
|
||||
when(_vpcMgr.isProviderSupportServiceInVpc(100L, Network.Service.Firewall, Network.Provider.VPCVirtualRouter)).thenReturn(true);
|
||||
|
||||
assertTrue(vpcVirtualRouterElement.canHandle(network, Network.Service.Firewall));
|
||||
verify(_vpcMgr).isProviderSupportServiceInVpc(100L, Network.Service.Firewall, Network.Provider.VPCVirtualRouter);
|
||||
verify(_networkMdl, never()).isProviderSupportServiceInNetwork(network.getId(), Network.Service.Firewall, Network.Provider.VPCVirtualRouter);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,23 +21,29 @@ import com.cloud.exception.NetworkRuleConflictException;
|
|||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.network.IpAddressManager;
|
||||
import com.cloud.network.Network;
|
||||
import com.cloud.network.Network.Capability;
|
||||
import com.cloud.network.Network.Service;
|
||||
import com.cloud.network.NetworkModel;
|
||||
import com.cloud.network.NetworkRuleApplier;
|
||||
import com.cloud.network.dao.FirewallRulesDao;
|
||||
import com.cloud.network.dao.IPAddressVO;
|
||||
import com.cloud.network.dao.NetworkDao;
|
||||
import com.cloud.network.dao.NetworkVO;
|
||||
import com.cloud.network.element.FirewallServiceProvider;
|
||||
import com.cloud.network.element.VirtualRouterElement;
|
||||
import com.cloud.network.element.VpcVirtualRouterElement;
|
||||
import com.cloud.network.rules.FirewallRule;
|
||||
import com.cloud.network.rules.FirewallRule.FirewallRuleType;
|
||||
import com.cloud.network.rules.FirewallRule.Purpose;
|
||||
import com.cloud.network.rules.FirewallRuleVO;
|
||||
import com.cloud.network.vpc.Vpc;
|
||||
import com.cloud.network.vpc.VpcManager;
|
||||
import com.cloud.user.Account;
|
||||
import com.cloud.user.AccountManager;
|
||||
import com.cloud.user.DomainManager;
|
||||
import com.cloud.utils.component.ComponentContext;
|
||||
import org.apache.cloudstack.engine.orchestration.service.NetworkOrchestrationService;
|
||||
import org.apache.cloudstack.network.RoutedIpv4Manager;
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
|
|
@ -53,7 +59,9 @@ import org.mockito.junit.MockitoJUnitRunner;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
|
|
@ -79,6 +87,8 @@ public class FirewallManagerTest {
|
|||
@Mock
|
||||
IpAddressManager _ipAddrMgr;
|
||||
@Mock
|
||||
RoutedIpv4Manager routedIpv4Manager;
|
||||
@Mock
|
||||
FirewallRulesDao _firewallDao;
|
||||
@Mock
|
||||
NetworkDao _networkDao;
|
||||
|
|
@ -115,7 +125,7 @@ public class FirewallManagerTest {
|
|||
}
|
||||
|
||||
private FirewallRule createFirewallRule(int startPort, int endPort, Purpose purpose) {
|
||||
return new FirewallRuleVO("xid", 1L, startPort, endPort, "TCP", 2, 3, 4, purpose, new ArrayList<>(),
|
||||
return new FirewallRuleVO("xid", 1L, startPort, endPort, "TCP", 2L, 3, 4, purpose, new ArrayList<>(),
|
||||
new ArrayList<>(), 5, 6, null, FirewallRule.TrafficType.Ingress);
|
||||
}
|
||||
|
||||
|
|
@ -332,4 +342,34 @@ public class FirewallManagerTest {
|
|||
|
||||
Assert.assertFalse(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testValidateFirewallRuleVpcWithoutAssociatedNetworkUsesVpcCapabilities() {
|
||||
final Account caller = Mockito.mock(Account.class);
|
||||
final IPAddressVO ipAddress = Mockito.mock(IPAddressVO.class);
|
||||
final NetworkVO network = Mockito.mock(NetworkVO.class);
|
||||
final FirewallServiceProvider firewallServiceProvider = Mockito.mock(FirewallServiceProvider.class);
|
||||
final Map<Capability, String> firewallCaps = new HashMap<>();
|
||||
final Map<Service, Map<Capability, String>> capabilities = new HashMap<>();
|
||||
|
||||
firewallCaps.put(Capability.SupportedTrafficDirection, "ingress, egress");
|
||||
firewallCaps.put(Capability.SupportedProtocols, "tcp,udp,icmp");
|
||||
firewallCaps.put(Capability.SupportedEgressProtocols, "tcp,udp,icmp");
|
||||
capabilities.put(Service.Firewall, firewallCaps);
|
||||
|
||||
when(ipAddress.getAssociatedWithNetworkId()).thenReturn(null);
|
||||
when(ipAddress.getVpcId()).thenReturn(10L);
|
||||
when(_networkModel.getNetwork(2L)).thenReturn(network);
|
||||
when(network.getVpcId()).thenReturn(10L);
|
||||
when(network.getDataCenterId()).thenReturn(1L);
|
||||
when(routedIpv4Manager.isVirtualRouterGateway(network)).thenReturn(false);
|
||||
when(firewallServiceProvider.getProvider()).thenReturn(Network.Provider.VPCVirtualRouter);
|
||||
when(firewallServiceProvider.getCapabilities()).thenReturn(capabilities);
|
||||
when(_vpcMgr.isProviderSupportServiceInVpc(10L, Service.Firewall, Network.Provider.VPCVirtualRouter)).thenReturn(true);
|
||||
_firewallMgr._firewallElements = List.of(firewallServiceProvider);
|
||||
|
||||
_firewallMgr.validateFirewallRule(caller, ipAddress, 80, 80, "tcp", Purpose.Firewall, FirewallRuleType.User, 2L, FirewallRule.TrafficType.Ingress);
|
||||
|
||||
verify(_networkModel, Mockito.never()).getNetworkServiceCapabilities(Mockito.anyLong(), Mockito.eq(Service.Firewall));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue