Shared Network Firewall (Security groups) in Advanced zone without security groups (#9415)

This commit is contained in:
Vishesh 2024-09-05 14:05:05 +05:30 committed by GitHub
parent 6a559f46e3
commit 72d0546d8b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
26 changed files with 402 additions and 99 deletions

View File

@ -356,4 +356,8 @@ public interface NetworkModel {
void verifyIp6DnsPair(final String ip6Dns1, final String ip6Dns2); void verifyIp6DnsPair(final String ip6Dns1, final String ip6Dns2);
boolean isSecurityGroupSupportedForZone(Long zoneId);
boolean checkSecurityGroupSupportForNetwork(DataCenter zone, List<Long> networkIds,
List<Long> securityGroupsIds);
} }

View File

@ -79,7 +79,7 @@ public class AddIpToVmNicCmd extends BaseAsyncCreateCmd {
private boolean isZoneSGEnabled() { private boolean isZoneSGEnabled() {
Network ntwk = _entityMgr.findById(Network.class, getNetworkId()); Network ntwk = _entityMgr.findById(Network.class, getNetworkId());
DataCenter dc = _entityMgr.findById(DataCenter.class, ntwk.getDataCenterId()); DataCenter dc = _entityMgr.findById(DataCenter.class, ntwk.getDataCenterId());
return dc.isSecurityGroupEnabled(); return dc.isSecurityGroupEnabled() || _ntwkModel.isSecurityGroupSupportedForZone(dc.getId());
} }
@Override @Override

View File

@ -127,7 +127,7 @@ public class RemoveIpFromVmNicCmd extends BaseAsyncCmd {
private boolean isZoneSGEnabled() { private boolean isZoneSGEnabled() {
Network ntwk = _entityMgr.findById(Network.class, getNetworkId()); Network ntwk = _entityMgr.findById(Network.class, getNetworkId());
DataCenter dc = _entityMgr.findById(DataCenter.class, ntwk.getDataCenterId()); DataCenter dc = _entityMgr.findById(DataCenter.class, ntwk.getDataCenterId());
return dc.isSecurityGroupEnabled(); return dc.isSecurityGroupEnabled() || _ntwkModel.isSecurityGroupSupportedForZone(dc.getId());
} }
@Override @Override

View File

@ -312,10 +312,6 @@ public class ZoneResponse extends BaseResponseWithAnnotations implements SetReso
return networkType; return networkType;
} }
public boolean isSecurityGroupsEnabled() {
return securityGroupsEnabled;
}
public String getAllocationState() { public String getAllocationState() {
return allocationState; return allocationState;
} }
@ -332,10 +328,6 @@ public class ZoneResponse extends BaseResponseWithAnnotations implements SetReso
return capacities; return capacities;
} }
public boolean isLocalStorageEnabled() {
return localStorageEnabled;
}
public Set<ResourceTagResponse> getTags() { public Set<ResourceTagResponse> getTags() {
return tags; return tags;
} }
@ -344,6 +336,14 @@ public class ZoneResponse extends BaseResponseWithAnnotations implements SetReso
return resourceDetails; return resourceDetails;
} }
public boolean isSecurityGroupsEnabled() {
return securityGroupsEnabled;
}
public boolean isLocalStorageEnabled() {
return localStorageEnabled;
}
public Boolean getAllowUserSpecifyVRMtu() { public Boolean getAllowUserSpecifyVRMtu() {
return allowUserSpecifyVRMtu; return allowUserSpecifyVRMtu;
} }
@ -356,6 +356,10 @@ public class ZoneResponse extends BaseResponseWithAnnotations implements SetReso
return routerPublicInterfaceMaxMtu; return routerPublicInterfaceMaxMtu;
} }
public boolean isNsxEnabled() {
return nsxEnabled;
}
@Override @Override
public void setResourceIconResponse(ResourceIconResponse resourceIconResponse) { public void setResourceIconResponse(ResourceIconResponse resourceIconResponse) {
this.resourceIconResponse = resourceIconResponse; this.resourceIconResponse = resourceIconResponse;

View File

@ -346,7 +346,7 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L
} }
DataCenterVO zone = _dcDao.findById(dcId); DataCenterVO zone = _dcDao.findById(dcId);
boolean securityGroupEnabled = zone.isSecurityGroupEnabled(); boolean securityGroupEnabled = zone.isSecurityGroupEnabled() || _networkMgr.isSecurityGroupSupportedForZone(zone.getId());
params.put("securitygroupenabled", Boolean.toString(securityGroupEnabled)); params.put("securitygroupenabled", Boolean.toString(securityGroupEnabled));
params.put("router.aggregation.command.each.timeout", _configDao.getValue(Config.RouterAggregationCommandEachTimeout.toString())); params.put("router.aggregation.command.each.timeout", _configDao.getValue(Config.RouterAggregationCommandEachTimeout.toString()));
@ -695,7 +695,7 @@ public class XcpServerDiscoverer extends DiscovererBase implements Discoverer, L
HashMap<String, Object> params = super.buildConfigParams(host); HashMap<String, Object> params = super.buildConfigParams(host);
DataCenterVO zone = _dcDao.findById(host.getDataCenterId()); DataCenterVO zone = _dcDao.findById(host.getDataCenterId());
if (zone != null) { if (zone != null) {
boolean securityGroupEnabled = zone.isSecurityGroupEnabled(); boolean securityGroupEnabled = zone.isSecurityGroupEnabled() || _networkMgr.isSecurityGroupSupportedForZone(zone.getId());
params.put("securitygroupenabled", Boolean.toString(securityGroupEnabled)); params.put("securitygroupenabled", Boolean.toString(securityGroupEnabled));
} }
return params; return params;

View File

@ -401,7 +401,7 @@ public class KubernetesClusterResourceModifierActionWorker extends KubernetesClu
if (StringUtils.isNotBlank(kubernetesCluster.getKeyPair())) { if (StringUtils.isNotBlank(kubernetesCluster.getKeyPair())) {
keypairs.add(kubernetesCluster.getKeyPair()); keypairs.add(kubernetesCluster.getKeyPair());
} }
if (zone.isSecurityGroupEnabled()) { if (kubernetesCluster.getSecurityGroupId() != null && networkModel.checkSecurityGroupSupportForNetwork(zone, networkIds, List.of(kubernetesCluster.getSecurityGroupId()))) {
List<Long> securityGroupIds = new ArrayList<>(); List<Long> securityGroupIds = new ArrayList<>();
securityGroupIds.add(kubernetesCluster.getSecurityGroupId()); securityGroupIds.add(kubernetesCluster.getSecurityGroupId());
nodeVm = userVmService.createAdvancedSecurityGroupVirtualMachine(zone, serviceOffering, clusterTemplate, networkIds, securityGroupIds, owner, nodeVm = userVmService.createAdvancedSecurityGroupVirtualMachine(zone, serviceOffering, clusterTemplate, networkIds, securityGroupIds, owner,

View File

@ -215,7 +215,9 @@ public class KubernetesClusterStartWorker extends KubernetesClusterResourceModif
if (StringUtils.isNotBlank(kubernetesCluster.getKeyPair())) { if (StringUtils.isNotBlank(kubernetesCluster.getKeyPair())) {
keypairs.add(kubernetesCluster.getKeyPair()); keypairs.add(kubernetesCluster.getKeyPair());
} }
if (zone.isSecurityGroupEnabled()) { if (kubernetesCluster.getSecurityGroupId() != null &&
networkModel.checkSecurityGroupSupportForNetwork(zone, networkIds,
List.of(kubernetesCluster.getSecurityGroupId()))) {
List<Long> securityGroupIds = new ArrayList<>(); List<Long> securityGroupIds = new ArrayList<>();
securityGroupIds.add(kubernetesCluster.getSecurityGroupId()); securityGroupIds.add(kubernetesCluster.getSecurityGroupId());
controlVm = userVmService.createAdvancedSecurityGroupVirtualMachine(zone, serviceOffering, clusterTemplate, networkIds, securityGroupIds, owner, controlVm = userVmService.createAdvancedSecurityGroupVirtualMachine(zone, serviceOffering, clusterTemplate, networkIds, securityGroupIds, owner,
@ -289,7 +291,8 @@ public class KubernetesClusterStartWorker extends KubernetesClusterResourceModif
if (StringUtils.isNotBlank(kubernetesCluster.getKeyPair())) { if (StringUtils.isNotBlank(kubernetesCluster.getKeyPair())) {
keypairs.add(kubernetesCluster.getKeyPair()); keypairs.add(kubernetesCluster.getKeyPair());
} }
if (zone.isSecurityGroupEnabled()) { if (kubernetesCluster.getSecurityGroupId() != null &&
networkModel.checkSecurityGroupSupportForNetwork(zone, networkIds, List.of(kubernetesCluster.getSecurityGroupId()))) {
List<Long> securityGroupIds = new ArrayList<>(); List<Long> securityGroupIds = new ArrayList<>();
securityGroupIds.add(kubernetesCluster.getSecurityGroupId()); securityGroupIds.add(kubernetesCluster.getSecurityGroupId());
additionalControlVm = userVmService.createAdvancedSecurityGroupVirtualMachine(zone, serviceOffering, clusterTemplate, networkIds, securityGroupIds, owner, additionalControlVm = userVmService.createAdvancedSecurityGroupVirtualMachine(zone, serviceOffering, clusterTemplate, networkIds, securityGroupIds, owner,

View File

@ -145,6 +145,8 @@ import com.cloud.vm.dao.NicDao;
import com.cloud.vm.dao.NicSecondaryIpDao; import com.cloud.vm.dao.NicSecondaryIpDao;
import com.cloud.vm.dao.VMInstanceDao; import com.cloud.vm.dao.VMInstanceDao;
import static com.cloud.network.Network.Service.SecurityGroup;
public class NetworkModelImpl extends ManagerBase implements NetworkModel, Configurable { public class NetworkModelImpl extends ManagerBase implements NetworkModel, Configurable {
public static final String UNABLE_TO_USE_NETWORK = "Unable to use network with id= %s, permission denied"; public static final String UNABLE_TO_USE_NETWORK = "Unable to use network with id= %s, permission denied";
@Inject @Inject
@ -1262,7 +1264,7 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel, Confi
physicalNetworkId = findPhysicalNetworkId(network.getDataCenterId(), null, null); physicalNetworkId = findPhysicalNetworkId(network.getDataCenterId(), null, null);
} }
return isServiceEnabledInNetwork(physicalNetworkId, network.getId(), Service.SecurityGroup); return isServiceEnabledInNetwork(physicalNetworkId, network.getId(), SecurityGroup);
} }
@Override @Override
@ -2755,4 +2757,38 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel, Confi
throw new InvalidParameterValueException("Invalid IPv6 for IPv6 DNS2"); throw new InvalidParameterValueException("Invalid IPv6 for IPv6 DNS2");
} }
} }
@Override
public boolean isSecurityGroupSupportedForZone(Long zoneId) {
List<? extends PhysicalNetwork> networks = getPhysicalNtwksSupportingTrafficType(zoneId, TrafficType.Guest);
for (PhysicalNetwork network : networks ) {
if (_pNSPDao.isServiceProviderEnabled(network.getId(), Provider.SecurityGroupProvider.getName(), Service.SecurityGroup.getName())) {
return true;
}
}
return false;
}
@Override
public boolean checkSecurityGroupSupportForNetwork(DataCenter zone, List<Long> networkIds,
List<Long> securityGroupsIds) {
if (zone.isSecurityGroupEnabled()) {
return true;
}
if (CollectionUtils.isNotEmpty(networkIds)) {
for (Long networkId : networkIds) {
Network network = _networksDao.findById(networkId);
if (network == null) {
throw new InvalidParameterValueException("Unable to find network by id " + networkId);
}
if (network.getGuestType() == Network.GuestType.Shared && isSecurityGroupSupportedInNetwork(network)) {
return true;
}
}
} else if (CollectionUtils.isNotEmpty(securityGroupsIds)) {
Network networkWithSecurityGroup = getNetworkWithSGWithFreeIPs(zone.getId());
return networkWithSecurityGroup != null;
}
return false;
}
} }

View File

@ -19,6 +19,7 @@ package com.cloud.network.as;
import java.security.SecureRandom; import java.security.SecureRandom;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -37,6 +38,7 @@ import java.util.concurrent.TimeUnit;
import javax.inject.Inject; import javax.inject.Inject;
import com.cloud.network.NetworkModel;
import org.apache.cloudstack.acl.ControlledEntity; import org.apache.cloudstack.acl.ControlledEntity;
import org.apache.cloudstack.affinity.AffinityGroupVO; import org.apache.cloudstack.affinity.AffinityGroupVO;
import org.apache.cloudstack.affinity.dao.AffinityGroupDao; import org.apache.cloudstack.affinity.dao.AffinityGroupDao;
@ -251,6 +253,8 @@ public class AutoScaleManagerImpl extends ManagerBase implements AutoScaleManage
@Inject @Inject
NetworkOrchestrationService networkMgr; NetworkOrchestrationService networkMgr;
@Inject @Inject
NetworkModel networkModel;
@Inject
private UserVmManager userVmMgr; private UserVmManager userVmMgr;
@Inject @Inject
private UserDataManager userDataMgr; private UserDataManager userDataMgr;
@ -1808,7 +1812,8 @@ public class AutoScaleManagerImpl extends ManagerBase implements AutoScaleManage
null, null, true, null, affinityGroupIdList, customParameters, null, null, null, null, null, true, null, affinityGroupIdList, customParameters, null, null, null,
null, true, overrideDiskOfferingId); null, true, overrideDiskOfferingId);
} else { } else {
if (zone.isSecurityGroupEnabled()) { if (networkModel.checkSecurityGroupSupportForNetwork(zone, networkIds,
Collections.emptyList())) {
vm = userVmService.createAdvancedSecurityGroupVirtualMachine(zone, serviceOffering, template, networkIds, null, vm = userVmService.createAdvancedSecurityGroupVirtualMachine(zone, serviceOffering, template, networkIds, null,
owner, vmHostName,vmHostName, diskOfferingId, dataDiskSize, null, owner, vmHostName,vmHostName, diskOfferingId, dataDiskSize, null,
hypervisorType, HTTPMethod.GET, userData, userDataId, userDataDetails, sshKeyPairs, hypervisorType, HTTPMethod.GET, userData, userDataId, userDataDetails, sshKeyPairs,

View File

@ -27,6 +27,7 @@ import java.io.UnsupportedEncodingException;
import java.net.URLDecoder; import java.net.URLDecoder;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
@ -3094,7 +3095,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
if (zone.getNetworkType() == NetworkType.Basic) { if (zone.getNetworkType() == NetworkType.Basic) {
// Get default guest network in Basic zone // Get default guest network in Basic zone
defaultNetwork = _networkModel.getExclusiveGuestNetwork(zone.getId()); defaultNetwork = _networkModel.getExclusiveGuestNetwork(zone.getId());
} else if (zone.isSecurityGroupEnabled()) { } else if (_networkModel.checkSecurityGroupSupportForNetwork(zone, Collections.emptyList(), securityGroupIdList)) {
NicVO defaultNic = _nicDao.findDefaultNicForVM(vm.getId()); NicVO defaultNic = _nicDao.findDefaultNicForVM(vm.getId());
if (defaultNic != null) { if (defaultNic != null) {
defaultNetwork = _networkDao.findById(defaultNic.getNetworkId()); defaultNetwork = _networkDao.findById(defaultNic.getNetworkId());
@ -6153,7 +6154,8 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
dataDiskTemplateToDiskOfferingMap, userVmOVFProperties, dynamicScalingEnabled, overrideDiskOfferingId); dataDiskTemplateToDiskOfferingMap, userVmOVFProperties, dynamicScalingEnabled, overrideDiskOfferingId);
} }
} else { } else {
if (zone.isSecurityGroupEnabled()) { if (_networkModel.checkSecurityGroupSupportForNetwork(zone, networkIds,
cmd.getSecurityGroupIdList())) {
vm = createAdvancedSecurityGroupVirtualMachine(zone, serviceOffering, template, networkIds, getSecurityGroupIdList(cmd, zone, template, owner), owner, name, vm = createAdvancedSecurityGroupVirtualMachine(zone, serviceOffering, template, networkIds, getSecurityGroupIdList(cmd, zone, template, owner), owner, name,
displayName, diskOfferingId, size, group, cmd.getHypervisor(), cmd.getHttpMethod(), userData, userDataId, userDataDetails, sshKeyPairNames, cmd.getIpToNetworkMap(), addrs, displayVm, keyboard, displayName, diskOfferingId, size, group, cmd.getHypervisor(), cmd.getHttpMethod(), userData, userDataId, userDataDetails, sshKeyPairNames, cmd.getIpToNetworkMap(), addrs, displayVm, keyboard,
cmd.getAffinityGroupIdList(), cmd.getDetails(), cmd.getCustomId(), cmd.getDhcpOptionsMap(), cmd.getAffinityGroupIdList(), cmd.getDetails(), cmd.getCustomId(), cmd.getDhcpOptionsMap(),
@ -7573,7 +7575,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
Set<NetworkVO> applicableNetworks = new LinkedHashSet<>(); Set<NetworkVO> applicableNetworks = new LinkedHashSet<>();
Map<Long, String> requestedIPv4ForNics = new HashMap<>(); Map<Long, String> requestedIPv4ForNics = new HashMap<>();
Map<Long, String> requestedIPv6ForNics = new HashMap<>(); Map<Long, String> requestedIPv6ForNics = new HashMap<>();
if (zone.isSecurityGroupEnabled()) { // advanced zone with security groups if (_networkModel.checkSecurityGroupSupportForNetwork(zone, networkIdList, securityGroupIdList)) { // advanced zone with security groups
// cleanup the old security groups // cleanup the old security groups
_securityGroupMgr.removeInstanceFromGroups(cmd.getVmId()); _securityGroupMgr.removeInstanceFromGroups(cmd.getVmId());
// if networkIdList is null and the first network of vm is shared network, then keep it if possible // if networkIdList is null and the first network of vm is shared network, then keep it if possible
@ -8794,7 +8796,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
private Network getNetworkForOvfNetworkMapping(DataCenter zone, Account owner) throws InsufficientCapacityException, ResourceAllocationException { private Network getNetworkForOvfNetworkMapping(DataCenter zone, Account owner) throws InsufficientCapacityException, ResourceAllocationException {
Network network = null; Network network = null;
if (zone.isSecurityGroupEnabled()) { if (zone.isSecurityGroupEnabled() || _networkModel.isSecurityGroupSupportedForZone(zone.getId())) {
network = _networkModel.getNetworkWithSGWithFreeIPs(zone.getId()); network = _networkModel.getNetworkWithSGWithFreeIPs(zone.getId());
if (network == null) { if (network == null) {
throw new InvalidParameterValueException("No network with security enabled is found in zone ID: " + zone.getUuid()); throw new InvalidParameterValueException("No network with security enabled is found in zone ID: " + zone.getUuid());

View File

@ -291,7 +291,7 @@ public class VnfTemplateManagerImpl extends ManagerBase implements VnfTemplateMa
@Override @Override
public SecurityGroup createSecurityGroupForVnfAppliance(DataCenter zone, VirtualMachineTemplate template, Account owner, public SecurityGroup createSecurityGroupForVnfAppliance(DataCenter zone, VirtualMachineTemplate template, Account owner,
DeployVnfApplianceCmd cmd) { DeployVnfApplianceCmd cmd) {
if (zone == null || !zone.isSecurityGroupEnabled()) { if (zone == null || !(zone.isSecurityGroupEnabled() || networkModel.isSecurityGroupSupportedForZone(zone.getId()))) {
return null; return null;
} }
if (!cmd.getVnfConfigureManagement()) { if (!cmd.getVnfConfigureManagement()) {

View File

@ -938,4 +938,14 @@ public class MockNetworkModelImpl extends ManagerBase implements NetworkModel {
@Override @Override
public void verifyIp6DnsPair(String ip4Dns1, String ip4Dns2) {} public void verifyIp6DnsPair(String ip4Dns1, String ip4Dns2) {}
@Override
public boolean isSecurityGroupSupportedForZone(Long zoneId) {
return false;
}
@Override
public boolean checkSecurityGroupSupportForNetwork(DataCenter zone, List<Long> networkIds, List<Long> securityGroupsIds) {
return false;
}
} }

View File

@ -42,6 +42,7 @@ import com.cloud.exception.ResourceUnavailableException;
import com.cloud.host.HostVO; import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDao; import com.cloud.host.dao.HostDao;
import com.cloud.network.Network; import com.cloud.network.Network;
import com.cloud.network.NetworkModel;
import com.cloud.network.as.dao.AutoScalePolicyConditionMapDao; import com.cloud.network.as.dao.AutoScalePolicyConditionMapDao;
import com.cloud.network.as.dao.AutoScalePolicyDao; import com.cloud.network.as.dao.AutoScalePolicyDao;
import com.cloud.network.as.dao.AutoScaleVmGroupDao; import com.cloud.network.as.dao.AutoScaleVmGroupDao;
@ -139,6 +140,7 @@ import org.springframework.test.util.ReflectionTestUtils;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
@ -355,6 +357,8 @@ public class AutoScaleManagerImplTest {
@Mock @Mock
NetworkVO networkMock; NetworkVO networkMock;
@Mock @Mock
NetworkModel networkModel;
@Mock
NetworkOfferingVO networkOfferingMock; NetworkOfferingVO networkOfferingMock;
@Mock @Mock
CounterVO counterMock; CounterVO counterMock;
@ -1311,10 +1315,10 @@ public class AutoScaleManagerImplTest {
when(userVmMock.getId()).thenReturn(virtualMachineId); when(userVmMock.getId()).thenReturn(virtualMachineId);
when(zoneMock.getNetworkType()).thenReturn(DataCenter.NetworkType.Advanced); when(zoneMock.getNetworkType()).thenReturn(DataCenter.NetworkType.Advanced);
when(zoneMock.isSecurityGroupEnabled()).thenReturn(true);
when(userVmService.createAdvancedSecurityGroupVirtualMachine(any(), any(), any(), any(), any(), any(), any(), when(userVmService.createAdvancedSecurityGroupVirtualMachine(any(), any(), any(), any(), any(), any(), any(),
any(), any(), any(), any(), any(), any(), eq(userData), eq(userDataId), eq(userDataDetails.toString()), any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), any(), eq(userData), eq(userDataId), eq(userDataDetails.toString()), any(), any(), any(), any(), any(), any(),
any(), any(), any(), any(), any(), eq(true), any(), any())).thenReturn(userVmMock); any(), any(), any(), any(), any(), eq(true), any(), any())).thenReturn(userVmMock);
when(networkModel.checkSecurityGroupSupportForNetwork(zoneMock, List.of(networkId), Collections.emptyList())).thenReturn(true);
long result = autoScaleManagerImplSpy.createNewVM(asVmGroupMock); long result = autoScaleManagerImplSpy.createNewVM(asVmGroupMock);
@ -1360,10 +1364,10 @@ public class AutoScaleManagerImplTest {
when(userVmMock.getId()).thenReturn(virtualMachineId); when(userVmMock.getId()).thenReturn(virtualMachineId);
when(zoneMock.getNetworkType()).thenReturn(DataCenter.NetworkType.Advanced); when(zoneMock.getNetworkType()).thenReturn(DataCenter.NetworkType.Advanced);
when(zoneMock.isSecurityGroupEnabled()).thenReturn(false);
when(userVmService.createAdvancedVirtualMachine(any(), any(), any(), any(), any(), any(), any(), when(userVmService.createAdvancedVirtualMachine(any(), any(), any(), any(), any(), any(), any(),
any(), any(), any(), any(), any(), eq(userData), eq(userDataId), eq(userDataDetails.toString()), any(), any(), any(), eq(true), any(), any(), any(), any(), any(), any(), any(), any(), eq(userData), eq(userDataId), eq(userDataDetails.toString()), any(), any(), any(), eq(true), any(), any(), any(),
any(), any(), any(), any(), eq(true), any(), any())).thenReturn(userVmMock); any(), any(), any(), any(), eq(true), any(), any())).thenReturn(userVmMock);
when(networkModel.checkSecurityGroupSupportForNetwork(zoneMock, List.of(networkId), Collections.emptyList())).thenReturn(false);
long result = autoScaleManagerImplSpy.createNewVM(asVmGroupMock); long result = autoScaleManagerImplSpy.createNewVM(asVmGroupMock);

View File

@ -954,4 +954,14 @@ public class MockNetworkModelImpl extends ManagerBase implements NetworkModel {
@Override @Override
public void verifyIp6DnsPair(String ip4Dns1, String ip4Dns2) {} public void verifyIp6DnsPair(String ip4Dns1, String ip4Dns2) {}
@Override
public boolean isSecurityGroupSupportedForZone(Long zoneId) {
return false;
}
@Override
public boolean checkSecurityGroupSupportForNetwork(DataCenter zone, List<Long> networkIds, List<Long> securityGroupsIds) {
return false;
}
} }

View File

@ -29,6 +29,7 @@ import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import com.cloud.network.NetworkModel;
import org.junit.After; import org.junit.After;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Before; import org.junit.Before;
@ -56,6 +57,9 @@ public class SecondaryStorageManagerTest {
@Mock @Mock
NetworkDao _networkDao; NetworkDao _networkDao;
@Mock
NetworkModel _networkModel;
@InjectMocks @InjectMocks
SecondaryStorageManagerImpl _ssMgr = new SecondaryStorageManagerImpl(); SecondaryStorageManagerImpl _ssMgr = new SecondaryStorageManagerImpl();
@ -76,6 +80,7 @@ public class SecondaryStorageManagerTest {
DataCenterVO dc = mock(DataCenterVO.class); DataCenterVO dc = mock(DataCenterVO.class);
when(dc.getNetworkType()).thenReturn(NetworkType.Advanced); when(dc.getNetworkType()).thenReturn(NetworkType.Advanced);
when(dc.isSecurityGroupEnabled()).thenReturn(false); when(dc.isSecurityGroupEnabled()).thenReturn(false);
when(_networkModel.isSecurityGroupSupportedForZone(anyLong())).thenReturn(false);
when(_dcDao.findById(Mockito.anyLong())).thenReturn(dc); when(_dcDao.findById(Mockito.anyLong())).thenReturn(dc);
@ -102,6 +107,7 @@ public class SecondaryStorageManagerTest {
DataCenterVO dc = Mockito.mock(DataCenterVO.class); DataCenterVO dc = Mockito.mock(DataCenterVO.class);
when(dc.getNetworkType()).thenReturn(NetworkType.Advanced); when(dc.getNetworkType()).thenReturn(NetworkType.Advanced);
when(dc.isSecurityGroupEnabled()).thenReturn(true); when(dc.isSecurityGroupEnabled()).thenReturn(true);
when(_networkModel.isSecurityGroupSupportedForZone(anyLong())).thenReturn(true);
when(_dcDao.findById(Mockito.anyLong())).thenReturn(dc); when(_dcDao.findById(Mockito.anyLong())).thenReturn(dc);

View File

@ -31,7 +31,9 @@ from marvin.lib.base import (Zone,
VPC, VPC,
SecurityGroup, SecurityGroup,
Host, Host,
) NetworkServiceProvider,
PhysicalNetwork,
TrafficType)
from marvin.lib.common import (get_domain, from marvin.lib.common import (get_domain,
get_zone, get_zone,
@ -158,7 +160,9 @@ class TestCreateZoneSG(cloudstackTestCase):
return return
class TestNetworksInAdvancedSG(cloudstackTestCase): class TestNetworksInAdvancedSG(cloudstackTestCase):
"""Test Creation of different types of networks in SG enabled advanced zone""" """Test Creation of different types of networks in
- SG enabled advanced zone, or
- advanced zone without SG but with SG provider enabled"""
@classmethod @classmethod
def setUpClass(cls): def setUpClass(cls):
@ -169,6 +173,26 @@ class TestNetworksInAdvancedSG(cloudstackTestCase):
# Get Zone, Domain and templates # Get Zone, Domain and templates
cls.domain = get_domain(cls.api_client) cls.domain = get_domain(cls.api_client)
cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests())
if cls.zone.securitygroupsenabled is False:
physical_networks = PhysicalNetwork.list(cls.api_client, zoneid=cls.zone.id)
selected_physical_network = None
for net in physical_networks:
traffic_types = TrafficType.list(cls.api_client, physicalnetworkid=net.id)
for traffic_type in traffic_types:
if traffic_type.traffictype == 'Guest':
selected_physical_network = net
break
if selected_physical_network is not None:
break
if selected_physical_network is None:
raise Exception("No physical network found with guest traffic type")
# Enable security group provider for physical network
nsps = NetworkServiceProvider.list(cls.api_client, physicalnetworkid=selected_physical_network.id, name='SecurityGroupProvider')
if len(nsps) == 0:
raise Exception("No security group provider found for physical network")
NetworkServiceProvider.update(cls.api_client, nsps[0].id, state='Enabled')
cls.template = get_template(cls.api_client, cls.zone.id, cls.template = get_template(cls.api_client, cls.zone.id,
cls.services["ostype"]) cls.services["ostype"])
@ -294,7 +318,7 @@ class TestNetworksInAdvancedSG(cloudstackTestCase):
return return
@attr(tags = ["advancedsg"]) @attr(tags = ["advancedsg", "advanced"])
def test_03_createIsolatedNetwork(self): def test_03_createIsolatedNetwork(self):
""" Test Isolated Network """ """ Test Isolated Network """
@ -311,7 +335,7 @@ class TestNetworksInAdvancedSG(cloudstackTestCase):
self.isolated_network_offering = NetworkOffering.create(self.api_client, self.services["isolated_network_offering"], self.isolated_network_offering = NetworkOffering.create(self.api_client, self.services["isolated_network_offering"],
conservemode=False) conservemode=False)
self.cleanup.append(self.isolated_network_offering) self.cleanup_nwOfferings.append(self.isolated_network_offering)
self.debug("Isolated Network offering created: %s" % self.isolated_network_offering.id) self.debug("Isolated Network offering created: %s" % self.isolated_network_offering.id)
@ -374,7 +398,7 @@ class TestNetworksInAdvancedSG(cloudstackTestCase):
Exception: %s" % e) Exception: %s" % e)
return return
@attr(tags = ["advancedsg"]) @attr(tags = ["advancedsg", "advanced"])
def test_05_deployVM_SharedwithSG(self): def test_05_deployVM_SharedwithSG(self):
""" Test VM deployment in shared networks with SecurityGroup Provider """ """ Test VM deployment in shared networks with SecurityGroup Provider """
@ -453,7 +477,7 @@ class TestNetworksInAdvancedSG(cloudstackTestCase):
self.debug("Virtual Machine created: %s" % virtual_machine.id) self.debug("Virtual Machine created: %s" % virtual_machine.id)
return return
@attr(tags = ["advancedsg"]) @attr(tags = ["advancedsg", "advanced"])
def test_06_SharedNwSGAccountSpecific(self): def test_06_SharedNwSGAccountSpecific(self):
""" Test Account specific shared network creation with SG""" """ Test Account specific shared network creation with SG"""
@ -535,7 +559,7 @@ class TestNetworksInAdvancedSG(cloudstackTestCase):
return return
@attr(tags = ["advancedsg"]) @attr(tags = ["advancedsg", "advanced"])
def test_07_SharedNwSG_DomainWide_SubdomainAcccess(self): def test_07_SharedNwSG_DomainWide_SubdomainAcccess(self):
""" Test Domain wide shared network with SG, with subdomain access set True""" """ Test Domain wide shared network with SG, with subdomain access set True"""
@ -556,7 +580,7 @@ class TestNetworksInAdvancedSG(cloudstackTestCase):
self.debug("Created domain %s" % self.parent_domain.id) self.debug("Created domain %s" % self.parent_domain.id)
self.debug("Creating child domain under this domain") self.debug("Creating child domain under this domain")
self.child_domain = Domain.create(self.api_client,services=self.services["domain"], self.child_domain = Domain.create(self.api_client,services=self.services["domain"],
parentdomainid=self.parent_domain) parentdomainid=self.parent_domain.id)
self.debug("Created child domain: %s" % self.child_domain.id) self.debug("Created child domain: %s" % self.child_domain.id)
@ -753,7 +777,7 @@ class TestNetworksInAdvancedSG(cloudstackTestCase):
return return
@attr(tags = ["advancedsg"]) @attr(tags = ["advancedsg", "advanced"])
def test_10_deleteSharedNwSGAccountSpecific_InUse(self): def test_10_deleteSharedNwSGAccountSpecific_InUse(self):
""" Test delete Account specific shared network creation with SG which is in use""" """ Test delete Account specific shared network creation with SG which is in use"""
@ -806,7 +830,7 @@ class TestNetworksInAdvancedSG(cloudstackTestCase):
return return
@attr(tags = ["advancedsg"]) @attr(tags = ["advancedsg", "advanced"])
def test_11_deleteSharedNwSG_DomainWide_InUse(self): def test_11_deleteSharedNwSG_DomainWide_InUse(self):
""" Test delete Domain wide shared network with SG which is in use""" """ Test delete Domain wide shared network with SG which is in use"""
@ -861,7 +885,7 @@ class TestNetworksInAdvancedSG(cloudstackTestCase):
return return
@attr(tags = ["advancedsg"]) @attr(tags = ["advancedsg", "advanced"])
def test_29_deleteSharedNwSG_ZoneWide_InUse(self): def test_29_deleteSharedNwSG_ZoneWide_InUse(self):
""" Test delete Zone wide shared network with SG which is in use""" """ Test delete Zone wide shared network with SG which is in use"""
@ -908,7 +932,7 @@ class TestNetworksInAdvancedSG(cloudstackTestCase):
self.cleanup_vms.append(vm) self.cleanup_vms.append(vm)
return return
@attr(tags = ["advancedsg"]) @attr(tags = ["advancedsg", "advanced"])
def test_12_deleteSharedNwSGAccountSpecific_NotInUse(self): def test_12_deleteSharedNwSGAccountSpecific_NotInUse(self):
""" Test delete Account specific shared network creation with SG which is not in use""" """ Test delete Account specific shared network creation with SG which is not in use"""
@ -950,7 +974,7 @@ class TestNetworksInAdvancedSG(cloudstackTestCase):
return return
@attr(tags = ["advancedsg"]) @attr(tags = ["advancedsg", "advanced"])
def test_13_deleteSharedNwSG_DomainWide_NotInUse(self): def test_13_deleteSharedNwSG_DomainWide_NotInUse(self):
""" Test delete Domain wide shared network with SG which is not in use""" """ Test delete Domain wide shared network with SG which is not in use"""
@ -994,7 +1018,7 @@ class TestNetworksInAdvancedSG(cloudstackTestCase):
return return
@attr(tags = ["advancedsg"]) @attr(tags = ["advancedsg", "advanced"])
def test_30_deleteSharedNwSG_ZoneWide_NotInUse(self): def test_30_deleteSharedNwSG_ZoneWide_NotInUse(self):
""" Test delete zone wide shared network with SG which is not in use""" """ Test delete zone wide shared network with SG which is not in use"""
@ -1031,7 +1055,7 @@ class TestNetworksInAdvancedSG(cloudstackTestCase):
return return
@attr(tags = ["advancedsg"]) @attr(tags = ["advancedsg", "advanced"])
def test__14_createSharedNwWithSG_withoutParams(self): def test__14_createSharedNwWithSG_withoutParams(self):
""" Test create shared network with SG without specifying necessary parameters""" """ Test create shared network with SG without specifying necessary parameters"""
@ -1076,7 +1100,7 @@ class TestNetworksInAdvancedSG(cloudstackTestCase):
return return
@attr(tags = ["advancedsg"]) @attr(tags = ["advancedsg", "advanced"])
def test__15_createVPC(self): def test__15_createVPC(self):
""" Test create VPC in advanced SG enabled zone""" """ Test create VPC in advanced SG enabled zone"""
@ -1116,6 +1140,26 @@ class TestNetworksInAdvancedSG_VmOperations(cloudstackTestCase):
# Get Zone, Domain and templates # Get Zone, Domain and templates
cls.domain = get_domain(cls.api_client) cls.domain = get_domain(cls.api_client)
cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests())
if cls.zone.securitygroupsenabled is False:
physical_networks = PhysicalNetwork.list(cls.api_client, zoneid=cls.zone.id)
selected_physical_network = None
for net in physical_networks:
traffic_types = TrafficType.list(cls.api_client, physicalnetworkid=net.id)
for traffic_type in traffic_types:
if traffic_type.traffictype == 'Guest':
selected_physical_network = net
break
if selected_physical_network is not None:
break
if selected_physical_network is None:
raise Exception("No physical network found with guest traffic type")
# Enable security group provider for physical network
nsps = NetworkServiceProvider.list(cls.api_client, physicalnetworkid=selected_physical_network.id, name='SecurityGroupProvider')
if len(nsps) == 0:
raise Exception("No security group provider found for physical network")
NetworkServiceProvider.update(cls.api_client, nsps[0].id, state='Enabled')
cls.template = get_template(cls.api_client,cls.zone.id,cls.services["ostype"]) cls.template = get_template(cls.api_client,cls.zone.id,cls.services["ostype"])
cls.services["virtual_machine"]["zoneid"] = cls.zone.id cls.services["virtual_machine"]["zoneid"] = cls.zone.id
@ -1314,7 +1358,7 @@ class TestNetworksInAdvancedSG_VmOperations(cloudstackTestCase):
status = os.system("%s -i %s" %(file2, config_file)) status = os.system("%s -i %s" %(file2, config_file))
return status return status
@attr(tags = ["advancedsg"]) @attr(tags = ["advancedsg", "advanced"])
def test__16_AccountSpecificNwAccess(self): def test__16_AccountSpecificNwAccess(self):
""" Test account specific network access of users""" """ Test account specific network access of users"""
@ -1409,7 +1453,7 @@ class TestNetworksInAdvancedSG_VmOperations(cloudstackTestCase):
return return
@attr(tags = ["advancedsg"]) @attr(tags = ["advancedsg", "advanced"])
def test__17_DomainSpecificNwAccess(self): def test__17_DomainSpecificNwAccess(self):
""" Test domain specific network access of users""" """ Test domain specific network access of users"""
@ -1520,7 +1564,7 @@ class TestNetworksInAdvancedSG_VmOperations(cloudstackTestCase):
return return
@data("account", "domain") @data("account", "domain")
@attr(tags = ["advancedsg"]) @attr(tags = ["advancedsg", "advanced"])
def test_18_DeployVM_NoFreeIPs(self, value): def test_18_DeployVM_NoFreeIPs(self, value):
""" Test deploy VM in account/domain specific SG enabled shared network when no free IPs are available""" """ Test deploy VM in account/domain specific SG enabled shared network when no free IPs are available"""
@ -1624,7 +1668,7 @@ class TestNetworksInAdvancedSG_VmOperations(cloudstackTestCase):
return return
@data("default", "custom") @data("default", "custom")
@attr(tags = ["advancedsg"]) @attr(tags = ["advancedsg", "advanced"])
def test_20_DeployVM_SecGrp_sharedNetwork(self, value): def test_20_DeployVM_SecGrp_sharedNetwork(self, value):
""" Test deploy VM in default/custom security group and shared network""" """ Test deploy VM in default/custom security group and shared network"""
@ -1680,7 +1724,7 @@ class TestNetworksInAdvancedSG_VmOperations(cloudstackTestCase):
return return
@attr(tags = ["advancedsg"]) @attr(tags = ["advancedsg", "advanced"])
def test_24_DeployVM_Multiple_Shared_Networks(self): def test_24_DeployVM_Multiple_Shared_Networks(self):
""" Test deploy VM in multiple zone wide shared networks""" """ Test deploy VM in multiple zone wide shared networks"""
@ -1728,7 +1772,7 @@ class TestNetworksInAdvancedSG_VmOperations(cloudstackTestCase):
return return
@attr(tags = ["advancedsg"]) @attr(tags = ["advancedsg", "advanced"])
def test_25_Deploy_Multiple_VM_Different_Shared_Networks_Same_SG(self): def test_25_Deploy_Multiple_VM_Different_Shared_Networks_Same_SG(self):
""" Test deploy Multiple VMs in different shared networks but same security group""" """ Test deploy Multiple VMs in different shared networks but same security group"""
@ -1796,7 +1840,7 @@ class TestNetworksInAdvancedSG_VmOperations(cloudstackTestCase):
return return
@attr(tags = ["advancedsg"]) @attr(tags = ["advancedsg", "advanced"])
def test_26_Destroy_Deploy_VM_NoFreeIPs(self): def test_26_Destroy_Deploy_VM_NoFreeIPs(self):
""" Test destroy VM in zone wide shared nw when IPs are full and then try to deploy vm""" """ Test destroy VM in zone wide shared nw when IPs are full and then try to deploy vm"""
@ -1903,7 +1947,7 @@ class TestNetworksInAdvancedSG_VmOperations(cloudstackTestCase):
# Should be able to SSH VM # Should be able to SSH VM
try: try:
self.debug("SSH into VM: %s" % vm.nic[0].ipaddress) self.debug("SSH into VM: %s" % vm.nic[0].ipaddress)
vm.get_ssh_client(ipaddress=vm.nic[0].ipaddress) vm.get_ssh_client(ipaddress=vm.nic[0].ipaddress, retries=5)
self.debug("SSH to VM successful, proceeding for %s operation" % value) self.debug("SSH to VM successful, proceeding for %s operation" % value)
@ -1914,7 +1958,7 @@ class TestNetworksInAdvancedSG_VmOperations(cloudstackTestCase):
vm.reboot(self.api_client) vm.reboot(self.api_client)
self.debug("SSH into VM: %s" % vm.nic[0].ipaddress) self.debug("SSH into VM: %s" % vm.nic[0].ipaddress)
vm.get_ssh_client(ipaddress=vm.nic[0].ipaddress) vm.get_ssh_client(ipaddress=vm.nic[0].ipaddress, retries=5)
except Exception as e: except Exception as e:
self.fail("SSH Access failed for %s: %s, failed at line %s" % \ self.fail("SSH Access failed for %s: %s, failed at line %s" % \
@ -1972,7 +2016,7 @@ class TestNetworksInAdvancedSG_VmOperations(cloudstackTestCase):
# Should be able to SSH VM # Should be able to SSH VM
try: try:
self.debug("SSH into VM: %s" % vm.nic[0].ipaddress) self.debug("SSH into VM: %s" % vm.nic[0].ipaddress)
vm.get_ssh_client(ipaddress=vm.nic[0].ipaddress) vm.get_ssh_client(ipaddress=vm.nic[0].ipaddress, retries=5)
self.debug("SSH to VM successful, proceeding for %s operation" % value) self.debug("SSH to VM successful, proceeding for %s operation" % value)
vm.delete(self.api_client, expunge=False) vm.delete(self.api_client, expunge=False)
if value == "recover": if value == "recover":
@ -1989,7 +2033,7 @@ class TestNetworksInAdvancedSG_VmOperations(cloudstackTestCase):
retriesCount -= 1 retriesCount -= 1
time.sleep(10) time.sleep(10)
self.debug("SSH into VM: %s" % vm.nic[0].ipaddress) self.debug("SSH into VM: %s" % vm.nic[0].ipaddress)
vm.get_ssh_client(ipaddress=vm.nic[0].ipaddress) vm.get_ssh_client(ipaddress=vm.nic[0].ipaddress, retries=5)
self.debug("SSH successful") self.debug("SSH successful")
self.cleanup_vms.append(vm) self.cleanup_vms.append(vm)
elif value == "expunge": elif value == "expunge":
@ -2003,7 +2047,7 @@ class TestNetworksInAdvancedSG_VmOperations(cloudstackTestCase):
try: try:
self.debug("SSH into VM: %s, this should fail" % vm.nic[0].ipaddress) self.debug("SSH into VM: %s, this should fail" % vm.nic[0].ipaddress)
vm.get_ssh_client(ipaddress=vm.nic[0].ipaddress) vm.get_ssh_client(ipaddress=vm.nic[0].ipaddress, retries=5)
self.fail("SSH should have failed, instead it succeeded") self.fail("SSH should have failed, instead it succeeded")
except Exception as e: except Exception as e:
self.debug("SSH failed as expected with exception: %s" % e) self.debug("SSH failed as expected with exception: %s" % e)
@ -2019,7 +2063,7 @@ class TestNetworksInAdvancedSG_VmOperations(cloudstackTestCase):
return return
@attr(tags = ["advancedsg"]) @attr(tags = ["advancedsg", "advanced"])
def test_31_Deploy_VM_multiple_shared_networks_sg(self): def test_31_Deploy_VM_multiple_shared_networks_sg(self):
""" Test deploy VM in multiple SG enabled shared networks""" """ Test deploy VM in multiple SG enabled shared networks"""
@ -2069,7 +2113,7 @@ class TestNetworksInAdvancedSG_VmOperations(cloudstackTestCase):
@unittest.skip("Testing pending on multihost setup") @unittest.skip("Testing pending on multihost setup")
@data("account","domain","zone") @data("account","domain","zone")
@attr(tags = ["advancedsg"]) @attr(tags = ["advancedsg", "advanced"])
def test_33_VM_Migrate_SharedNwSG(self, value): def test_33_VM_Migrate_SharedNwSG(self, value):
""" Test migration of VM deployed in Account specific shared network""" """ Test migration of VM deployed in Account specific shared network"""
@ -2280,6 +2324,26 @@ class TestSecurityGroups_BasicSanity(cloudstackTestCase):
# Get Zone, Domain and templates # Get Zone, Domain and templates
cls.domain = get_domain(cls.api_client) cls.domain = get_domain(cls.api_client)
cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests())
if cls.zone.securitygroupsenabled is False:
physical_networks = PhysicalNetwork.list(cls.api_client, zoneid=cls.zone.id)
selected_physical_network = None
for net in physical_networks:
traffic_types = TrafficType.list(cls.api_client, physicalnetworkid=net.id)
for traffic_type in traffic_types:
if traffic_type.traffictype == 'Guest':
selected_physical_network = net
break
if selected_physical_network is not None:
break
if selected_physical_network is None:
raise Exception("No physical network found with guest traffic type")
# Enable security group provider for physical network
nsps = NetworkServiceProvider.list(cls.api_client, physicalnetworkid=selected_physical_network.id, name='SecurityGroupProvider')
if len(nsps) == 0:
raise Exception("No security group provider found for physical network")
NetworkServiceProvider.update(cls.api_client, nsps[0].id, state='Enabled')
cls.template = get_template(cls.api_client,cls.zone.id,cls.services["ostype"]) cls.template = get_template(cls.api_client,cls.zone.id,cls.services["ostype"])
cls.services["virtual_machine"]["zoneid"] = cls.zone.id cls.services["virtual_machine"]["zoneid"] = cls.zone.id
@ -2488,7 +2552,7 @@ class TestSecurityGroups_BasicSanity(cloudstackTestCase):
# Should be able to SSH VM # Should be able to SSH VM
try: try:
self.debug("SSH into VM: %s" % vm.nic[0].ipaddress) self.debug("SSH into VM: %s" % vm.nic[0].ipaddress)
ssh = vm.get_ssh_client(ipaddress=vm.nic[0].ipaddress) ssh = vm.get_ssh_client(ipaddress=vm.nic[0].ipaddress, retries=5)
# Ping to outsite world # Ping to outsite world
res = ssh.execute("ping -c 1 www.google.com") res = ssh.execute("ping -c 1 www.google.com")
@ -2580,7 +2644,7 @@ class TestSecurityGroups_BasicSanity(cloudstackTestCase):
# Should be able to SSH VM # Should be able to SSH VM
try: try:
self.debug("SSH into VM: %s" % vm.nic[0].ipaddress) self.debug("SSH into VM: %s" % vm.nic[0].ipaddress)
ssh = vm.get_ssh_client(ipaddress=vm.nic[0].ipaddress) ssh = vm.get_ssh_client(ipaddress=vm.nic[0].ipaddress, retries=5)
# Ping to outsite world # Ping to outsite world
res = ssh.execute("ping -c 1 www.google.com") res = ssh.execute("ping -c 1 www.google.com")
@ -2673,7 +2737,7 @@ class TestSecurityGroups_BasicSanity(cloudstackTestCase):
# Should be able to SSH VM # Should be able to SSH VM
try: try:
self.debug("SSH into VM: %s" % vm.ssh_ip) self.debug("SSH into VM: %s" % vm.ssh_ip)
ssh = vm.get_ssh_client(ipaddress=vm.nic[0].ipaddress) ssh = vm.get_ssh_client(ipaddress=vm.nic[0].ipaddress, retries=5)
# Ping to outsite world # Ping to outsite world
res = ssh.execute("ping -c 1 www.google.com") res = ssh.execute("ping -c 1 www.google.com")
@ -2695,7 +2759,7 @@ class TestSecurityGroups_BasicSanity(cloudstackTestCase):
) )
return return
@attr(tags = ["advancedsg"]) @attr(tags = ["advancedsg", "advanced"])
def test_32_delete_default_security_group(self): def test_32_delete_default_security_group(self):
""" Test Delete the default security group when No VMs are deployed""" """ Test Delete the default security group when No VMs are deployed"""
@ -2741,6 +2805,26 @@ class TestSharedNetworkOperations(cloudstackTestCase):
# Get Zone, Domain and templates # Get Zone, Domain and templates
cls.domain = get_domain(cls.api_client) cls.domain = get_domain(cls.api_client)
cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests())
if cls.zone.securitygroupsenabled is False:
physical_networks = PhysicalNetwork.list(cls.api_client, zoneid=cls.zone.id)
selected_physical_network = None
for net in physical_networks:
traffic_types = TrafficType.list(cls.api_client, physicalnetworkid=net.id)
for traffic_type in traffic_types:
if traffic_type.traffictype == 'Guest':
selected_physical_network = net
break
if selected_physical_network is not None:
break
if selected_physical_network is None:
raise Exception("No physical network found with guest traffic type")
# Enable security group provider for physical network
nsps = NetworkServiceProvider.list(cls.api_client, physicalnetworkid=selected_physical_network.id, name='SecurityGroupProvider')
if len(nsps) == 0:
raise Exception("No security group provider found for physical network")
NetworkServiceProvider.update(cls.api_client, nsps[0].id, state='Enabled')
cls.template = get_template(cls.api_client,cls.zone.id,cls.services["ostype"]) cls.template = get_template(cls.api_client,cls.zone.id,cls.services["ostype"])
cls.services["virtual_machine"]["zoneid"] = cls.zone.id cls.services["virtual_machine"]["zoneid"] = cls.zone.id
@ -2864,7 +2948,7 @@ class TestSharedNetworkOperations(cloudstackTestCase):
return return
@data("account","domain","zone") @data("account","domain","zone")
@attr(tags = ["advancedsg"]) @attr(tags = ["advancedsg", "advanced"])
def test_34_restart_shared_network_sg(self, value): def test_34_restart_shared_network_sg(self, value):
""" Test restart account/domain/zone wide shared network""" """ Test restart account/domain/zone wide shared network"""
@ -3196,7 +3280,7 @@ class TestAccountBasedIngressRules(cloudstackTestCase):
self.api_client.authorizeSecurityGroupIngress(cmd) self.api_client.authorizeSecurityGroupIngress(cmd)
self.debug("Getting SSH client of virtual machine 1: %s" % self.virtual_machine_1.id) self.debug("Getting SSH client of virtual machine 1: %s" % self.virtual_machine_1.id)
sshClient = self.virtual_machine_1.get_ssh_client(ipaddress=self.virtual_machine_1.nic[0].ipaddress) sshClient = self.virtual_machine_1.get_ssh_client(ipaddress=self.virtual_machine_1.nic[0].ipaddress, retries=5)
try: try:
if value == "accessByIp": if value == "accessByIp":
self.debug("SSHing into vm_2 %s from vm_1 %s" % (self.virtual_machine_2.nic[0].ipaddress,self.virtual_machine_1.nic[0].ipaddress)) self.debug("SSHing into vm_2 %s from vm_1 %s" % (self.virtual_machine_2.nic[0].ipaddress,self.virtual_machine_1.nic[0].ipaddress))
@ -3255,7 +3339,7 @@ class TestAccountBasedIngressRules(cloudstackTestCase):
self.api_client.authorizeSecurityGroupIngress(cmd) self.api_client.authorizeSecurityGroupIngress(cmd)
self.debug("Getting SSH client of virtual machine 1: %s" % self.virtual_machine_1.id) self.debug("Getting SSH client of virtual machine 1: %s" % self.virtual_machine_1.id)
sshClient = self.virtual_machine_1.get_ssh_client(ipaddress=self.virtual_machine_1.nic[0].ipaddress) sshClient = self.virtual_machine_1.get_ssh_client(ipaddress=self.virtual_machine_1.nic[0].ipaddress, retries=5)
try: try:
self.debug("SSHing into vm_2 %s from vm_1 %s" % (self.virtual_machine_2.nic[0].ipaddress,self.virtual_machine_1.nic[0].ipaddress)) self.debug("SSHing into vm_2 %s from vm_1 %s" % (self.virtual_machine_2.nic[0].ipaddress,self.virtual_machine_1.nic[0].ipaddress))
command = "ping -c 1 %s" % self.virtual_machine_2.nic[0].ipaddress command = "ping -c 1 %s" % self.virtual_machine_2.nic[0].ipaddress
@ -3317,7 +3401,7 @@ class TestAccountBasedIngressRules(cloudstackTestCase):
self.debug("Deployed vm: %s" % self.virtual_machine_4.id) self.debug("Deployed vm: %s" % self.virtual_machine_4.id)
self.debug("Getting SSH client of virtual machine 1: %s" % self.virtual_machine_3.id) self.debug("Getting SSH client of virtual machine 1: %s" % self.virtual_machine_3.id)
sshClient = self.virtual_machine_3.get_ssh_client(ipaddress=self.virtual_machine_3.nic[0].ipaddress) sshClient = self.virtual_machine_3.get_ssh_client(ipaddress=self.virtual_machine_3.nic[0].ipaddress, retries=5)
try: try:
if value == "accessByIp": if value == "accessByIp":
self.debug("SSHing into vm_4 %s from vm_3 %s" % (self.virtual_machine_4.nic[0].ipaddress,self.virtual_machine_3.nic[0].ipaddress)) self.debug("SSHing into vm_4 %s from vm_3 %s" % (self.virtual_machine_4.nic[0].ipaddress,self.virtual_machine_3.nic[0].ipaddress))
@ -3386,7 +3470,7 @@ class TestAccountBasedIngressRules(cloudstackTestCase):
self.debug("Deployed vm: %s" % self.virtual_machine_3.id) self.debug("Deployed vm: %s" % self.virtual_machine_3.id)
self.debug("Getting SSH client of virtual machine 1: %s" % self.virtual_machine_3.id) self.debug("Getting SSH client of virtual machine 1: %s" % self.virtual_machine_3.id)
sshClient = self.virtual_machine_3.get_ssh_client(ipaddress=self.virtual_machine_3.nic[0].ipaddress) sshClient = self.virtual_machine_3.get_ssh_client(ipaddress=self.virtual_machine_3.nic[0].ipaddress, retries=5)
try: try:
if value == "accessByIp": if value == "accessByIp":
self.debug("SSHing into vm_2 %s from vm_3 %s" % (self.virtual_machine_2.nic[0].ipaddress,self.virtual_machine_3.nic[0].ipaddress)) self.debug("SSHing into vm_2 %s from vm_3 %s" % (self.virtual_machine_2.nic[0].ipaddress,self.virtual_machine_3.nic[0].ipaddress))
@ -3446,7 +3530,7 @@ class TestAccountBasedIngressRules(cloudstackTestCase):
self.debug("Getting SSH client of virtual machine 1: %s" % self.virtual_machine_1.id) self.debug("Getting SSH client of virtual machine 1: %s" % self.virtual_machine_1.id)
try: try:
sshClient = self.virtual_machine_1.get_ssh_client(ipaddress=self.virtual_machine_1.nic[0].ipaddress) sshClient = self.virtual_machine_1.get_ssh_client(ipaddress=self.virtual_machine_1.nic[0].ipaddress, retries=5)
self.debug("SSHing into vm_2 %s from vm_1 %s" % (self.virtual_machine_2.nic[0].ipaddress,self.virtual_machine_1.nic[0].ipaddress)) self.debug("SSHing into vm_2 %s from vm_1 %s" % (self.virtual_machine_2.nic[0].ipaddress,self.virtual_machine_1.nic[0].ipaddress))
command = "ssh -t -t root@%s" % self.virtual_machine_2.nic[0].ipaddress command = "ssh -t -t root@%s" % self.virtual_machine_2.nic[0].ipaddress
self.debug("command: --> %s" % command) self.debug("command: --> %s" % command)
@ -3468,7 +3552,7 @@ class TestAccountBasedIngressRules(cloudstackTestCase):
self.debug("Getting SSH client of virtual machine 1: %s" % self.virtual_machine_1.id) self.debug("Getting SSH client of virtual machine 1: %s" % self.virtual_machine_1.id)
try: try:
sshClient = self.virtual_machine_1.get_ssh_client(ipaddress=self.virtual_machine_1.nic[0].ipaddress) sshClient = self.virtual_machine_1.get_ssh_client(ipaddress=self.virtual_machine_1.nic[0].ipaddress, retries=5)
self.debug("SSHing into vm_2 %s from vm_1 %s" % (self.virtual_machine_2.nic[0].ipaddress,self.virtual_machine_1.nic[0].ipaddress)) self.debug("SSHing into vm_2 %s from vm_1 %s" % (self.virtual_machine_2.nic[0].ipaddress,self.virtual_machine_1.nic[0].ipaddress))
command = "ssh -t -t root@%s" % self.virtual_machine_2.nic[0].ipaddress command = "ssh -t -t root@%s" % self.virtual_machine_2.nic[0].ipaddress
self.debug("command: --> %s" % command) self.debug("command: --> %s" % command)

View File

@ -28,7 +28,10 @@ from marvin.lib.base import (Account,
SecurityGroup, SecurityGroup,
Router, Router,
Host, Host,
Network) Network,
PhysicalNetwork,
TrafficType,
NetworkServiceProvider)
from marvin.lib.common import (get_domain, from marvin.lib.common import (get_domain,
get_zone, get_zone,
get_template, get_template,
@ -73,6 +76,26 @@ class TestDefaultSecurityGroup(cloudstackTestCase):
# Get Zone, Domain and templates # Get Zone, Domain and templates
cls.domain = get_domain(cls.api_client) cls.domain = get_domain(cls.api_client)
cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests()) cls.zone = get_zone(cls.api_client, cls.testClient.getZoneForTests())
if cls.zone.securitygroupsenabled is False:
physical_networks = PhysicalNetwork.list(cls.api_client, zoneid=cls.zone.id)
selected_physical_network = None
for net in physical_networks:
traffic_types = TrafficType.list(cls.api_client, physicalnetworkid=net.id)
for traffic_type in traffic_types:
if traffic_type.traffictype == 'Guest':
selected_physical_network = net
break
if selected_physical_network is not None:
break
if selected_physical_network is None:
raise Exception("No physical network found with guest traffic type")
# Enable security group provider for physical network
nsps = NetworkServiceProvider.list(cls.api_client, physicalnetworkid=selected_physical_network.id, name='SecurityGroupProvider')
if len(nsps) == 0:
raise Exception("No security group provider found for physical network")
NetworkServiceProvider.update(cls.api_client, nsps[0].id, state='Enabled')
cls.testdata['mode'] = cls.zone.networktype cls.testdata['mode'] = cls.zone.networktype
template = get_template( template = get_template(
@ -115,7 +138,7 @@ class TestDefaultSecurityGroup(cloudstackTestCase):
return return
@attr(tags=["sg", "basic", "eip", "advancedsg"]) @attr(tags=["sg", "basic", "eip", "advancedsg", "advanced"])
def test_01_deployVM_InDefaultSecurityGroup(self): def test_01_deployVM_InDefaultSecurityGroup(self):
"""Test deploy VM in default security group """Test deploy VM in default security group
""" """
@ -193,7 +216,7 @@ class TestDefaultSecurityGroup(cloudstackTestCase):
) )
return return
@attr(tags=["sg", "basic", "eip", "advancedsg"]) @attr(tags=["sg", "basic", "eip", "advancedsg", "advanced"])
def test_02_listSecurityGroups(self): def test_02_listSecurityGroups(self):
"""Test list security groups for admin account """Test list security groups for admin account
""" """
@ -228,7 +251,7 @@ class TestDefaultSecurityGroup(cloudstackTestCase):
) )
return return
@attr(tags=["sg", "basic", "eip", "advancedsg"]) @attr(tags=["sg", "basic", "eip", "advancedsg", "advanced"])
def test_03_accessInDefaultSecurityGroup(self): def test_03_accessInDefaultSecurityGroup(self):
"""Test access in default security group """Test access in default security group
""" """
@ -314,7 +337,8 @@ class TestDefaultSecurityGroup(cloudstackTestCase):
self.virtual_machine.ssh_ip, self.virtual_machine.ssh_ip,
self.virtual_machine.ssh_port, self.virtual_machine.ssh_port,
self.virtual_machine.username, self.virtual_machine.username,
self.virtual_machine.password self.virtual_machine.password,
retries=5
) )
return return
@ -453,7 +477,7 @@ class TestAuthorizeIngressRule(cloudstackTestCase):
# Should be able to SSH VM # Should be able to SSH VM
try: try:
self.debug("SSH into VM: %s" % self.virtual_machine.id) self.debug("SSH into VM: %s" % self.virtual_machine.id)
self.virtual_machine.get_ssh_client() self.virtual_machine.get_ssh_client(retries=5)
except Exception as e: except Exception as e:
self.fail("SSH Access failed for %s: %s" % self.fail("SSH Access failed for %s: %s" %
(self.virtual_machine.ipaddress, e) (self.virtual_machine.ipaddress, e)
@ -604,7 +628,7 @@ class TestRevokeIngressRule(cloudstackTestCase):
# Should be able to SSH VM # Should be able to SSH VM
try: try:
self.debug("SSH into VM: %s" % self.virtual_machine.id) self.debug("SSH into VM: %s" % self.virtual_machine.id)
self.virtual_machine.get_ssh_client() self.virtual_machine.get_ssh_client(retries=5)
except Exception as e: except Exception as e:
self.fail("SSH Access failed for %s: %s" % self.fail("SSH Access failed for %s: %s" %
(self.virtual_machine.ipaddress, e) (self.virtual_machine.ipaddress, e)
@ -937,7 +961,7 @@ class TestdeployVMWithUserData(cloudstackTestCase):
% self.virtual_machine.ssh_ip % self.virtual_machine.ssh_ip
) )
ssh = self.virtual_machine.get_ssh_client() ssh = self.virtual_machine.get_ssh_client(retries=5)
except Exception as e: except Exception as e:
self.fail("SSH Access failed for %s: %s" % self.fail("SSH Access failed for %s: %s" %
(self.virtual_machine.ipaddress, e) (self.virtual_machine.ipaddress, e)
@ -1348,7 +1372,7 @@ class TestIngressRule(cloudstackTestCase):
self.virtual_machine.ssh_ip, self.virtual_machine.ssh_ip,
self.testdata["ingress_rule"]["endport"] self.testdata["ingress_rule"]["endport"]
)) ))
self.virtual_machine.get_ssh_client() self.virtual_machine.get_ssh_client(retries=5)
except Exception as e: except Exception as e:
self.fail("SSH access failed for ingress rule ID: %s, %s" self.fail("SSH access failed for ingress rule ID: %s, %s"
@ -1476,7 +1500,7 @@ class TestIngressRule(cloudstackTestCase):
self.virtual_machine.ssh_ip, self.virtual_machine.ssh_ip,
self.testdata["ingress_rule"]["endport"] self.testdata["ingress_rule"]["endport"]
)) ))
self.virtual_machine.get_ssh_client() self.virtual_machine.get_ssh_client(retries=5)
except Exception as e: except Exception as e:
self.fail("SSH access failed for ingress rule ID: %s, %s" self.fail("SSH access failed for ingress rule ID: %s, %s"
@ -1623,7 +1647,7 @@ class TestIngressRule(cloudstackTestCase):
self.debug( self.debug(
"Trying to SSH into VM %s" % "Trying to SSH into VM %s" %
self.virtual_machine.ssh_ip) self.virtual_machine.ssh_ip)
self.virtual_machine.get_ssh_client() self.virtual_machine.get_ssh_client(retries=5)
except Exception as e: except Exception as e:
self.fail("SSH access failed for ingress rule ID: %s" self.fail("SSH access failed for ingress rule ID: %s"
% ingress_rule["id"] % ingress_rule["id"]
@ -1642,7 +1666,7 @@ class TestIngressRule(cloudstackTestCase):
self.debug( self.debug(
"Trying to SSH into VM %s" % "Trying to SSH into VM %s" %
self.virtual_machine.ssh_ip) self.virtual_machine.ssh_ip)
self.virtual_machine.get_ssh_client() self.virtual_machine.get_ssh_client(retries=5)
except Exception as e: except Exception as e:
self.fail("SSH access failed for ingress rule ID: %s" self.fail("SSH access failed for ingress rule ID: %s"
% ingress_rule["id"] % ingress_rule["id"]

View File

@ -209,6 +209,7 @@
"label.action.unmanage.volume": "Unmanage Volume", "label.action.unmanage.volume": "Unmanage Volume",
"label.action.unmanage.volumes": "Unmanage Volumes", "label.action.unmanage.volumes": "Unmanage Volumes",
"label.action.update.host": "Update host", "label.action.update.host": "Update host",
"label.action.update.security.groups": "Update security groups",
"label.action.update.offering.access": "Update offering access", "label.action.update.offering.access": "Update offering access",
"label.action.update.resource.count": "Update resource count", "label.action.update.resource.count": "Update resource count",
"label.action.value": "Action/Value", "label.action.value": "Action/Value",

View File

@ -307,10 +307,7 @@ export default {
return false return false
} }
const listZoneHaveSGEnabled = store.getters.zones.filter(zone => zone.securitygroupsenabled === true) const listZoneHaveSGEnabled = store.getters.zones.filter(zone => zone.securitygroupsenabled === true)
if (!listZoneHaveSGEnabled || listZoneHaveSGEnabled.length === 0) { return (listZoneHaveSGEnabled && listZoneHaveSGEnabled.length > 0) || store.getters.showSecurityGroups
return false
}
return true
}, },
actions: [ actions: [
{ {

View File

@ -36,6 +36,7 @@ const getters = {
isLdapEnabled: state => state.user.isLdapEnabled, isLdapEnabled: state => state.user.isLdapEnabled,
cloudian: state => state.user.cloudian, cloudian: state => state.user.cloudian,
zones: state => state.user.zones, zones: state => state.user.zones,
showSecurityGroups: state => state.user.showSecurityGroups,
timezoneoffset: state => state.user.timezoneoffset, timezoneoffset: state => state.user.timezoneoffset,
usebrowsertimezone: state => state.user.usebrowsertimezone, usebrowsertimezone: state => state.user.usebrowsertimezone,
server: state => state.app.server, server: state => state.app.server,

View File

@ -34,6 +34,7 @@ import {
DEFAULT_THEME, DEFAULT_THEME,
APIS, APIS,
ZONES, ZONES,
SHOW_SECURTIY_GROUPS,
TIMEZONE_OFFSET, TIMEZONE_OFFSET,
USE_BROWSER_TIMEZONE, USE_BROWSER_TIMEZONE,
HEADER_NOTICES, HEADER_NOTICES,
@ -124,6 +125,10 @@ const user = {
state.zones = zones state.zones = zones
vueProps.$localStorage.set(ZONES, zones) vueProps.$localStorage.set(ZONES, zones)
}, },
SET_SHOW_SECURITY_GROUPS: (state, show) => {
state.showSecurityGroups = show
vueProps.$localStorage.set(SHOW_SECURTIY_GROUPS, show)
},
SET_DOMAIN_STORE (state, domainStore) { SET_DOMAIN_STORE (state, domainStore) {
state.domainStore = domainStore state.domainStore = domainStore
vueProps.$localStorage.set(DOMAIN_STORE, domainStore) vueProps.$localStorage.set(DOMAIN_STORE, domainStore)
@ -290,6 +295,7 @@ const user = {
const cachedUseBrowserTimezone = vueProps.$localStorage.get(USE_BROWSER_TIMEZONE, false) const cachedUseBrowserTimezone = vueProps.$localStorage.get(USE_BROWSER_TIMEZONE, false)
const cachedCustomColumns = vueProps.$localStorage.get(CUSTOM_COLUMNS, {}) const cachedCustomColumns = vueProps.$localStorage.get(CUSTOM_COLUMNS, {})
const domainStore = vueProps.$localStorage.get(DOMAIN_STORE, {}) const domainStore = vueProps.$localStorage.get(DOMAIN_STORE, {})
const cachedShowSecurityGroups = vueProps.$localStorage.get(SHOW_SECURTIY_GROUPS, false)
const darkMode = vueProps.$localStorage.get(DARK_MODE, false) const darkMode = vueProps.$localStorage.get(DARK_MODE, false)
const latestVersion = vueProps.$localStorage.get(LATEST_CS_VERSION, { version: '', fetchedTs: 0 }) const latestVersion = vueProps.$localStorage.get(LATEST_CS_VERSION, { version: '', fetchedTs: 0 })
const hasAuth = Object.keys(cachedApis).length > 0 const hasAuth = Object.keys(cachedApis).length > 0
@ -300,6 +306,7 @@ const user = {
if (hasAuth) { if (hasAuth) {
console.log('Login detected, using cached APIs') console.log('Login detected, using cached APIs')
commit('SET_ZONES', cachedZones) commit('SET_ZONES', cachedZones)
commit('SET_SHOW_SECURITY_GROUPS', cachedShowSecurityGroups)
commit('SET_APIS', cachedApis) commit('SET_APIS', cachedApis)
commit('SET_TIMEZONE_OFFSET', cachedTimezoneOffset) commit('SET_TIMEZONE_OFFSET', cachedTimezoneOffset)
commit('SET_USE_BROWSER_TIMEZONE', cachedUseBrowserTimezone) commit('SET_USE_BROWSER_TIMEZONE', cachedUseBrowserTimezone)
@ -388,6 +395,15 @@ const user = {
reject(error) reject(error)
}) })
api(
'listNetworkServiceProviders',
{ name: 'SecurityGroupProvider', state: 'Enabled' }
).then(response => {
const showSecurityGroups = response.listnetworkserviceprovidersresponse.count > 0
commit('SET_SHOW_SECURITY_GROUPS', showSecurityGroups)
}).catch(ignored => {
})
api('listCapabilities').then(response => { api('listCapabilities').then(response => {
const result = response.listcapabilitiesresponse.capability const result = response.listcapabilitiesresponse.capability
commit('SET_FEATURES', result) commit('SET_FEATURES', result)
@ -397,6 +413,9 @@ const user = {
if (result && result.customhypervisordisplayname) { if (result && result.customhypervisordisplayname) {
commit('SET_CUSTOM_HYPERVISOR_NAME', result.customhypervisordisplayname) commit('SET_CUSTOM_HYPERVISOR_NAME', result.customhypervisordisplayname)
} }
if (result && result.securitygroupsenabled) {
commit('SET_SHOW_SECURITY_GROUPS', result.securitygroupsenabled)
}
}).catch(error => { }).catch(error => {
reject(error) reject(error)
}) })

View File

@ -29,6 +29,7 @@ export const DEFAULT_CONTENT_WIDTH_TYPE = 'DEFAULT_CONTENT_WIDTH_TYPE'
export const DEFAULT_MULTI_TAB = 'DEFAULT_MULTI_TAB' export const DEFAULT_MULTI_TAB = 'DEFAULT_MULTI_TAB'
export const APIS = 'APIS' export const APIS = 'APIS'
export const ZONES = 'ZONES' export const ZONES = 'ZONES'
export const SHOW_SECURTIY_GROUPS = 'SHOW_SECURITY_GROUPS'
export const HEADER_NOTICES = 'HEADER_NOTICES' export const HEADER_NOTICES = 'HEADER_NOTICES'
export const TIMEZONE_OFFSET = 'TIMEZONE_OFFSET' export const TIMEZONE_OFFSET = 'TIMEZONE_OFFSET'
export const USE_BROWSER_TIMEZONE = 'USE_BROWSER_TIMEZONE' export const USE_BROWSER_TIMEZONE = 'USE_BROWSER_TIMEZONE'

View File

@ -1369,7 +1369,19 @@ export default {
return tabList return tabList
}, },
showSecurityGroupSection () { showSecurityGroupSection () {
return (this.networks.length > 0 && this.zone?.securitygroupsenabled) || (this.zone?.networktype === 'Basic') if (this.networks.length < 1) {
return false
}
for (const network of this.options.networks) {
if (this.form.networkids && this.form.networkids.includes(network.id)) {
for (const service of network.service) {
if (service.name === 'SecurityGroup') {
return true
}
}
}
}
return false
}, },
isUserAllowedToListSshKeys () { isUserAllowedToListSshKeys () {
return Boolean('listSSHKeyPairs' in this.$store.getters.apis) return Boolean('listSSHKeyPairs' in this.$store.getters.apis)

View File

@ -117,7 +117,14 @@
:routerlinks="(record) => { return { id: '/backup/' + record.id } }" :routerlinks="(record) => { return { id: '/backup/' + record.id } }"
:showSearch="false"/> :showSearch="false"/>
</a-tab-pane> </a-tab-pane>
<a-tab-pane :tab="$t('label.securitygroups')" key="securitygroups" v-if="dataResource.securitygroup && dataResource.securitygroup.length > 0"> <a-tab-pane :tab="$t('label.securitygroups')" key="securitygroups" v-if="dataResource.securitygroup && dataResource.securitygroup.length > 0 || $store.getters.showSecurityGroups">
<a-button
type="primary"
style="width: 100%; margin-bottom: 10px"
@click="showUpdateSGModal"
:loading="loading">
<template #icon><edit-outlined /></template> {{ $t('label.action.update.security.groups') }}
</a-button>
<ListResourceTable <ListResourceTable
:items="dataResource.securitygroup" :items="dataResource.securitygroup"
:columns="['name', 'description']" :columns="['name', 'description']"
@ -143,6 +150,21 @@
</a-tab-pane> </a-tab-pane>
</a-tabs> </a-tabs>
<a-modal
:visible="showUpdateSecurityGroupsModal"
:title="$t('label.action.update.security.groups')"
:maskClosable="false"
:closable="true"
@ok="updateSecurityGroups"
@cancel="closeModals">
<security-group-selection
:zoneId="this.vm.zoneid"
:value="securitygroupids"
:loading="false"
:preFillContent="dataPreFill"
@select-security-group-item="($event) => updateSecurityGroupsSelection($event)"></security-group-selection>
</a-modal>
<a-modal <a-modal
:visible="showAddVolumeModal" :visible="showAddVolumeModal"
:title="$t('label.action.create.volume.add')" :title="$t('label.action.create.volume.add')"
@ -320,6 +342,7 @@ import TooltipButton from '@/components/widgets/TooltipButton'
import ResourceIcon from '@/components/view/ResourceIcon' import ResourceIcon from '@/components/view/ResourceIcon'
import AnnotationsTab from '@/components/view/AnnotationsTab' import AnnotationsTab from '@/components/view/AnnotationsTab'
import VolumesTab from '@/components/view/VolumesTab.vue' import VolumesTab from '@/components/view/VolumesTab.vue'
import SecurityGroupSelection from '@views/compute/wizard/SecurityGroupSelection'
export default { export default {
name: 'InstanceTab', name: 'InstanceTab',
@ -333,6 +356,7 @@ export default {
NicsTable, NicsTable,
InstanceSchedules, InstanceSchedules,
ListResourceTable, ListResourceTable,
SecurityGroupSelection,
TooltipButton, TooltipButton,
ResourceIcon, ResourceIcon,
AnnotationsTab, AnnotationsTab,
@ -359,6 +383,7 @@ export default {
showAddNetworkModal: false, showAddNetworkModal: false,
showUpdateIpModal: false, showUpdateIpModal: false,
showSecondaryIpModal: false, showSecondaryIpModal: false,
showUpdateSecurityGroupsModal: false,
diskOfferings: [], diskOfferings: [],
addNetworkData: { addNetworkData: {
allNetworks: [], allNetworks: [],
@ -366,6 +391,7 @@ export default {
ip: '' ip: ''
}, },
loadingNic: false, loadingNic: false,
loadingSG: false,
editIpAddressNic: '', editIpAddressNic: '',
editIpAddressValue: '', editIpAddressValue: '',
editNetworkId: '', editNetworkId: '',
@ -378,7 +404,9 @@ export default {
opts: [] opts: []
}, },
annotations: [], annotations: [],
dataResource: {} dataResource: {},
dataPreFill: {},
securitygroupids: []
} }
}, },
created () { created () {
@ -501,11 +529,24 @@ export default {
this.showAddNetworkModal = true this.showAddNetworkModal = true
this.listNetworks() this.listNetworks()
}, },
showUpdateSGModal () {
this.loadingSG = true
if (this.vm.securitygroup && this.vm.securitygroup?.length > 0) {
this.securitygroupids = []
for (const sg of this.vm.securitygroup) {
this.securitygroupids.push(sg.id)
}
this.dataPreFill = { securitygroupids: this.securitygroupids }
}
this.showUpdateSecurityGroupsModal = true
this.loadingSG = false
},
closeModals () { closeModals () {
this.showAddVolumeModal = false this.showAddVolumeModal = false
this.showAddNetworkModal = false this.showAddNetworkModal = false
this.showUpdateIpModal = false this.showUpdateIpModal = false
this.showSecondaryIpModal = false this.showSecondaryIpModal = false
this.showUpdateSecurityGroupsModal = false
this.addNetworkData.network = '' this.addNetworkData.network = ''
this.addNetworkData.ip = '' this.addNetworkData.ip = ''
this.editIpAddressValue = '' this.editIpAddressValue = ''
@ -730,6 +771,17 @@ export default {
this.loadingNic = false this.loadingNic = false
this.fetchSecondaryIPs(this.selectedNicId) this.fetchSecondaryIPs(this.selectedNicId)
}) })
},
updateSecurityGroupsSelection (securitygroupids) {
this.securitygroupids = securitygroupids || []
},
updateSecurityGroups () {
api('updateVirtualMachine', { id: this.vm.id, securitygroupids: this.securitygroupids.join(',') }).catch(error => {
this.$notifyError(error)
}).finally(() => {
this.closeModals()
this.parentFetchData()
})
} }
} }
} }

View File

@ -94,7 +94,7 @@ export default {
} }
], ],
items: [], items: [],
selectedRowKeys: [], selectedRowKeys: this?.preFillContent?.securitygroupids || [],
page: 1, page: 1,
pageSize: 10, pageSize: 10,
keyword: null, keyword: null,

View File

@ -937,10 +937,38 @@ export default {
} }
] ]
}, },
// { {
// title: 'SecurityGroupProvider', title: 'SecurityGroupProvider',
// details: ['name', 'state', 'id', 'servicelist'], details: ['name', 'state', 'id', 'servicelist'],
// }, actions: [
{
api: 'updateNetworkServiceProvider',
icon: 'stop-outlined',
listView: true,
label: 'label.disable.provider',
confirm: 'message.confirm.disable.provider',
show: (record) => { return record && record.id && record.state === 'Enabled' },
mapping: {
state: {
value: (record) => { return 'Disabled' }
}
}
},
{
api: 'updateNetworkServiceProvider',
icon: 'play-circle-outlined',
listView: true,
label: 'label.enable.provider',
confirm: 'message.confirm.enable.provider',
show: (record) => { return record && record.id && record.state === 'Disabled' },
mapping: {
state: {
value: (record) => { return 'Enabled' }
}
}
}
]
},
{ {
title: 'VirtualRouter', title: 'VirtualRouter',
actions: [ actions: [