mirror of
				https://github.com/apache/cloudstack.git
				synced 2025-10-26 08:42:29 +01:00 
			
		
		
		
	add a web-based Ip Allocator:
In external-ip mode, management server can get user VM's ip from
direct.attach.network.externalIpAllocator.url.
This simple tool provides such kind of ip allocator service.
How to:
1. setup the dnsmasq:
	add the following in dnsmasq.conf:
		dhcp-range=starting-ip-allocate-to-vm,end-ip,netmask,static
    		dhcp-option=option:router,gateway
2. run cloud-web-ipallocator,
	The default listing port is 8080, if it's used by others, change the port by:
		cloud-web-ipallocator other-port
3. set the following in direct.attach.network.externalIpAllocator.url:
	http://your-host-ip:listening-port/ipallocator
			
			
This commit is contained in:
		
							parent
							
								
									0682d70ce6
								
							
						
					
					
						commit
						4fe1d8f335
					
				
							
								
								
									
										136
									
								
								python/bindir/cloud-web-ipallocator.in
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										136
									
								
								python/bindir/cloud-web-ipallocator.in
									
									
									
									
									
										Executable file
									
								
							| @ -0,0 +1,136 @@ | |||||||
|  | #! /usr/bin/python | ||||||
|  | import web | ||||||
|  | import socket, struct | ||||||
|  | import cloud_utils | ||||||
|  | from cloud_utils import Command | ||||||
|  | urls = ("/ipallocator", "ipallocator") | ||||||
|  | app = web.application(urls, globals()) | ||||||
|  | 
 | ||||||
|  | augtool = Command("augtool") | ||||||
|  | service = Command("service") | ||||||
|  | class dhcp: | ||||||
|  | 	_instance = None | ||||||
|  | 	def __init__(self): | ||||||
|  | 		self.availIP=[] | ||||||
|  | 		self.router=None | ||||||
|  | 		self.netmask=None | ||||||
|  | 		self.initialized=False | ||||||
|  | 
 | ||||||
|  | 		options = augtool.match("/files/etc/dnsmasq.conf/dhcp-option").stdout.strip() | ||||||
|  | 		for option in options.splitlines(): | ||||||
|  | 			if option.find("option:router") != -1: | ||||||
|  | 				self.router = option.split("=")[1].strip().split(",")[1] | ||||||
|  | 				print self.router | ||||||
|  | 
 | ||||||
|  | 		dhcp_range = augtool.get("/files/etc/dnsmasq.conf/dhcp-range").stdout.strip() | ||||||
|  | 		dhcp_start = dhcp_range.split("=")[1].strip().split(",")[0] | ||||||
|  | 		dhcp_end = dhcp_range.split("=")[1].strip().split(",")[1] | ||||||
|  | 		self.netmask = dhcp_range.split("=")[1].strip().split(",")[2] | ||||||
|  | 		print dhcp_start, dhcp_end, self.netmask | ||||||
|  | 
 | ||||||
|  |  		start_ip_num = self.ipToNum(dhcp_start); | ||||||
|  | 		end_ip_num =  self.ipToNum(dhcp_end) | ||||||
|  | 		print start_ip_num, end_ip_num | ||||||
|  | 	 | ||||||
|  | 		for ip in range(start_ip_num, end_ip_num + 1): | ||||||
|  | 			self.availIP.append(ip)	 | ||||||
|  | 		print self.availIP[0], self.availIP[len(self.availIP) - 1]	 | ||||||
|  | 		 | ||||||
|  | 		#load the ip already allocated | ||||||
|  | 		self.reloadAllocatedIP() | ||||||
|  | 
 | ||||||
|  | 	def ipToNum(self, ip): | ||||||
|  | 		return struct.unpack("!I", socket.inet_aton(ip))[0] | ||||||
|  | 
 | ||||||
|  | 	def numToIp(self, num): | ||||||
|  | 		return socket.inet_ntoa(struct.pack('!I', num)) | ||||||
|  | 
 | ||||||
|  | 	def getFreeIP(self): | ||||||
|  | 		if len(self.availIP) > 0: | ||||||
|  | 			ip = self.numToIp(self.availIP[0]) | ||||||
|  | 			self.availIP.remove(self.availIP[0])	 | ||||||
|  | 			return ip | ||||||
|  | 		else: | ||||||
|  | 			return None | ||||||
|  | 
 | ||||||
|  | 	def getNetmask(self): | ||||||
|  | 		return self.netmask | ||||||
|  | 
 | ||||||
|  | 	def getRouter(self): | ||||||
|  | 		return self.router | ||||||
|  | 
 | ||||||
|  | 	def getInstance(): | ||||||
|  | 		if not dhcp._instance: | ||||||
|  | 			dhcp._instance = dhcp() | ||||||
|  | 		return dhcp._instance | ||||||
|  | 	getInstance = staticmethod(getInstance) | ||||||
|  | 
 | ||||||
|  | 	def reloadAllocatedIP(self): | ||||||
|  | 		dhcp_hosts = augtool.match("/files/etc/dnsmasq.conf/dhcp-host").stdout.strip().splitlines() | ||||||
|  | 		 | ||||||
|  | 		for host in dhcp_hosts: | ||||||
|  | 			if host.find("dhcp-host") != -1: | ||||||
|  | 				allocatedIP = self.ipToNum(host.split("=")[1].strip().split(",")[1]) | ||||||
|  | 				if allocatedIP in self.availIP:	 | ||||||
|  | 					self.availIP.remove(allocatedIP) | ||||||
|  | 		 | ||||||
|  | 	def allocateIP(self, mac): | ||||||
|  | 		newIP = self.getFreeIP() | ||||||
|  | 		dhcp_host = augtool.match("/files/etc/dnsmasq.conf/dhcp-host").stdout.strip() | ||||||
|  | 		cnt = len(dhcp_host.splitlines()) + 1 | ||||||
|  | 		script = """set %s %s | ||||||
|  | 			    save"""%("/files/etc/dnsmasq.conf/dhcp-host[" + str(cnt) + "]", str(mac) + "," + newIP) | ||||||
|  | 		augtool < script | ||||||
|  | 		#reset dnsmasq | ||||||
|  | 		service("dnsmasq", "restart", stdout=None, stderr=None) | ||||||
|  | 		return newIP | ||||||
|  | 
 | ||||||
|  | 	def releaseIP(self, ip): | ||||||
|  | 		dhcp_host = augtool.match("/files/etc/dnsmasq.conf/dhcp-host").stdout.strip() | ||||||
|  | 		path = None | ||||||
|  | 		for host in dhcp_host.splitlines(): | ||||||
|  | 			if host.find(ip) != -1: | ||||||
|  | 				path = host.split("=")[0].strip() | ||||||
|  | 				 | ||||||
|  | 		if path == None: | ||||||
|  | 			print "Can't find " + str(ip) + " in conf file" | ||||||
|  | 			return None | ||||||
|  | 
 | ||||||
|  | 		print path | ||||||
|  | 		script = """rm %s | ||||||
|  | 			    save"""%(path) | ||||||
|  | 		augtool < script | ||||||
|  | 		 | ||||||
|  | 		#reset dnsmasq | ||||||
|  | 		service("dnsmasq", "restart", stdout=None, stderr=None) | ||||||
|  | 
 | ||||||
|  | class ipallocator: | ||||||
|  | 	def GET(self): | ||||||
|  | 		try: | ||||||
|  | 			user_data = web.input() | ||||||
|  | 			command = user_data.command | ||||||
|  | 			print "Processing: " + command | ||||||
|  | 
 | ||||||
|  | 			dhcpInit = dhcp.getInstance() | ||||||
|  | 
 | ||||||
|  | 			if command == "getIpAddr": | ||||||
|  | 				mac = user_data.mac | ||||||
|  | 				zone_id = user_data.dc | ||||||
|  | 				pod_id = user_data.pod | ||||||
|  | 				print mac, zone_id, pod_id | ||||||
|  | 				freeIP = dhcpInit.allocateIP(mac) | ||||||
|  | 				if not freeIP: | ||||||
|  | 					return "0,0,0" | ||||||
|  | 				print "Find an available IP: " + freeIP | ||||||
|  | 		 | ||||||
|  | 				return freeIP + "," + dhcpInit.getNetmask() + "," + dhcpInit.getRouter() | ||||||
|  | 			elif command == "releaseIpAddr": | ||||||
|  | 				ip = user_data.ip | ||||||
|  | 				zone_id = user_data.dc | ||||||
|  | 				pod_id = user_data.pod | ||||||
|  | 				dhcpInit.releaseIP(ip) | ||||||
|  | 		except: | ||||||
|  | 			return None | ||||||
|  | 
 | ||||||
|  | if __name__ == "__main__": | ||||||
|  | 	app.run() | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user