Exemplo n.º 1
0
    def post(self, request):
        form, error = JsonParser(
            Argument('id', type=int, required=False),
            Argument('group_ids', type=list, filter=lambda x: len(x), help='请选择主机分组'),
            Argument('name', help='请输主机名称'),
            Argument('username', handler=str.strip, help='请输入登录用户名'),
            Argument('hostname', handler=str.strip, help='请输入主机名或IP'),
            Argument('port', type=int, help='请输入SSH端口'),
            Argument('pkey', required=False),
            Argument('desc', required=False),
            Argument('password', required=False),
        ).parse(request.body)
        if error is None:
            password = form.pop('password')
            private_key, public_key = AppSetting.get_ssh_key()
            try:
                if form.pkey:
                    private_key = form.pkey
                elif password:
                    with SSH(form.hostname, form.port, form.username, password=password) as ssh:
                        ssh.add_public_key(public_key)

                with SSH(form.hostname, form.port, form.username, private_key) as ssh:
                    ssh.ping()
            except BadAuthenticationType:
                return json_response(error='该主机不支持密钥认证,请参考官方文档,错误代码:E01')
            except AuthenticationException:
                if password:
                    return json_response(error='密钥认证失败,请参考官方文档,错误代码:E02')
                return json_response('auth fail')

            group_ids = form.pop('group_ids')
            other = Host.objects.filter(name=form.name).first()
            if other and (not form.id or other.id != form.id):
                return json_response(error=f'已存在的主机名称【{form.name}】')
            if form.id:
                Host.objects.filter(pk=form.id).update(is_verified=True, **form)
                host = Host.objects.get(pk=form.id)
            else:
                host = Host.objects.create(created_by=request.user, is_verified=True, **form)
                _sync_host_extend(host, ssh=ssh)
            host.groups.set(group_ids)
            response = host.to_view()
            response['group_ids'] = group_ids
            return json_response(response)
        return json_response(error=error)
Exemplo n.º 2
0
def batch_sync_host(token, hosts, password):
    private_key, public_key = AppSetting.get_ssh_key()
    threads, latest_exception, rds = [], None, get_redis_connection()
    max_workers = max(10, os.cpu_count() * 5)
    with futures.ThreadPoolExecutor(max_workers=max_workers) as executor:
        for host in hosts:
            t = executor.submit(_sync_host_extend, host, private_key, public_key, password)
            t.host = host
            threads.append(t)
        for t in futures.as_completed(threads):
            exception = t.exception()
            if exception:
                rds.rpush(token, json.dumps({'key': t.host.id, 'status': 'fail', 'message': f'{exception}'}))
            else:
                rds.rpush(token, json.dumps({'key': t.host.id, 'status': 'ok'}))
                t.host.is_verified = True
                t.host.save()
        rds.expire(token, 60)