host_exec.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. from flask import Blueprint, request
  2. from apps.assets.models import HostExecTemplate, Host
  3. from libs.tools import json_response, JsonParser, Argument, QueuePool
  4. from libs.ssh import ssh_exec_command_with_stream, get_ssh_client
  5. from public import db
  6. from libs.decorators import require_permission
  7. from threading import Thread
  8. import json
  9. import uuid
  10. blueprint = Blueprint(__name__, __name__)
  11. @blueprint.route('/tpl/', methods=['GET'])
  12. @require_permission('assets_host_exec_view | assets_host_exec | assets_host_exec_tpl_view')
  13. def get():
  14. form, error = JsonParser(Argument('page', type=int, default=1, required=False),
  15. Argument('pagesize', type=int, default=10, required=False),
  16. Argument('tpl_query', type=dict, required=False),).parse(request.args)
  17. if error is None:
  18. tpl_data = HostExecTemplate.query
  19. if form.page == -1:
  20. return json_response({'data': [x.to_json() for x in tpl_data.all()], 'total': -1})
  21. if form.tpl_query['name_field']:
  22. tpl_data = tpl_data.filter(HostExecTemplate.tpl_name.like('%{}%'.format(form.tpl_query['name_field'])))
  23. if form.tpl_query['type_field']:
  24. tpl_data = tpl_data.filter_by(tpl_type=form.tpl_query['type_field'])
  25. result = tpl_data.limit(form.pagesize).offset((form.page - 1) * form.pagesize).all()
  26. return json_response({'data': [x.to_json() for x in result], 'total': tpl_data.count()})
  27. return json_response(message=error)
  28. @blueprint.route('/tpl/', methods=['POST'])
  29. @require_permission('assets_host_exec_tpl_add')
  30. def post():
  31. form, error = JsonParser('tpl_name', 'tpl_type', 'tpl_content',
  32. Argument('tpl_desc', nullable=True, required=False)).parse()
  33. if error is None:
  34. tpl = HostExecTemplate(**form)
  35. tpl.save()
  36. return json_response(tpl)
  37. return json_response(message=error)
  38. @blueprint.route('/tpl/<int:tpl_id>', methods=['DELETE'])
  39. @require_permission('assets_host_exec_tpl_del')
  40. def delete(tpl_id):
  41. HostExecTemplate.query.get_or_404(tpl_id).delete()
  42. return json_response()
  43. @blueprint.route('/tpl/<int:tpl_id>', methods=['PUT'])
  44. @require_permission('assets_host_exec_tpl_edit')
  45. def put(tpl_id):
  46. form, error = JsonParser('tpl_name', 'tpl_type', 'tpl_content',
  47. Argument('tpl_desc', nullable=True, required=False)).parse()
  48. if error is None:
  49. tpl = HostExecTemplate.query.get_or_404(tpl_id)
  50. tpl.update(**form)
  51. return json_response(tpl)
  52. return json_response(message=error)
  53. @blueprint.route('/tpl_type', methods=['GET'])
  54. @require_permission('assets_host_exec_view | assets_host_exec_tpl_view')
  55. def fetch_tpl_type():
  56. types = db.session.query(HostExecTemplate.tpl_type.distinct().label('tpl_type')).all()
  57. return json_response([x.tpl_type for x in types])
  58. @blueprint.route('/exec_command/<string:token>', methods=['DELETE'])
  59. @require_permission('assets_host_exec')
  60. def exec_delete(token):
  61. q = QueuePool.get_queue(token)
  62. if q:
  63. q.destroy()
  64. return json_response()
  65. @blueprint.route('/exec_command', methods=['POST'])
  66. @require_permission('assets_host_exec')
  67. def exec_host_command():
  68. form, error = JsonParser('hosts_id', 'command').parse()
  69. if error is None:
  70. ip_list = Host.query.filter(Host.id.in_(tuple(form.hosts_id))).all()
  71. token = uuid.uuid4().hex
  72. q = QueuePool.make_queue(token, len(ip_list))
  73. for h in ip_list:
  74. Thread(target=hosts_exec, args=(q, h.ssh_ip, h.ssh_port, form.command)).start()
  75. return json_response(token)
  76. return json_response(message=error)
  77. def hosts_exec(q, ip, port, command):
  78. ssh_client = get_ssh_client(ip, port)
  79. q.destroyed.append(ssh_client.close)
  80. output = ssh_exec_command_with_stream(ssh_client, command)
  81. for line in output:
  82. q.put({ip: line})
  83. q.put({ip: '\n** 执行完成 **'})
  84. q.done()