Skip to content

Commit 8888b27

Browse files
committed
Add global setting vm.distinct.hostname.scope
1 parent 91a2ffe commit 8888b27

File tree

4 files changed

+86
-11
lines changed

4 files changed

+86
-11
lines changed

engine/schema/src/main/java/com/cloud/vm/dao/VMInstanceDao.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.util.HashMap;
2121
import java.util.List;
2222
import java.util.Map;
23+
import java.util.Set;
2324

2425
import com.cloud.hypervisor.Hypervisor;
2526
import com.cloud.utils.Pair;
@@ -144,6 +145,10 @@ public interface VMInstanceDao extends GenericDao<VMInstanceVO, Long>, StateDao<
144145
*/
145146
List<String> listDistinctHostNames(long networkId, VirtualMachine.Type... types);
146147

148+
boolean hostNameExistsInDomainIds(String hostName, Set<Long> domainIdList);
149+
150+
boolean hostNameExistsInDomainIdsAccountIds(String hostName, Set<Long> accountIdList);
151+
147152
List<VMInstanceVO> findByHostInStates(Long hostId, State... states);
148153

149154
List<VMInstanceVO> listStartingWithNoHostId();

engine/schema/src/main/java/com/cloud/vm/dao/VMInstanceDaoImpl.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,13 @@
2424
import java.util.HashMap;
2525
import java.util.List;
2626
import java.util.Map;
27+
import java.util.Set;
2728
import java.util.stream.Collectors;
2829

2930
import javax.annotation.PostConstruct;
3031
import javax.inject.Inject;
3132

33+
import org.apache.commons.collections.CollectionUtils;
3234
import org.apache.log4j.Logger;
3335
import org.springframework.stereotype.Component;
3436

@@ -294,6 +296,8 @@ protected void init() {
294296
DistinctHostNameSearch.selectFields(DistinctHostNameSearch.entity().getHostName());
295297

296298
DistinctHostNameSearch.and("types", DistinctHostNameSearch.entity().getType(), SearchCriteria.Op.IN);
299+
DistinctHostNameSearch.and("accounts", DistinctHostNameSearch.entity().getAccountId(), SearchCriteria.Op.IN);
300+
DistinctHostNameSearch.and("domains", DistinctHostNameSearch.entity().getDomainId(), SearchCriteria.Op.IN);
297301
DistinctHostNameSearch.and("removed", DistinctHostNameSearch.entity().getRemoved(), SearchCriteria.Op.NULL);
298302
DistinctHostNameSearch.join("nicSearch", nicSearch, DistinctHostNameSearch.entity().getId(), nicSearch.entity().getInstanceId(), JoinBuilder.JoinType.INNER);
299303
DistinctHostNameSearch.done();
@@ -885,6 +889,20 @@ public List<String> listDistinctHostNames(long networkId, VirtualMachine.Type...
885889
return customSearch(sc, null);
886890
}
887891

892+
public boolean hostNameExistsInDomainIds(String hostName, Set<Long> domainIdList) {
893+
SearchCriteria<String> sc = DistinctHostNameSearch.create();
894+
sc.setParameters("domains", domainIdList.toArray());
895+
896+
return CollectionUtils.isNotEmpty(customSearch(sc, null));
897+
}
898+
899+
public boolean hostNameExistsInDomainIdsAccountIds(String hostName, Set<Long> accountIdList) {
900+
SearchCriteria<String> sc = DistinctHostNameSearch.create();
901+
sc.setParameters("accounts", accountIdList.toArray());
902+
903+
return CollectionUtils.isNotEmpty(customSearch(sc, null));
904+
}
905+
888906
@Override
889907
@DB
890908
public boolean remove(Long id) {

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@ public interface UserVmManager extends UserVmService {
5959
"Destroys the VM's root volume when the VM is destroyed.",
6060
true, ConfigKey.Scope.Domain);
6161

62+
ConfigKey<String> VmDistinctHostNameScope = new ConfigKey<>(String.class, "vm.distinct.hostname.scope", ConfigKey.CATEGORY_ADVANCED,
63+
"network",
64+
"Scope of resources to check while checking if the hostname is unique. Possible values are global, domain, subdomain, account, network.",
65+
true, ConfigKey.Scope.Global, null, "VM distinct hostname scope", null, null, null, ConfigKey.Kind.Select,
66+
"global,domain,subdomain,account,network");
67+
6268
static final int MAX_USER_DATA_LENGTH_BYTES = 2048;
6369

6470
public static final String CKS_NODE = "cksnode";

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

Lines changed: 57 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4472,18 +4472,64 @@ private Map<String, Set<Long>> getNetworkIdPerNetworkDomain(List<? extends Netwo
44724472

44734473
private void checkIfHostNameUniqueInNtwkDomain(String hostName, List<? extends Network> networkList) {
44744474
// Check that hostName is unique in the network domain
4475-
Map<String, Set<Long>> ntwkDomains = getNetworkIdPerNetworkDomain(networkList);
4476-
for (Entry<String, Set<Long>> ntwkDomain : ntwkDomains.entrySet()) {
4477-
for (Long ntwkId : ntwkDomain.getValue()) {
4478-
// * get all vms hostNames in the network
4479-
List<String> hostNames = _vmInstanceDao.listDistinctHostNames(ntwkId);
4480-
// * verify that there are no duplicates
4481-
if (hostNames.contains(hostName)) {
4482-
throw new InvalidParameterValueException("The vm with hostName " + hostName + " already exists in the network domain: " + ntwkDomain.getKey() + "; network="
4483-
+ ((_networkModel.getNetwork(ntwkId) != null) ? _networkModel.getNetwork(ntwkId).getName() : "<unknown>"));
4475+
Set<Long> domainIdList = new HashSet<>();
4476+
switch (VmDistinctHostNameScope.value()) {
4477+
case "global":
4478+
// Check that hostName is unique in the zone
4479+
VMInstanceVO vm = _vmInstanceDao.findVMByHostName(hostName);
4480+
if (vm != null) {
4481+
throw new InvalidParameterValueException("The vm with hostName " + hostName + " already exists in the zone");
4482+
}
4483+
case "domain":
4484+
// Check that hostName is unique in the domain
4485+
for (Network network : networkList) {
4486+
domainIdList.add(network.getDomainId());
4487+
}
4488+
if (_vmInstanceDao.hostNameExistsInDomainIds(hostName, domainIdList)) {
4489+
throw new InvalidParameterValueException("The vm with hostName " + hostName + " already exists in the domain");
4490+
}
4491+
break;
4492+
case "subdomain":
4493+
for (Network network : networkList) {
4494+
domainIdList.add(network.getDomainId());
4495+
}
4496+
Set<Long> finalDomainIdList = new HashSet<>();
4497+
for (Long domainId : domainIdList) {
4498+
finalDomainIdList.add(domainId);
4499+
DomainVO domain = _domainDao.findById(domainId);
4500+
List<Long> childDomainIds = _domainDao.getDomainChildrenIds(domain.getPath());
4501+
finalDomainIdList.addAll(childDomainIds);
4502+
}
4503+
4504+
if (_vmInstanceDao.hostNameExistsInDomainIds(hostName, finalDomainIdList)) {
4505+
throw new InvalidParameterValueException("The vm with hostName " + hostName + " already exists in the domain or subdomain");
4506+
}
4507+
break;
4508+
case "account":
4509+
// Check that hostName is unique in the account
4510+
Set<Long> accountIdList = new HashSet<>();
4511+
for (Network network : networkList) {
4512+
accountIdList.add(network.getAccountId());
4513+
}
4514+
if (_vmInstanceDao.hostNameExistsInDomainIdsAccountIds(hostName, accountIdList)) {
4515+
throw new InvalidParameterValueException("The vm with hostName " + hostName + " already exists in the account");
4516+
}
4517+
break;
4518+
default:
4519+
Map<String, Set<Long>> ntwkDomains = getNetworkIdPerNetworkDomain(networkList);
4520+
for (Entry<String, Set<Long>> ntwkDomain : ntwkDomains.entrySet()) {
4521+
for (Long ntwkId : ntwkDomain.getValue()) {
4522+
// * get all vms hostNames in the network
4523+
List<String> hostNames = _vmInstanceDao.listDistinctHostNames(ntwkId);
4524+
// * verify that there are no duplicates
4525+
if (hostNames.contains(hostName)) {
4526+
throw new InvalidParameterValueException("The vm with hostName " + hostName + " already exists in the network domain: " + ntwkDomain.getKey() + "; network="
4527+
+ ((_networkModel.getNetwork(ntwkId) != null) ? _networkModel.getNetwork(ntwkId).getName() : "<unknown>"));
4528+
}
4529+
}
44844530
}
4485-
}
44864531
}
4532+
44874533
}
44884534

44894535
private String generateHostName(String uuidName) {
@@ -8250,7 +8296,7 @@ public String getConfigComponentName() {
82508296
public ConfigKey<?>[] getConfigKeys() {
82518297
return new ConfigKey<?>[] {EnableDynamicallyScaleVm, AllowDiskOfferingChangeDuringScaleVm, AllowUserExpungeRecoverVm, VmIpFetchWaitInterval, VmIpFetchTrialMax,
82528298
VmIpFetchThreadPoolMax, VmIpFetchTaskWorkers, AllowDeployVmIfGivenHostFails, EnableAdditionalVmConfig, DisplayVMOVFProperties,
8253-
KvmAdditionalConfigAllowList, XenServerAdditionalConfigAllowList, VmwareAdditionalConfigAllowList, DestroyRootVolumeOnVmDestruction};
8299+
KvmAdditionalConfigAllowList, XenServerAdditionalConfigAllowList, VmwareAdditionalConfigAllowList, DestroyRootVolumeOnVmDestruction, VmDistinctHostNameScope};
82548300
}
82558301

82568302
@Override

0 commit comments

Comments
 (0)