From 47615a26b613473971cd5a8a5cbaccde7c191721 Mon Sep 17 00:00:00 2001 From: Alena Prokharchyk Date: Mon, 16 Jul 2012 13:34:25 -0700 Subject: [PATCH] VPC: CS-15583 - hostName for the vm should be unique inside the network domain --- .../com/cloud/network/dao/NetworkDaoImpl.java | 3 +- .../src/com/cloud/vm/UserVmManagerImpl.java | 31 ++++++++++++++++- .../src/com/cloud/vm/dao/VMInstanceDao.java | 8 +++++ .../com/cloud/vm/dao/VMInstanceDaoImpl.java | 34 ++++++++++++++++++- 4 files changed, 73 insertions(+), 3 deletions(-) diff --git a/server/src/com/cloud/network/dao/NetworkDaoImpl.java b/server/src/com/cloud/network/dao/NetworkDaoImpl.java index 766481796d9..d644286c053 100644 --- a/server/src/com/cloud/network/dao/NetworkDaoImpl.java +++ b/server/src/com/cloud/network/dao/NetworkDaoImpl.java @@ -71,8 +71,9 @@ public class NetworkDaoImpl extends GenericDaoBase implements N private final GenericSearchBuilder NetworksCount; final SearchBuilder SourceNATSearch; final GenericSearchBuilder CountByZoneAndURI; + + ResourceTagsDaoImpl _tagsDao = ComponentLocator.inject(ResourceTagsDaoImpl.class); - NetworkAccountDaoImpl _accountsDao = ComponentLocator.inject(NetworkAccountDaoImpl.class); NetworkDomainDaoImpl _domainsDao = ComponentLocator.inject(NetworkDomainDaoImpl.class); NetworkOpDaoImpl _opDao = ComponentLocator.inject(NetworkOpDaoImpl.class); diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java index 917e3e6a41f..b57ac15ab25 100755 --- a/server/src/com/cloud/vm/UserVmManagerImpl.java +++ b/server/src/com/cloud/vm/UserVmManagerImpl.java @@ -2403,14 +2403,43 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager String instanceName = VirtualMachineName.getVmName(id, owner.getId(), _instance); String uuidName = UUID.randomUUID().toString(); + + //verify hostname information if (hostName == null) { hostName = uuidName; } else { - // verify hostName (hostname doesn't have to be unique) + //1) check is hostName is RFC complient if (!NetUtils.verifyDomainNameLabel(hostName, true)) { throw new InvalidParameterValueException("Invalid name. Vm name can contain ASCII letters 'a' through 'z', the digits '0' through '9', " + "and the hyphen ('-'), must be between 1 and 63 characters long, and can't start or end with \"-\" and can't start with digit"); } + //2) hostName has to be unique in the network domain + Map> ntwkDomains = new HashMap>(); + for (NetworkVO network : networkList) { + String ntwkDomain = network.getNetworkDomain(); + if (!ntwkDomains.containsKey(ntwkDomain)) { + List ntwkIds = new ArrayList(); + ntwkIds.add(network.getId()); + ntwkDomains.put(ntwkDomain, ntwkIds); + } else { + List ntwkIds = ntwkDomains.get(ntwkDomain); + ntwkIds.add(network.getId()); + ntwkDomains.put(ntwkDomain, ntwkIds); + } + } + + for (String ntwkDomain : ntwkDomains.keySet()) { + for (Long ntwkId : ntwkDomains.get(ntwkDomain)) { + //* get all vms hostNames in the network + List hostNames = _vmInstanceDao.listDistinctHostNames(ntwkId); + //* verify that there are no duplicates + if (hostNames.contains(hostName)) { + throw new InvalidParameterValueException("The vm with hostName " + hostName + + " already exists in the network domain: " + ntwkDomain + "; network=" + + _networkMgr.getNetwork(ntwkId)); + } + } + } } HypervisorType hypervisorType = null; diff --git a/server/src/com/cloud/vm/dao/VMInstanceDao.java b/server/src/com/cloud/vm/dao/VMInstanceDao.java index 3aebba45337..2cf3d75018c 100644 --- a/server/src/com/cloud/vm/dao/VMInstanceDao.java +++ b/server/src/com/cloud/vm/dao/VMInstanceDao.java @@ -26,6 +26,7 @@ import com.cloud.utils.fsm.StateDao; import com.cloud.vm.VMInstanceVO; import com.cloud.vm.VirtualMachine; import com.cloud.vm.VirtualMachine.State; +import com.cloud.vm.VirtualMachine.Type; /* @@ -100,4 +101,11 @@ public interface VMInstanceDao extends GenericDao, StateDao< List listNonRemovedVmsByTypeAndNetwork(long networkId, VirtualMachine.Type... types); + /** + * @param networkId + * @param types + * @return + */ + List listDistinctHostNames(long networkId, VirtualMachine.Type... types); + } diff --git a/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java b/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java index 8de2f941f62..db4ab1631f6 100644 --- a/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java +++ b/server/src/com/cloud/vm/dao/VMInstanceDaoImpl.java @@ -78,7 +78,10 @@ public class VMInstanceDaoImpl extends GenericDaoBase implem protected GenericSearchBuilder CountRunningByHost; protected GenericSearchBuilder CountRunningByAccount; protected SearchBuilder NetworkTypeSearch; + protected GenericSearchBuilder DistinctHostNameSearch; + ResourceTagsDaoImpl _tagsDao = ComponentLocator.inject(ResourceTagsDaoImpl.class); + NicDao _nicDao = ComponentLocator.inject(NicDaoImpl.class); protected final Attribute _updateTimeAttr; @@ -98,6 +101,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase implem protected final HostDaoImpl _hostDao = ComponentLocator.inject(HostDaoImpl.class); protected VMInstanceDaoImpl() { + IdStatesSearch = createSearchBuilder(); IdStatesSearch.and("id", IdStatesSearch.entity().getId(), Op.EQ); IdStatesSearch.and("states", IdStatesSearch.entity().getState(), Op.IN); @@ -533,7 +537,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase implem @Override public List listNonRemovedVmsByTypeAndNetwork(long networkId, VirtualMachine.Type... types) { if (NetworkTypeSearch == null) { - NicDao _nicDao = ComponentLocator.getLocator("management-server").getDao(NicDao.class); + SearchBuilder nicSearch = _nicDao.createSearchBuilder(); nicSearch.and("networkId", nicSearch.entity().getNetworkId(), SearchCriteria.Op.EQ); @@ -554,6 +558,34 @@ public class VMInstanceDaoImpl extends GenericDaoBase implem return listBy(sc); } + + + @Override + public List listDistinctHostNames(long networkId, VirtualMachine.Type... types) { + if (DistinctHostNameSearch == null) { + + SearchBuilder nicSearch = _nicDao.createSearchBuilder(); + nicSearch.and("networkId", nicSearch.entity().getNetworkId(), SearchCriteria.Op.EQ); + + DistinctHostNameSearch = createSearchBuilder(String.class); + DistinctHostNameSearch.selectField(DistinctHostNameSearch.entity().getHostName()); + + DistinctHostNameSearch.and("types", DistinctHostNameSearch.entity().getType(), SearchCriteria.Op.IN); + DistinctHostNameSearch.and("removed", DistinctHostNameSearch.entity().getRemoved(), SearchCriteria.Op.NULL); + DistinctHostNameSearch.join("nicSearch", nicSearch, DistinctHostNameSearch.entity().getId(), + nicSearch.entity().getInstanceId(), JoinBuilder.JoinType.INNER); + DistinctHostNameSearch.done(); + } + + SearchCriteria sc = DistinctHostNameSearch.create(); + if (types != null && types.length != 0) { + sc.setParameters("types", (Object[]) types); + } + sc.setJoinParameters("nicSearch", "networkId", networkId); + + return customSearch(sc, null); + } + @Override @DB public boolean remove(Long id) {