123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- from flask import Blueprint, request
- from apps.assets.models import Host, HostExtend
- from apps.deploy.models import AppHostRel
- from libs.tools import json_response, JsonParser, Argument
- from apps.setting import utils, Setting
- from libs import ssh
- from libs.utils import DockerClient, DockerException
- import math
- from public import db
- from libs.decorators import require_permission
- from apps.assets.utils import excel_parse
- blueprint = Blueprint(__name__, __name__)
- @blueprint.route('/', methods=['GET'])
- @require_permission('assets_host_view | publish_app_publish_host_select | '
- 'job_task_add | job_task_edit | assets_host_exec')
- def get():
- form, error = JsonParser(Argument('page', type=int, default=1, required=False),
- Argument('pagesize', type=int, default=10, required=False),
- Argument('host_query', type=dict, required=False), ).parse(request.args)
- if error is None:
- print('host_ng', form)
- host_data = Host.query
- if form.page == -1:
- return json_response({'data': [x.to_json() for x in host_data.all()], 'total': -1})
- if form.host_query.get('name_field'):
- host_data = host_data.filter(Host.name.like('%{}%'.format(form.host_query['name_field'])))
- if form.host_query.get('zone_field'):
- host_data = host_data.filter_by(zone=form.host_query['zone_field'])
- result = host_data.limit(form.pagesize).offset((form.page - 1) * form.pagesize).all()
- return json_response({'data': [x.to_json() for x in result], 'total': host_data.count()})
- return json_response(message=error)
- @blueprint.route('/', methods=['POST'])
- @require_permission('assets_host_add')
- def post():
- form, error = JsonParser('name', 'type', 'zone', 'docker_uri', 'ssh_ip', 'ssh_port',
- Argument('desc', nullable=True, required=False)).parse()
- if error is None:
- host = Host(**form)
- host.save()
- return json_response(host)
- return json_response(message=error)
- @blueprint.route('/<int:host_id>', methods=['DELETE'])
- @require_permission('assets_host_del')
- def delete(host_id):
- host = Host.query.get_or_404(host_id)
- if AppHostRel.query.filter_by(host_id=host_id).first():
- return json_response(message='请先取消与应用的关联后,再尝试删除该主机。')
- host.delete()
- return json_response()
- @blueprint.route('/<int:host_id>', methods=['PUT'])
- @require_permission('assets_host_edit')
- def put(host_id):
- form, error = JsonParser('name', 'type', 'zone', 'docker_uri', 'ssh_ip', 'ssh_port',
- Argument('desc', nullable=True, required=False)).parse()
- if error is None:
- host = Host.query.get_or_404(host_id)
- host.update(**form)
- return json_response(host)
- return json_response(message=error)
- @blueprint.route('/<int:host_id>/valid', methods=['GET'])
- @require_permission('assets_host_valid')
- def get_valid(host_id):
- cli = Host.query.get_or_404(host_id)
- if not Setting.has('ssh_private_key'):
- utils.generate_and_save_ssh_key()
- if ssh.ssh_ping(cli.ssh_ip, cli.ssh_port):
- try:
- sync_host_info(host_id, cli.docker_uri)
- except DockerException:
- return json_response(message='docker fail')
- else:
- return json_response(message='ssh fail')
- return json_response()
- @blueprint.route('/<int:host_id>/valid', methods=['POST'])
- @require_permission('assets_host_valid')
- def post_valid(host_id):
- form, error = JsonParser(Argument('secret', help='请输入root用户的密码!')).parse()
- if error is None:
- cli = Host.query.get_or_404(host_id)
- ssh.add_public_key(cli.ssh_ip, cli.ssh_port, form.secret)
- if ssh.ssh_ping(cli.ssh_ip, cli.ssh_port):
- try:
- sync_host_info(host_id, cli.docker_uri)
- except DockerException:
- return json_response(message='获取扩展信息失败,请检查docker是否可以正常连接!')
- else:
- return json_response(message='验证失败!')
- return json_response(message=error)
- @blueprint.route('/<int:host_id>/extend/', methods=['GET'])
- @require_permission('assets_host_valid')
- def get_extend(host_id):
- host_extend = HostExtend.query.filter_by(host_id=host_id).first()
- return json_response(host_extend)
- @blueprint.route('/zone/', methods=['GET'])
- @require_permission('assets_host_valid | assets_host_exec')
- def fetch_groups():
- zones = db.session.query(Host.zone.distinct().label('zone')).all()
- return json_response([x.zone for x in zones])
- @blueprint.route('/import', methods=['POST'])
- @require_permission('assets_host_add')
- def host_import():
- data = excel_parse()
- if data:
- index_map = {key: index for index, key in enumerate(data.keys())}
- for row in zip(*data.values()):
- print(row)
- Host(
- name=row[index_map['主机名称']],
- desc=row[index_map['备注信息']],
- type=row[index_map['主机类型']],
- zone=row[index_map['所属区域']],
- docker_uri=row[index_map['Docker连接地址']],
- ssh_ip=row[index_map['SSH连接地址']],
- ssh_port=row[index_map['SSH端口']],
- ).add()
- db.session.commit()
- return json_response(data='导入成功')
- def sync_host_info(host_id, uri):
- host_info = DockerClient(base_url=uri).docker_info()
- operate_system = host_info.get('OperatingSystem')
- memory = math.ceil(int(host_info.get('MemTotal'))/1024/1024/1024)
- cpu = host_info.get('NCPU')
- # outer_ip = 1
- # inner_ip = 2
- HostExtend.upsert({'host_id': host_id}, host_id=host_id, operate_system=operate_system, memory=memory, cpu=cpu)
- return True
|