Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@ public interface NetworkDao extends GenericDao<NetworkVO, Long>, StateDao<State,

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

List<NetworkVO> listByNetworkDomains(List<String> uniqueNtwkDomains);

List<NetworkVO> listByNetworkDomainsAndAccountIds(List<String> uniqueNtwkDomains, List<Long> accountIds);

List<NetworkVO> listByNetworkDomainsAndDomainIds(List<String> uniqueNtwkDomains, List<Long> domainIds);

/**
* Retrieves the next available mac address in this network configuration.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long>implements Ne

GenericSearchBuilder<NetworkVO, Long> GarbageCollectedSearch;
SearchBuilder<NetworkVO> PrivateNetworkSearch;
SearchBuilder<NetworkVO> NetworkDomainSearch;

@Inject
ResourceTagDao _tagsDao;
Expand Down Expand Up @@ -198,6 +199,12 @@ protected void init() {
PersistentNetworkSearch.join("persistent", persistentNtwkOffJoin, PersistentNetworkSearch.entity().getNetworkOfferingId(), persistentNtwkOffJoin.entity().getId(), JoinType.INNER);
PersistentNetworkSearch.done();

NetworkDomainSearch = createSearchBuilder();
NetworkDomainSearch.and("networkDomains", NetworkDomainSearch.entity().getNetworkDomain(), Op.IN);
NetworkDomainSearch.and("accounts", NetworkDomainSearch.entity().getAccountId(), Op.IN);
NetworkDomainSearch.and("domains", NetworkDomainSearch.entity().getDomainId(), Op.IN);
NetworkDomainSearch.done();

PhysicalNetworkSearch = createSearchBuilder();
PhysicalNetworkSearch.and("physicalNetworkId", PhysicalNetworkSearch.entity().getPhysicalNetworkId(), Op.EQ);
PhysicalNetworkSearch.done();
Expand Down Expand Up @@ -428,6 +435,29 @@ public List<NetworkVO> getAllPersistentNetworksFromZone(long dataCenterId) {
return search(sc, null);
}

@Override
public List<NetworkVO> listByNetworkDomains(List<String> uniqueNtwkDomains) {
SearchCriteria<NetworkVO> sc = NetworkDomainSearch.create();
sc.setParameters("networkDomains", uniqueNtwkDomains.toArray());
return search(sc, null);
}

@Override
public List<NetworkVO> listByNetworkDomainsAndAccountIds(List<String> uniqueNtwkDomains, List<Long> accountIds) {
SearchCriteria<NetworkVO> sc = NetworkDomainSearch.create();
sc.setParameters("networkDomains", uniqueNtwkDomains.toArray());
sc.setParameters("accounts", accountIds.toArray());
return search(sc, null);
}

@Override
public List<NetworkVO> listByNetworkDomainsAndDomainIds(List<String> uniqueNtwkDomains, List<Long> domainIds) {
SearchCriteria<NetworkVO> sc = NetworkDomainSearch.create();
sc.setParameters("networkDomains", uniqueNtwkDomains.toArray());
sc.setParameters("domains", domainIds.toArray());
return search(sc, null);
}

@Override
public String getNextAvailableMacAddress(final long networkConfigId, Integer zoneMacIdentifier) {
final SequenceFetcher fetch = SequenceFetcher.getInstance();
Expand Down
6 changes: 6 additions & 0 deletions server/src/main/java/com/cloud/vm/UserVmManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,12 @@ public interface UserVmManager extends UserVmService {
"If set to true, tags specified in `resource.limit.host.tags` are also included in vm.strict.host.tags.",
true);

ConfigKey<String> VmDistinctHostNameScope = new ConfigKey<>(String.class, "vm.distinct.hostname.scope", ConfigKey.CATEGORY_ADVANCED,
"network",
"Scope of resources to check while checking if the hostname is unique. Possible values are global, domain, subdomain, account, network.",
true, ConfigKey.Scope.Global, null, "VM distinct hostname scope", null, null, null, ConfigKey.Kind.Select,
"global,domain,subdomain,account,network");

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please help me understand what's the purpose of this global setting, if VM names have to be unique within a network domain?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, the network domain can be same for networks in different domain, account, etc. If a user a launches a VM with the same name in these networks, there can be conflict. This global setting allows the user to set scope for what all networks we need to check when creating a vm.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@vishesh92 can you please add "project" and "vpc" to the scope

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For project, we specify account_id as the project id. So, this is covered by the account scope. Adding project will make the check complicated.
For networks in a VPC, the network domain is same for all.

static final int MAX_USER_DATA_LENGTH_BYTES = 2048;

public static final String CKS_NODE = "cksnode";
Expand Down
74 changes: 63 additions & 11 deletions server/src/main/java/com/cloud/vm/UserVmManagerImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -4691,23 +4691,75 @@ protected void verifyIfHypervisorSupportsRootdiskSizeOverride(HypervisorType hyp
}
}

private void checkIfHostNameUniqueInNtwkDomain(String hostName, List<? extends Network> networkList) {
// Check that hostName is unique in the network domain
Map<String, List<Long>> ntwkDomains = new HashMap<String, List<Long>>();
private List<NetworkVO> getNetworksWithSameNetworkDomainInDomains(List<NetworkVO> networkList, boolean checkSubDomains) {
List<String> uniqueNtwkDomains = networkList.stream().map(NetworkVO::getNetworkDomain).collect(Collectors.toList());
List<Long> domainIdList = new ArrayList<>();
for (Network network : networkList) {
domainIdList.add(network.getDomainId());
}
Set<Long> finalDomainIdList = new HashSet<>(domainIdList);
if (checkSubDomains) {
for (Long domainId : domainIdList) {
DomainVO domain = _domainDao.findById(domainId);
List<Long> childDomainIds = _domainDao.getDomainChildrenIds(domain.getPath());
finalDomainIdList.addAll(childDomainIds);
}
}
return _networkDao.listByNetworkDomainsAndDomainIds(uniqueNtwkDomains, finalDomainIdList.stream().collect(Collectors.toList()));
}

private List<NetworkVO> getNetworksForCheckUniqueHostName(List<NetworkVO> networkList) {
List<NetworkVO> finalNetworkList;
List<String> uniqueNtwkDomains;
switch (VmDistinctHostNameScope.value()) {
case "global":
uniqueNtwkDomains = networkList.stream().map(NetworkVO::getNetworkDomain).collect(Collectors.toList());
finalNetworkList = _networkDao.listByNetworkDomains(uniqueNtwkDomains);
break;
case "domain":
finalNetworkList = getNetworksWithSameNetworkDomainInDomains(networkList, false);
break;
case "subdomain":
finalNetworkList = getNetworksWithSameNetworkDomainInDomains(networkList, true);
break;
case "account":
uniqueNtwkDomains = networkList.stream().map(NetworkVO::getNetworkDomain).collect(Collectors.toList());
List<Long> accountIds = networkList.stream().map(Network::getAccountId).collect(Collectors.toList());
finalNetworkList = _networkDao.listByNetworkDomainsAndAccountIds(uniqueNtwkDomains, accountIds);
break;
default:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

presuming the default section is for scope network, how this will behave for isolated or L2 networks ? I see you are checking only for VPCs

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

finalNetworkList = new ArrayList<>(networkList);

We set the final networklist to network list. And we fetch all networks for the VPCs to the final network list.

Set<Long> vpcIds = networkList.stream().map(Network::getVpcId).filter(Objects::nonNull).collect(Collectors.toSet());
finalNetworkList = new ArrayList<>(networkList);
for (Long vpcId : vpcIds) {
finalNetworkList.addAll(_networkDao.listByVpc(vpcId));
}
break;
}
return finalNetworkList;
}

private Map<String, Set<Long>> getNetworkIdPerNetworkDomain(List<NetworkVO> networkList) {
Map<String, Set<Long>> ntwkDomains = new HashMap<>();

List<NetworkVO> updatedNetworkList = getNetworksForCheckUniqueHostName(networkList);
for (Network network : updatedNetworkList) {
String ntwkDomain = network.getNetworkDomain();
Set<Long> ntwkIds;
if (!ntwkDomains.containsKey(ntwkDomain)) {
List<Long> ntwkIds = new ArrayList<Long>();
ntwkIds.add(network.getId());
ntwkDomains.put(ntwkDomain, ntwkIds);
ntwkIds = new HashSet<>();
} else {
List<Long> ntwkIds = ntwkDomains.get(ntwkDomain);
ntwkIds.add(network.getId());
ntwkDomains.put(ntwkDomain, ntwkIds);
ntwkIds = ntwkDomains.get(ntwkDomain);
}
ntwkIds.add(network.getId());
ntwkDomains.put(ntwkDomain, ntwkIds);
}
return ntwkDomains;
}

for (Entry<String, List<Long>> ntwkDomain : ntwkDomains.entrySet()) {
private void checkIfHostNameUniqueInNtwkDomain(String hostName, List<NetworkVO> networkList) {
// Check that hostName is unique
Map<String, Set<Long>> ntwkDomains = getNetworkIdPerNetworkDomain(networkList);
for (Entry<String, Set<Long>> ntwkDomain : ntwkDomains.entrySet()) {
for (Long ntwkId : ntwkDomain.getValue()) {
// * get all vms hostNames in the network
List<String> hostNames = _vmInstanceDao.listDistinctHostNames(ntwkId);
Expand Down Expand Up @@ -9244,7 +9296,7 @@ public ConfigKey<?>[] getConfigKeys() {
return new ConfigKey<?>[] {EnableDynamicallyScaleVm, AllowDiskOfferingChangeDuringScaleVm, AllowUserExpungeRecoverVm, VmIpFetchWaitInterval, VmIpFetchTrialMax,
VmIpFetchThreadPoolMax, VmIpFetchTaskWorkers, AllowDeployVmIfGivenHostFails, EnableAdditionalVmConfig, DisplayVMOVFProperties,
KvmAdditionalConfigAllowList, XenServerAdditionalConfigAllowList, VmwareAdditionalConfigAllowList, DestroyRootVolumeOnVmDestruction,
EnforceStrictResourceLimitHostTagCheck, StrictHostTags, AllowUserForceStopVm};
EnforceStrictResourceLimitHostTagCheck, StrictHostTags, AllowUserForceStopVm, VmDistinctHostNameScope};
}

@Override
Expand Down
14 changes: 14 additions & 0 deletions server/src/test/java/com/cloud/vpc/dao/MockNetworkDaoImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -265,4 +265,18 @@ public List<NetworkVO> getAllPersistentNetworksFromZone(long dataCenterId) {
return null;
}

@Override
public List<NetworkVO> listByNetworkDomains(List<String> uniqueNtwkDomains) {
return List.of();
}

@Override
public List<NetworkVO> listByNetworkDomainsAndAccountIds(List<String> uniqueNtwkDomains, List<Long> accountIds) {
return List.of();
}

@Override
public List<NetworkVO> listByNetworkDomainsAndDomainIds(List<String> uniqueNtwkDomains, List<Long> domainIds) {
return List.of();
}
}
Loading