os_template_image.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. from math import ceil
  4. import requests
  5. from flask import Blueprint, url_for
  6. from flask import request
  7. import jimit as ji
  8. import json
  9. from api.base import Base
  10. from models import OSTemplateImage, OSTemplateProfile, Host, Config, OSTemplateImageKind, Guest
  11. from models import Rules
  12. from models import Utils
  13. __author__ = 'James Iter'
  14. __date__ = '2018/2/4'
  15. __contact__ = 'james.iter.cn@gmail.com'
  16. __copyright__ = '(c) 2018 by James Iter.'
  17. blueprint = Blueprint(
  18. 'api_os_template_image',
  19. __name__,
  20. url_prefix='/api/os_template_image'
  21. )
  22. blueprints = Blueprint(
  23. 'api_os_templates_image',
  24. __name__,
  25. url_prefix='/api/os_templates_image'
  26. )
  27. os_template_image_base = Base(the_class=OSTemplateImage, the_blueprint=blueprint, the_blueprints=blueprints)
  28. @Utils.dumps2response
  29. def r_create():
  30. os_template_image = OSTemplateImage()
  31. args_rules = [
  32. Rules.LABEL.value,
  33. Rules.DESCRIPTION.value,
  34. Rules.PATH.value,
  35. Rules.LOGO.value,
  36. Rules.OS_TEMPLATE_PROFILE_ID_EXT.value,
  37. Rules.ACTIVE.value,
  38. Rules.OS_TEMPLATE_IMAGE_KIND.value
  39. ]
  40. os_template_image.label = request.json.get('label')
  41. os_template_image.description = request.json.get('description')
  42. os_template_image.path = request.json.get('path')
  43. os_template_image.logo = request.json.get('logo')
  44. os_template_image.active = bool(int(request.json.get('active', 1)))
  45. os_template_image.os_template_profile_id = request.json.get('os_template_profile_id')
  46. os_template_image.kind = request.json.get('kind')
  47. os_template_image.progress = 100
  48. try:
  49. ji.Check.previewing(args_rules, os_template_image.__dict__)
  50. ret = dict()
  51. ret['state'] = ji.Common.exchange_state(20000)
  52. if os_template_image.exist_by('path'):
  53. ret['state'] = ji.Common.exchange_state(40901)
  54. ret['state']['sub']['zh-cn'] = ''.join([ret['state']['sub']['zh-cn'], ': ', os_template_image.path])
  55. return ret
  56. os_template_profile = OSTemplateProfile()
  57. os_template_profile.id = os_template_image.os_template_profile_id
  58. if not os_template_profile.exist():
  59. ret['state'] = ji.Common.exchange_state(40401)
  60. ret['state']['sub']['zh-cn'] = ''.join([ret['state']['sub']['zh-cn'], u': 操作系统模板描述文件ID: ',
  61. os_template_image.os_template_profile_id.__str__()])
  62. return ret
  63. os_template_image.create()
  64. os_template_image.get_by('path')
  65. ret['data'] = os_template_image.__dict__
  66. return ret
  67. except ji.PreviewingError, e:
  68. return json.loads(e.message)
  69. @Utils.dumps2response
  70. def r_update(_id):
  71. os_template_image = OSTemplateImage()
  72. args_rules = [
  73. Rules.ID.value
  74. ]
  75. if 'label' in request.json:
  76. args_rules.append(
  77. Rules.LABEL.value,
  78. )
  79. if 'description' in request.json:
  80. args_rules.append(
  81. Rules.DESCRIPTION.value,
  82. )
  83. if 'path' in request.json:
  84. args_rules.append(
  85. Rules.PATH.value,
  86. )
  87. if 'active' in request.json:
  88. args_rules.append(
  89. Rules.ACTIVE.value,
  90. )
  91. if 'logo' in request.json:
  92. args_rules.append(
  93. Rules.LOGO.value,
  94. )
  95. if 'os_template_profile_id' in request.json:
  96. args_rules.append(
  97. Rules.OS_TEMPLATE_PROFILE_ID_EXT.value,
  98. )
  99. if 'kind' in request.json:
  100. args_rules.append(
  101. Rules.OS_TEMPLATE_IMAGE_KIND.value,
  102. )
  103. if args_rules.__len__() < 2:
  104. ret = dict()
  105. ret['state'] = ji.Common.exchange_state(20000)
  106. return ret
  107. request.json['id'] = _id
  108. try:
  109. ji.Check.previewing(args_rules, request.json)
  110. os_template_image.id = request.json.get('id')
  111. os_template_image.get()
  112. os_template_image.label = request.json.get('label', os_template_image.label)
  113. os_template_image.description = request.json.get('description', os_template_image.description)
  114. os_template_image.path = request.json.get('path', os_template_image.path)
  115. os_template_image.active = request.json.get('active', os_template_image.active)
  116. os_template_image.logo = request.json.get('logo', os_template_image.logo)
  117. os_template_image.os_template_profile_id = \
  118. request.json.get('os_template_profile_id', os_template_image.os_template_profile_id)
  119. os_template_image.kind = request.json.get('kind', os_template_image.kind)
  120. os_template_image.update()
  121. os_template_image.get()
  122. ret = dict()
  123. ret['state'] = ji.Common.exchange_state(20000)
  124. ret['data'] = os_template_image.__dict__
  125. return ret
  126. except ji.PreviewingError, e:
  127. return json.loads(e.message)
  128. @Utils.dumps2response
  129. def r_delete(ids):
  130. ret = dict()
  131. ret['state'] = ji.Common.exchange_state(20000)
  132. config = Config()
  133. config.id = 1
  134. config.get()
  135. # 取全部活着的 hosts
  136. available_hosts = Host.get_available_hosts(nonrandom=None)
  137. if available_hosts.__len__() == 0:
  138. ret['state'] = ji.Common.exchange_state(50351)
  139. return ret
  140. chosen_host = available_hosts[0]
  141. node_id = chosen_host['node_id']
  142. os_template_image = OSTemplateImage()
  143. # TODO: 加入对,是否有被 Guest 引用的判断
  144. for _id in ids.split(','):
  145. os_template_image.id = _id
  146. os_template_image.get()
  147. for _id in ids.split(','):
  148. os_template_image.id = _id
  149. os_template_image.get()
  150. # 暂时不支持从计算节点上,删除公共镜像
  151. if os_template_image.kind == OSTemplateImageKind.public.value:
  152. os_template_image.delete()
  153. continue
  154. elif os_template_image.kind == OSTemplateImageKind.custom.value:
  155. os_template_image.progress = 254
  156. message = {
  157. '_object': 'os_template_image',
  158. 'action': 'delete',
  159. 'storage_mode': config.storage_mode,
  160. 'dfs_volume': config.dfs_volume,
  161. 'template_path': os_template_image.path,
  162. # uuid 这里没有实际意义,仅仅是为了迁就 JimV-C 的个命令格式
  163. 'uuid': None,
  164. 'node_id': node_id,
  165. 'os_template_image_id': os_template_image.id,
  166. 'passback_parameters': {'id': os_template_image.id}
  167. }
  168. Utils.emit_instruction(message=json.dumps(message))
  169. os_template_image.update()
  170. return ret
  171. @Utils.dumps2response
  172. def r_get(ids):
  173. return os_template_image_base.get(ids=ids, ids_rule=Rules.IDS.value, by_field='id')
  174. @Utils.dumps2response
  175. def r_get_by_filter():
  176. ret = os_template_image_base.get_by_filter()
  177. if '200' != ret['state']['code']:
  178. return ret
  179. os_template_images_id = list()
  180. for os_template_image in ret['data']:
  181. os_template_image_id = os_template_image['id']
  182. if os_template_image_id not in os_template_images_id:
  183. os_template_images_id.append(os_template_image_id)
  184. rows, _ = Guest.get_by_filter(filter_str=':'.join(['os_template_image_id', 'in',
  185. ','.join(_id.__str__() for _id in os_template_images_id)]))
  186. os_template_image_guest_mapping = dict()
  187. for guest in rows:
  188. os_template_image_id = guest['os_template_image_id']
  189. if os_template_image_id not in os_template_image_guest_mapping:
  190. os_template_image_guest_mapping[os_template_image_id] = list()
  191. os_template_image_guest_mapping[os_template_image_id].append(guest)
  192. for i, os_template_image in enumerate(ret['data']):
  193. if os_template_image['id'] in os_template_image_guest_mapping:
  194. ret['data'][i]['guests'] = os_template_image_guest_mapping[os_template_image['id']]
  195. return ret
  196. @Utils.dumps2response
  197. def r_content_search():
  198. ret = os_template_image_base.content_search()
  199. if '200' != ret['state']['code']:
  200. return ret
  201. os_template_images_id = list()
  202. for os_template_image in ret['data']:
  203. os_template_image_id = os_template_image['id']
  204. if os_template_image_id not in os_template_images_id:
  205. os_template_images_id.append(os_template_image_id)
  206. rows, _ = Guest.get_by_filter(filter_str=':'.join(['os_template_image_id', 'in',
  207. ','.join(_id.__str__() for _id in os_template_images_id)]))
  208. os_template_image_guest_mapping = dict()
  209. for guest in rows:
  210. os_template_image_id = guest['os_template_image_id']
  211. if os_template_image_id not in os_template_image_guest_mapping:
  212. os_template_image_guest_mapping[os_template_image_id] = list()
  213. os_template_image_guest_mapping[os_template_image_id].append(guest)
  214. for i, os_template_image in enumerate(ret['data']):
  215. if os_template_image['id'] in os_template_image_guest_mapping:
  216. ret['data'][i]['guests'] = os_template_image_guest_mapping[os_template_image['id']]
  217. return ret
  218. @Utils.dumps2response
  219. def r_show():
  220. args = list()
  221. page = int(request.args.get('page', 1))
  222. page_size = int(request.args.get('page_size', 1000))
  223. keyword = request.args.get('keyword', None)
  224. order_by = request.args.get('order_by', None)
  225. order = request.args.get('order', None)
  226. if page is not None:
  227. args.append('page=' + page.__str__())
  228. if page_size is not None:
  229. args.append('page_size=' + page_size.__str__())
  230. if keyword is not None:
  231. args.append('keyword=' + keyword.__str__())
  232. if order_by is not None:
  233. args.append('order_by=' + order_by)
  234. if order is not None:
  235. args.append('order=' + order)
  236. os_templates_image_url = url_for('api_os_templates_image.r_get_by_filter', _external=True)
  237. if keyword is not None:
  238. os_templates_image_url = url_for('api_os_templates_image.r_content_search', _external=True)
  239. if args.__len__() > 0:
  240. os_templates_image_url = os_templates_image_url + '?' + '&'.join(args)
  241. os_templates_image_ret = requests.get(url=os_templates_image_url, cookies=request.cookies)
  242. os_templates_image_ret = json.loads(os_templates_image_ret.content)
  243. public_count = 0
  244. custom_count = 0
  245. for os_template_image in os_templates_image_ret['data']:
  246. if os_template_image['kind'] == 0:
  247. public_count += 1
  248. elif os_template_image['kind'] == 1:
  249. custom_count += 1
  250. os_templates_profile, _ = OSTemplateProfile.get_by_filter()
  251. os_templates_profile_mapping_by_id = dict()
  252. for os_template_profile in os_templates_profile:
  253. os_templates_profile_mapping_by_id[os_template_profile['id']] = os_template_profile
  254. last_page = int(ceil(os_templates_image_ret['paging']['total'] / float(page_size)))
  255. page_length = 5
  256. pages = list()
  257. if page < int(ceil(page_length / 2.0)):
  258. for i in range(1, page_length + 1):
  259. pages.append(i)
  260. if i == last_page or last_page == 0:
  261. break
  262. elif last_page - page < page_length / 2:
  263. for i in range(last_page - page_length + 1, last_page + 1):
  264. if i < 1:
  265. continue
  266. pages.append(i)
  267. else:
  268. for i in range(page - page_length / 2, page + int(ceil(page_length / 2.0))):
  269. pages.append(i)
  270. if i == last_page or last_page == 0:
  271. break
  272. ret = dict()
  273. ret['state'] = ji.Common.exchange_state(20000)
  274. ret['data'] = {
  275. 'os_templates_image': os_templates_image_ret['data'],
  276. 'os_templates_profile_mapping_by_id': os_templates_profile_mapping_by_id,
  277. 'page': page,
  278. 'page_size': page_size,
  279. 'keyword': keyword,
  280. 'pages': pages,
  281. 'last_page': last_page,
  282. 'order_by': order_by,
  283. 'order': order,
  284. 'public_count': public_count,
  285. 'custom_count': custom_count
  286. }
  287. return ret