guest.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. import json
  4. import random
  5. from flask import Blueprint, render_template, url_for, request
  6. import requests
  7. from math import ceil
  8. import re
  9. import socket
  10. import time
  11. from models import Database as db
  12. from models.initialize import config
  13. __author__ = 'James Iter'
  14. __date__ = '2017/5/30'
  15. __contact__ = 'james.iter.cn@gmail.com'
  16. __copyright__ = '(c) 2017 by James Iter.'
  17. blueprint = Blueprint(
  18. 'v_guest',
  19. __name__,
  20. url_prefix='/guest'
  21. )
  22. blueprints = Blueprint(
  23. 'v_guests',
  24. __name__,
  25. url_prefix='/guests'
  26. )
  27. def show():
  28. args = list()
  29. page = int(request.args.get('page', 1))
  30. page_size = int(request.args.get('page_size', 10))
  31. keyword = request.args.get('keyword', None)
  32. resource_path = request.path
  33. if page is not None:
  34. args.append('page=' + page.__str__())
  35. if page_size is not None:
  36. args.append('page_size=' + page_size.__str__())
  37. if keyword is not None:
  38. args.append('keyword=' + keyword.__str__())
  39. host_url = request.host_url.rstrip('/')
  40. hosts_url = host_url + url_for('api_hosts.r_get_by_filter')
  41. guests_url = host_url + url_for('api_guests.r_get_by_filter')
  42. if keyword is not None:
  43. guests_url = host_url + url_for('api_guests.r_content_search')
  44. os_templates_image_url = host_url + url_for('api_os_templates_image.r_get_by_filter')
  45. os_templates_profile_url = host_url + url_for('api_os_templates_profile.r_get_by_filter')
  46. if args.__len__() > 0:
  47. guests_url = guests_url + '?' + '&'.join(args)
  48. hosts_ret = requests.get(url=hosts_url, cookies=request.cookies)
  49. hosts_ret = json.loads(hosts_ret.content)
  50. hosts_mapping_by_node_id = dict()
  51. for host in hosts_ret['data']:
  52. hosts_mapping_by_node_id[int(host['node_id'])] = host
  53. guests_ret = requests.get(url=guests_url, cookies=request.cookies)
  54. guests_ret = json.loads(guests_ret.content)
  55. os_templates_image_ret = requests.get(url=os_templates_image_url, cookies=request.cookies)
  56. os_templates_image_ret = json.loads(os_templates_image_ret.content)
  57. os_templates_image_mapping_by_id = dict()
  58. for os_template_image in os_templates_image_ret['data']:
  59. os_templates_image_mapping_by_id[os_template_image['id']] = os_template_image
  60. os_templates_profile_ret = requests.get(url=os_templates_profile_url, cookies=request.cookies)
  61. os_templates_profile_ret = json.loads(os_templates_profile_ret.content)
  62. os_templates_profile_mapping_by_id = dict()
  63. for os_template_profile in os_templates_profile_ret['data']:
  64. os_templates_profile_mapping_by_id[os_template_profile['id']] = os_template_profile
  65. guests_uuid = list()
  66. for guest in guests_ret['data']:
  67. guests_uuid.append(guest['uuid'])
  68. last_page = int(ceil(guests_ret['paging']['total'] / float(page_size)))
  69. page_length = 5
  70. pages = list()
  71. if page < int(ceil(page_length / 2.0)):
  72. for i in range(1, page_length + 1):
  73. pages.append(i)
  74. if i == last_page or last_page == 0:
  75. break
  76. elif last_page - page < page_length / 2:
  77. for i in range(last_page - page_length + 1, last_page + 1):
  78. if i < 1:
  79. continue
  80. pages.append(i)
  81. else:
  82. for i in range(page - page_length / 2, page + int(ceil(page_length / 2.0))):
  83. pages.append(i)
  84. if i == last_page or last_page == 0:
  85. break
  86. return render_template('guests_show.html', guests_ret=guests_ret, resource_path=resource_path,
  87. os_templates_image_mapping_by_id=os_templates_image_mapping_by_id,
  88. os_templates_profile_mapping_by_id=os_templates_profile_mapping_by_id,
  89. hosts_mapping_by_node_id=hosts_mapping_by_node_id, page=page,
  90. page_size=page_size, keyword=keyword, pages=pages, last_page=last_page)
  91. def create():
  92. host_url = request.host_url.rstrip('/')
  93. if request.method == 'POST':
  94. ability = request.form.get('ability')
  95. os_template_image_id = request.form.get('os_template_image_id')
  96. quantity = request.form.get('quantity')
  97. password = request.form.get('password')
  98. remark = request.form.get('remark')
  99. allocation_by_random = 'allocation_by_random' in request.form
  100. node_id = request.form.get('node_id')
  101. ssh_keys_id = request.form.getlist('ssh_keys_id')
  102. if not isinstance(ability, basestring):
  103. pass
  104. m = re.search('^(\d+)c(\d+)g$', ability.lower())
  105. if m is None:
  106. pass
  107. cpu = m.groups()[0]
  108. memory = m.groups()[1]
  109. payload = {
  110. "cpu": int(cpu),
  111. "memory": int(memory),
  112. "os_template_image_id": int(os_template_image_id),
  113. "quantity": int(quantity),
  114. "remark": remark,
  115. "password": password,
  116. "ssh_keys_id": ssh_keys_id,
  117. "lease_term": 100
  118. }
  119. if not allocation_by_random:
  120. payload['node_id'] = node_id
  121. url = host_url + '/api/guest'
  122. headers = {'content-type': 'application/json'}
  123. r = requests.post(url, data=json.dumps(payload), headers=headers, cookies=request.cookies)
  124. j_r = json.loads(r.content)
  125. if j_r['state']['code'] != '200':
  126. return render_template('failure.html',
  127. go_back_url='/guests',
  128. timeout=10000, title='创建失败',
  129. message_title='创建实例失败',
  130. message=j_r['state']['sub']['zh-cn'])
  131. guests_url = host_url + url_for('api_guests.r_get_by_filter')
  132. guests_ret = requests.get(url=guests_url, cookies=request.cookies)
  133. guests_ret = json.loads(guests_ret.content)
  134. page_size = 10
  135. last_page = int(ceil(guests_ret['paging']['total'] / float(page_size)))
  136. return render_template('success.html',
  137. go_back_url='/guests?page={0}&page_size={1}'.format(last_page, page_size),
  138. timeout=10000, title='提交成功',
  139. message_title='创建实例的请求已被接受',
  140. message='您所提交的资源正在创建中。根据所提交资源的大小,需要等待几到十几分钟。页面将在10秒钟后自动跳转到实例列表页面!')
  141. else:
  142. hosts_url = host_url + url_for('api_hosts.r_get_by_filter', alive=True)
  143. hosts_ret = requests.get(url=hosts_url, cookies=request.cookies)
  144. hosts_ret = json.loads(hosts_ret.content)
  145. return render_template('guest_create.html', hosts_ret=hosts_ret)
  146. def port_is_opened(port):
  147. s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  148. result = s.connect_ex(('0.0.0.0', port))
  149. if result == 0:
  150. return True
  151. else:
  152. return False
  153. def vnc(uuid):
  154. host_url = request.host_url.rstrip('/')
  155. hosts_url = host_url + url_for('api_hosts.r_get_by_filter')
  156. guest_url = host_url + url_for('api_guests.r_get', uuids=uuid)
  157. guest_ret = requests.get(url=guest_url, cookies=request.cookies)
  158. guest_ret = json.loads(guest_ret.content)
  159. hosts_ret = requests.get(url=hosts_url, cookies=request.cookies)
  160. hosts_ret = json.loads(hosts_ret.content)
  161. hosts_mapping_by_node_id = dict()
  162. for host in hosts_ret['data']:
  163. hosts_mapping_by_node_id[int(host['node_id'])] = host
  164. port = random.randrange(50000, 60000)
  165. while True:
  166. if not port_is_opened(port=port):
  167. break
  168. port = random.randrange(50000, 60000)
  169. payload = {'listen_port': port, 'target_host': hosts_mapping_by_node_id[guest_ret['data']['node_id']]['hostname'],
  170. 'target_port': guest_ret['data']['vnc_port']}
  171. db.r.rpush(config['ipc_queue'], json.dumps(payload, ensure_ascii=False))
  172. time.sleep(1)
  173. return render_template('vnc_lite.html', port=port, password=guest_ret['data']['vnc_password'])
  174. def detail(uuid):
  175. host_url = request.host_url.rstrip('/')
  176. hosts_url = host_url + url_for('api_hosts.r_get_by_filter')
  177. guest_url = host_url + url_for('api_guests.r_get', uuids=uuid)
  178. hosts_ret = requests.get(url=hosts_url, cookies=request.cookies)
  179. hosts_ret = json.loads(hosts_ret.content)
  180. hosts_mapping_by_node_id = dict()
  181. for host in hosts_ret['data']:
  182. hosts_mapping_by_node_id[int(host['node_id'])] = host
  183. guest_ret = requests.get(url=guest_url, cookies=request.cookies)
  184. guest_ret = json.loads(guest_ret.content)
  185. os_template_image_url = host_url + url_for('api_os_templates_image.r_get',
  186. ids=guest_ret['data']['os_template_image_id'].__str__())
  187. os_templates_profile_url = host_url + url_for('api_os_templates_profile.r_get_by_filter')
  188. os_template_image_ret = requests.get(url=os_template_image_url, cookies=request.cookies)
  189. os_template_image_ret = json.loads(os_template_image_ret.content)
  190. os_templates_profile_ret = requests.get(url=os_templates_profile_url, cookies=request.cookies)
  191. os_templates_profile_ret = json.loads(os_templates_profile_ret.content)
  192. os_templates_profile_mapping_by_id = dict()
  193. for os_template_profile in os_templates_profile_ret['data']:
  194. os_templates_profile_mapping_by_id[os_template_profile['id']] = os_template_profile
  195. disks_url = host_url + url_for('api_disks.r_get_by_filter', filter='guest_uuid:in:' + guest_ret['data']['uuid'])
  196. disks_ret = requests.get(url=disks_url, cookies=request.cookies)
  197. disks_ret = json.loads(disks_ret.content)
  198. url = host_url + '/api/config'
  199. config_ret = requests.get(url=url, cookies=request.cookies)
  200. config_ret = json.loads(config_ret.content)
  201. return render_template('guest_detail.html', uuid=uuid, guest_ret=guest_ret,
  202. os_template_image_ret=os_template_image_ret,
  203. os_templates_profile_mapping_by_id=os_templates_profile_mapping_by_id,
  204. hosts_mapping_by_node_id=hosts_mapping_by_node_id,
  205. disks_ret=disks_ret, config_ret=config_ret)
  206. def success():
  207. return render_template('success.html', go_back_url='/guests', timeout=10000, title='提交成功',
  208. message_title='创建实例的请求已被接受',
  209. message='您所提交的资源正在创建中。根据所提交资源的大小,需要等待几到十几分钟。页面将在10秒钟后自动跳转到实例列表页面!')