@Test public void test() throws ApiSenderException { EipInventory eip = deployer.eips.get("eip"); VmInstanceInventory vm = deployer.vms.get("TestVm"); VmNicInventory nic = vm.getVmNics().get(0); IpRangeInventory ipr = deployer.ipRanges.get("GuestIpRange"); String newIp = null; long s = NetworkUtils.ipv4StringToLong(ipr.getStartIp()); long e = NetworkUtils.ipv4StringToLong(ipr.getEndIp()); for (long l = s; s < e; s++) { String ip = NetworkUtils.longToIpv4String(l); if (!ip.equals(nic.getIp())) { newIp = ip; break; } } Assert.assertNotNull(newIp); api.stopVmInstance(vm.getUuid()); api.setStaticIp(vm.getUuid(), nic.getL3NetworkUuid(), newIp); EipVO eipvo = dbf.findByUuid(eip.getUuid(), EipVO.class); Assert.assertEquals(newIp, eipvo.getGuestIp()); }
private String allocateIp(IpRangeVO vo) { int total = vo.size(); Random random = new Random(); long s = random.nextInt(total) + NetworkUtils.ipv4StringToLong(vo.getStartIp()); long e = NetworkUtils.ipv4StringToLong(vo.getEndIp()); String ret = steppingAllocate(s, e, total, vo.getUuid()); if (ret != null) { return ret; } e = s; s = NetworkUtils.ipv4StringToLong(vo.getStartIp()); return steppingAllocate(s, e, total, vo.getUuid()); }
private String steppingAllocate(long s, long e, int total, String rangeUuid) { int step = 254; int failureCount = 0; int failureCheckPoint = 5; while (s < e) { // if failing failureCheckPoint times, the range is probably full, // we check the range. // why don't we check before steppingAllocate()? because in that case we // have to count the used IP every time allocating a IP, and count operation // is a full scan in DB, which is very costly if (failureCheckPoint == failureCount++) { SimpleQuery<UsedIpVO> q = dbf.createQuery(UsedIpVO.class); q.add(UsedIpVO_.ipRangeUuid, Op.EQ, rangeUuid); long count = q.count(); if (count == total) { logger.debug( String.format("ip range[uuid:%s] has no ip available, try next one", rangeUuid)); return null; } else { failureCount = 0; } } long te = s + step; te = te > e ? e : te; SimpleQuery<UsedIpVO> q = dbf.createQuery(UsedIpVO.class); q.select(UsedIpVO_.ipInLong); q.add(UsedIpVO_.ipInLong, Op.GTE, s); q.add(UsedIpVO_.ipInLong, Op.LTE, te); q.add(UsedIpVO_.ipRangeUuid, Op.EQ, rangeUuid); List<Long> used = q.listValue(); if (te - s + 1 == used.size()) { s += step; continue; } Collections.sort(used); return NetworkUtils.randomAllocateIpv4Address(s, te, used); } return null; }