Skip to content

Commit 0b9afe7

Browse files
authored
Enforce distinct hostnames network (#10212)
* Check for unique hostnames for all networks in the vpc * Address comments
1 parent cc6ee90 commit 0b9afe7

File tree

5 files changed

+122
-11
lines changed

5 files changed

+122
-11
lines changed

engine/schema/src/main/java/com/cloud/network/dao/NetworkDao.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import java.util.List;
2020
import java.util.Map;
21+
import java.util.Set;
2122

2223
import com.cloud.network.Network;
2324
import com.cloud.network.Network.GuestType;
@@ -47,6 +48,12 @@ public interface NetworkDao extends GenericDao<NetworkVO, Long>, StateDao<State,
4748

4849
int getOtherPersistentNetworksCount(long id, String broadcastURI, boolean isPersistent);
4950

51+
List<NetworkVO> listByNetworkDomains(Set<String> uniqueNtwkDomains);
52+
53+
List<NetworkVO> listByNetworkDomainsAndAccountIds(Set<String> uniqueNtwkDomains, Set<Long> accountIds);
54+
55+
List<NetworkVO> listByNetworkDomainsAndDomainIds(Set<String> uniqueNtwkDomains, Set<Long> domainIds);
56+
5057
/**
5158
* Retrieves the next available mac address in this network configuration.
5259
*

engine/schema/src/main/java/com/cloud/network/dao/NetworkDaoImpl.java

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long>implements Ne
8686

8787
GenericSearchBuilder<NetworkVO, Long> GarbageCollectedSearch;
8888
SearchBuilder<NetworkVO> PrivateNetworkSearch;
89+
SearchBuilder<NetworkVO> NetworkDomainSearch;
8990

9091
@Inject
9192
ResourceTagDao _tagsDao;
@@ -198,6 +199,12 @@ protected void init() {
198199
PersistentNetworkSearch.join("persistent", persistentNtwkOffJoin, PersistentNetworkSearch.entity().getNetworkOfferingId(), persistentNtwkOffJoin.entity().getId(), JoinType.INNER);
199200
PersistentNetworkSearch.done();
200201

202+
NetworkDomainSearch = createSearchBuilder();
203+
NetworkDomainSearch.and("networkDomains", NetworkDomainSearch.entity().getNetworkDomain(), Op.IN);
204+
NetworkDomainSearch.and("accounts", NetworkDomainSearch.entity().getAccountId(), Op.IN);
205+
NetworkDomainSearch.and("domains", NetworkDomainSearch.entity().getDomainId(), Op.IN);
206+
NetworkDomainSearch.done();
207+
201208
PhysicalNetworkSearch = createSearchBuilder();
202209
PhysicalNetworkSearch.and("physicalNetworkId", PhysicalNetworkSearch.entity().getPhysicalNetworkId(), Op.EQ);
203210
PhysicalNetworkSearch.done();
@@ -428,6 +435,29 @@ public List<NetworkVO> getAllPersistentNetworksFromZone(long dataCenterId) {
428435
return search(sc, null);
429436
}
430437

438+
@Override
439+
public List<NetworkVO> listByNetworkDomains(Set<String> uniqueNtwkDomains) {
440+
SearchCriteria<NetworkVO> sc = NetworkDomainSearch.create();
441+
sc.setParameters("networkDomains", uniqueNtwkDomains.toArray());
442+
return search(sc, null);
443+
}
444+
445+
@Override
446+
public List<NetworkVO> listByNetworkDomainsAndAccountIds(Set<String> uniqueNtwkDomains, Set<Long> accountIds) {
447+
SearchCriteria<NetworkVO> sc = NetworkDomainSearch.create();
448+
sc.setParameters("networkDomains", uniqueNtwkDomains.toArray());
449+
sc.setParameters("accounts", accountIds.toArray());
450+
return search(sc, null);
451+
}
452+
453+
@Override
454+
public List<NetworkVO> listByNetworkDomainsAndDomainIds(Set<String> uniqueNtwkDomains, Set<Long> domainIds) {
455+
SearchCriteria<NetworkVO> sc = NetworkDomainSearch.create();
456+
sc.setParameters("networkDomains", uniqueNtwkDomains.toArray());
457+
sc.setParameters("domains", domainIds.toArray());
458+
return search(sc, null);
459+
}
460+
431461
@Override
432462
public String getNextAvailableMacAddress(final long networkConfigId, Integer zoneMacIdentifier) {
433463
final SequenceFetcher fetch = SequenceFetcher.getInstance();

server/src/main/java/com/cloud/vm/UserVmManager.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,12 @@ public interface UserVmManager extends UserVmService {
8383
"If set to true, tags specified in `resource.limit.host.tags` are also included in vm.strict.host.tags.",
8484
true);
8585

86+
ConfigKey<String> VmDistinctHostNameScope = new ConfigKey<>(String.class, "vm.distinct.hostname.scope", ConfigKey.CATEGORY_ADVANCED,
87+
"network",
88+
"Defines the scope for enforcing unique VM hostnames which determines the resource boundary within which VM hostnames must be unique. Possible values: global, domain, subdomain, account, network.",
89+
true, ConfigKey.Scope.Global, null, "VM distinct hostname scope", null, null, null, ConfigKey.Kind.Select,
90+
"global,domain,subdomain,account,network");
91+
8692
ConfigKey<Boolean> EnableAdditionalVmConfig = new ConfigKey<>(
8793
"Advanced",
8894
Boolean.class,
@@ -92,6 +98,7 @@ public interface UserVmManager extends UserVmService {
9298
true,
9399
ConfigKey.Scope.Account);
94100

101+
95102
static final int MAX_USER_DATA_LENGTH_BYTES = 2048;
96103

97104
public static final String CKS_NODE = "cksnode";

server/src/main/java/com/cloud/vm/UserVmManagerImpl.java

Lines changed: 63 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4698,23 +4698,75 @@ protected void verifyIfHypervisorSupportsRootdiskSizeOverride(HypervisorType hyp
46984698
}
46994699
}
47004700

4701-
private void checkIfHostNameUniqueInNtwkDomain(String hostName, List<? extends Network> networkList) {
4702-
// Check that hostName is unique in the network domain
4703-
Map<String, List<Long>> ntwkDomains = new HashMap<String, List<Long>>();
4701+
private List<NetworkVO> getNetworksWithSameNetworkDomainInDomains(List<NetworkVO> networkList, boolean checkSubDomains) {
4702+
Set<String> uniqueNtwkDomains = networkList.stream().map(NetworkVO::getNetworkDomain).collect(Collectors.toSet());
4703+
Set<Long> domainIdList = new HashSet<>();
47044704
for (Network network : networkList) {
4705+
domainIdList.add(network.getDomainId());
4706+
}
4707+
Set<Long> finalDomainIdSet = new HashSet<>(domainIdList);
4708+
if (checkSubDomains) {
4709+
for (Long domainId : domainIdList) {
4710+
DomainVO domain = _domainDao.findById(domainId);
4711+
List<Long> childDomainIds = _domainDao.getDomainChildrenIds(domain.getPath());
4712+
finalDomainIdSet.addAll(childDomainIds);
4713+
}
4714+
}
4715+
return _networkDao.listByNetworkDomainsAndDomainIds(uniqueNtwkDomains, finalDomainIdSet);
4716+
}
4717+
4718+
private List<NetworkVO> getNetworksForCheckUniqueHostName(List<NetworkVO> networkList) {
4719+
List<NetworkVO> finalNetworkList;
4720+
Set<String> uniqueNtwkDomains;
4721+
switch (VmDistinctHostNameScope.value()) {
4722+
case "global":
4723+
uniqueNtwkDomains = networkList.stream().map(NetworkVO::getNetworkDomain).collect(Collectors.toSet());
4724+
finalNetworkList = _networkDao.listByNetworkDomains(uniqueNtwkDomains);
4725+
break;
4726+
case "domain":
4727+
finalNetworkList = getNetworksWithSameNetworkDomainInDomains(networkList, false);
4728+
break;
4729+
case "subdomain":
4730+
finalNetworkList = getNetworksWithSameNetworkDomainInDomains(networkList, true);
4731+
break;
4732+
case "account":
4733+
uniqueNtwkDomains = networkList.stream().map(NetworkVO::getNetworkDomain).collect(Collectors.toSet());
4734+
Set<Long> accountIds = networkList.stream().map(Network::getAccountId).collect(Collectors.toSet());
4735+
finalNetworkList = _networkDao.listByNetworkDomainsAndAccountIds(uniqueNtwkDomains, accountIds);
4736+
break;
4737+
default:
4738+
Set<Long> vpcIds = networkList.stream().map(Network::getVpcId).filter(Objects::nonNull).collect(Collectors.toSet());
4739+
finalNetworkList = new ArrayList<>(networkList);
4740+
for (Long vpcId : vpcIds) {
4741+
finalNetworkList.addAll(_networkDao.listByVpc(vpcId));
4742+
}
4743+
break;
4744+
}
4745+
return finalNetworkList;
4746+
}
4747+
4748+
private Map<String, Set<Long>> getNetworkIdPerNetworkDomain(List<NetworkVO> networkList) {
4749+
Map<String, Set<Long>> ntwkDomains = new HashMap<>();
4750+
4751+
List<NetworkVO> updatedNetworkList = getNetworksForCheckUniqueHostName(networkList);
4752+
for (Network network : updatedNetworkList) {
47054753
String ntwkDomain = network.getNetworkDomain();
4754+
Set<Long> ntwkIds;
47064755
if (!ntwkDomains.containsKey(ntwkDomain)) {
4707-
List<Long> ntwkIds = new ArrayList<Long>();
4708-
ntwkIds.add(network.getId());
4709-
ntwkDomains.put(ntwkDomain, ntwkIds);
4756+
ntwkIds = new HashSet<>();
47104757
} else {
4711-
List<Long> ntwkIds = ntwkDomains.get(ntwkDomain);
4712-
ntwkIds.add(network.getId());
4713-
ntwkDomains.put(ntwkDomain, ntwkIds);
4758+
ntwkIds = ntwkDomains.get(ntwkDomain);
47144759
}
4760+
ntwkIds.add(network.getId());
4761+
ntwkDomains.put(ntwkDomain, ntwkIds);
47154762
}
4763+
return ntwkDomains;
4764+
}
47164765

4717-
for (Entry<String, List<Long>> ntwkDomain : ntwkDomains.entrySet()) {
4766+
private void checkIfHostNameUniqueInNtwkDomain(String hostName, List<NetworkVO> networkList) {
4767+
// Check that hostName is unique
4768+
Map<String, Set<Long>> ntwkDomains = getNetworkIdPerNetworkDomain(networkList);
4769+
for (Entry<String, Set<Long>> ntwkDomain : ntwkDomains.entrySet()) {
47184770
for (Long ntwkId : ntwkDomain.getValue()) {
47194771
// * get all vms hostNames in the network
47204772
List<String> hostNames = _vmInstanceDao.listDistinctHostNames(ntwkId);
@@ -9284,7 +9336,7 @@ public ConfigKey<?>[] getConfigKeys() {
92849336
return new ConfigKey<?>[] {EnableDynamicallyScaleVm, AllowDiskOfferingChangeDuringScaleVm, AllowUserExpungeRecoverVm, VmIpFetchWaitInterval, VmIpFetchTrialMax,
92859337
VmIpFetchThreadPoolMax, VmIpFetchTaskWorkers, AllowDeployVmIfGivenHostFails, EnableAdditionalVmConfig, DisplayVMOVFProperties,
92869338
KvmAdditionalConfigAllowList, XenServerAdditionalConfigAllowList, VmwareAdditionalConfigAllowList, DestroyRootVolumeOnVmDestruction,
9287-
EnforceStrictResourceLimitHostTagCheck, StrictHostTags, AllowUserForceStopVm};
9339+
EnforceStrictResourceLimitHostTagCheck, StrictHostTags, AllowUserForceStopVm, VmDistinctHostNameScope};
92889340
}
92899341

92909342
@Override

server/src/test/java/com/cloud/vpc/dao/MockNetworkDaoImpl.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import java.util.ArrayList;
3030
import java.util.List;
3131
import java.util.Map;
32+
import java.util.Set;
3233

3334
@DB()
3435
public class MockNetworkDaoImpl extends GenericDaoBase<NetworkVO, Long> implements NetworkDao {
@@ -265,4 +266,18 @@ public List<NetworkVO> getAllPersistentNetworksFromZone(long dataCenterId) {
265266
return null;
266267
}
267268

269+
@Override
270+
public List<NetworkVO> listByNetworkDomains(Set<String> uniqueNtwkDomains) {
271+
return List.of();
272+
}
273+
274+
@Override
275+
public List<NetworkVO> listByNetworkDomainsAndAccountIds(Set<String> uniqueNtwkDomains, Set<Long> accountIds) {
276+
return List.of();
277+
}
278+
279+
@Override
280+
public List<NetworkVO> listByNetworkDomainsAndDomainIds(Set<String> uniqueNtwkDomains, Set<Long> domainIds) {
281+
return List.of();
282+
}
268283
}

0 commit comments

Comments
 (0)