Esempio n. 1
0
    async def disconnect(self, code):
        # 关闭远程 tail
        webuser = self.scope['user'].username
        redis = RedisObj()
        remote_tail_is_stop = redis.get('remote_tail_' + str(webuser))
        if remote_tail_is_stop == '0':
            redis.set('remote_tail_' + str(webuser), '1')

        await self.channel_layer.group_discard(webuser, self.channel_name)
Esempio n. 2
0
 def remote_tail(self, host, port, user, passwd, logfile, webuser, filter_text=None):
     # 创建一个可跨文件的全局变量,控制停止
     try:
         self.client = paramiko.SSHClient()
         self.client.load_system_host_keys()
         self.client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
         self.client.connect(hostname=host, port=port, username=user, password=passwd)
         interact = SSHClientInteraction(self.client, timeout=10, display=False)
         interact.expect('.*#.*')
         logfile = logfile.strip().replace('&&', '').replace('||', '').replace('|', '')
         self.send_message(webuser, '[INFO][%s@%s]开始监控日志' % (user, host))
         redis = RedisObj()
         redis.set('remote_tail_' + str(webuser), self.client)
         if filter_text:
             filter_text_re = filter_text.strip().replace('&&', '').replace('||', '').replace('|', '')
             interact.send('tail -f %s|grep --color=never %s' % (logfile, filter_text_re))
         else:
             interact.send('tail -f %s' % (logfile))
         interact.tail(output_callback=lambda m: self.send_message(webuser, m), stop_callback=lambda x: self.get_is_stop(webuser))
     except Exception as e:
         self.send_message(webuser, e)
     finally:
         redis = RedisObj()
         redis.set('remote_tail_' + str(webuser), '1')
         try:
             self.client.close()
         except Exception as e:
             self.send_message(webuser, e)
Esempio n. 3
0
def local_tailf(logfile, webuser, id):
    info_logger.info('[部署日志监控开始] 文件地址:%s 用户:%s 项目ID:%s' % (logfile, webuser, id))
    redis = RedisObj()
    f = open(logfile, 'rt')
    f.seek(0, 0)
    while True:
        line = f.readline()
        if not line:
            is_stop = redis.get('deploy_' + str(webuser) + '_' + str(id))
            if is_stop == '1':
                Tailf.send_message(webuser, '[INFO]文件监视结束..')
                f.close()
                info_logger.info('[部署日志监控结束] 文件地址:%s 用户:%s 项目ID:%s' % (logfile, webuser, id))
                break
            else:
                time.sleep(0.2)
                continue
        Tailf.send_message(webuser, line)
Esempio n. 4
0
 def run(self, id, log, version, serverid, record_id, webuser, start_time):
     info_logger.info('[部署任务开始] 开始时间:%s 记录ID:%s 部署版本:%s 用户:%s 项目ID:%s' %
                      (start_time, record_id, version, webuser, id))
     redis = RedisObj()
     redis.set('deploy_' + str(webuser) + '_' + str(id), '0')
     self.init(webuser, record_id, id)
     self.start_time = start_time
     with open(log, 'a') as f:
         f.write('[INFO]版本: %s 执行用户: %s 开始时间: %s\n[INFO]本次部署日志路径: %s\n' %
                 (version, webuser, start_time, log))
     try:
         self.do_prev_deploy(log)
         self.do_checkout(version, log)
         self.do_post_deploy(log)
         for sid in serverid:
             try:
                 connect = connect_init(sid)
                 connect.init_env(env=self.custom_global_env)
                 self.do_prev_release(log, connect)
                 self.do_release(log, connect)
                 self.do_post_release(log, connect)
             except Exception as e:
                 time.sleep(5)
                 Tailf.send_message(webuser,
                                    '[ERROR] 服务器为空或ID %s 可能已被删除!' % sid)
                 Tailf.send_message(webuser, '[ERROR] 错误信息:' % e)
                 error_logger.error(
                     '[部署任务错误] 开始时间:%s 记录ID:%s 部署版本:%s 用户:%s 项目ID:%s 信息:%s'
                     % (start_time, record_id, version, webuser, id, e))
         self.end(serverid, record_id)
         info_logger.info('[部署任务已结束] 记录ID:%s 部署版本:%s 用户:%s 项目ID:%s' %
                          (record_id, version, webuser, id))
     except Exception as e:
         Tailf.send_message(webuser, '[ERROR] 错误信息: %s' % e)
         error_logger.error(
             '[部署任务错误] 开始时间:%s 记录ID:%s 部署版本:%s 用户:%s 项目ID:%s 信息:%s' %
             (start_time, record_id, version, webuser, id, e))
     finally:
         if self.localhost:
             self.localhost.close()
         # 关闭local_tailf死循环
         redis.set('deploy_' + str(webuser) + '_' + str(id), '1')
Esempio n. 5
0
 def get_is_stop(self, webuser):
     redis = RedisObj()
     is_stop = redis.get('remote_tail_' + str(webuser))
     return True if is_stop == '1' else False
Esempio n. 6
0
    def post(self, request, format=None):
        if request.data['excu'] == 'init':
            # 项目初始化
            id = request.data['id']
            result = self.repo_init(id)
            if result.exited == 0:
                Project.objects.filter(id=id).update(status='Succeed')
                info_logger.info('初始化项目:' + str(id) + ',执行成功!')
                http_status = OK
                msg = '初始化成功!'
            else:
                error_logger.error('初始化项目:%s 执行失败! 错误信息:%s' %
                                   (str(id), result.stderr))
                http_status = BAD
                msg = '初始化项目:%s 执行失败! 错误信息:%s' % (str(id), result.stderr)

            return XopsResponse(msg, status=http_status)

        elif request.data['excu'] == 'deploy':
            # 部署操作
            id = request.data['id']
            webuser = request.user.username
            alias = request.data['alias']
            self.start_time = time.strftime("%Y%m%d%H%M%S", time.localtime())
            record_id = str(alias) + '_' + str(self.start_time)
            name = '部署_' + record_id
            DeployRecord.objects.create(name=name,
                                        alias=alias,
                                        status='Failed',
                                        project_id=int(id))
            Project.objects.filter(id=id).update(last_task_status='Failed')
            local_log_path = self._path.rstrip('/') + '/' + str(
                id) + '_' + str(request.data['alias']) + '/logs'
            log = local_log_path + '/' + record_id + '.log'
            version = request.data['version'].strip()
            serverid = request.data['server_ids']
            # 调用celery异步任务
            deploy.delay(id, log, version, serverid, record_id, webuser,
                         self.start_time)
            return XopsResponse(record_id)

        elif request.data['excu'] == 'rollback':
            # 回滚
            id = request.data['id']
            project_id = request.data['project_id']
            alias = request.data['alias']
            self.start_time = time.strftime("%Y%m%d%H%M%S", time.localtime())
            record_id = str(alias) + '_' + str(self.start_time)
            log = self._path.rstrip('/') + '/' + str(project_id) + '_' + str(
                alias) + '/logs/' + record_id + '.log'
            self.do_rollback(id, log, record_id)
            return XopsResponse(record_id)

        elif request.data['excu'] == 'deploymsg':
            # 部署控制台消息读取
            try:
                id = request.data['id']
                alias = request.data['alias']
                record = request.data['record']
                scenario = int(request.data['scenario'])
                logfile = self._path.rstrip('/') + '/' + str(id) + '_' + str(
                    alias) + '/logs/' + record + '.log'
                webuser = request.user.username
                if scenario == 0:
                    local_tailf.delay(logfile, webuser, id)
                http_status = OK
                request_status = '执行成功!'
            except Exception as e:
                http_status = BAD
                request_status = str(e)
            return XopsResponse(request_status, status=http_status)

        elif request.data['excu'] == 'readlog' and request.data[
                'scenario'] == 1:
            # 读取部署日志
            try:
                id = request.data['id']
                alias = request.data['alias']
                record = request.data['record']
                logfile = self._path.rstrip('/') + '/' + str(id) + '_' + str(
                    alias) + '/logs/' + record + '.log'
                response = FileResponse(open(logfile, 'rb'))
                response['Content-Type'] = 'text/plain'
                return response
            except Exception:
                http_status = BAD
                request_status = '执行错误:文件不存在!'
            return XopsResponse(request_status, status=http_status)

        elif request.data['excu'] == 'app_start':
            # 项目启动
            try:
                app_start = request.data['app_start']
                host = request.data['host']
                webuser = request.user.username
                auth_info, auth_key = auth_init(host)
                connect = Shell(auth_info,
                                connect_timeout=5,
                                connect_kwargs=auth_key)
                app_start = app_start.strip().replace('&&',
                                                      '').replace('||', '')
                connect.run(app_start, ws=True, webuser=webuser)
                connect.close()
                http_status = OK
                request_status = '执行成功!'
            except Exception as e:
                http_status = BAD
                request_status = '执行错误:' + str(e)
            return XopsResponse(request_status, status=http_status)

        elif request.data['excu'] == 'app_stop':
            # 项目停止
            try:
                app_stop = request.data['app_stop']
                host = request.data['host']
                webuser = request.user.username
                auth_info, auth_key = auth_init(host)
                connect = Shell(auth_info,
                                connect_timeout=5,
                                connect_kwargs=auth_key)
                app_stop = app_stop.strip().replace('&&', '').replace('||', '')
                connect.run(app_stop, ws=True, webuser=webuser)
                connect.close()
                http_status = OK
                request_status = '执行成功!'
            except Exception as e:
                http_status = BAD
                request_status = '执行错误:' + str(e)
            return XopsResponse(request_status, status=http_status)

        elif request.data['excu'] == 'tail_start':
            # 日志监控
            try:
                filter_text = str(request.data['filter'])
                app_log_file = request.data['app_log_file']
                host = request.data['host']
                webuser = request.user.username
                device_info = DeviceInfo.objects.filter(id=int(host)).values()
                host = device_info[0]['hostname']
                auth_type = device_info[0]['auth_type']
                connect_info = ConnectionInfo.objects.filter(
                    hostname=host, auth_type=auth_type).values()
                user = connect_info[0]['username']
                passwd = connect_info[0]['password']
                port = connect_info[0]['port']
                tail = Tailf()
                tail.remote_tail(host,
                                 port,
                                 user,
                                 passwd,
                                 app_log_file,
                                 webuser,
                                 filter_text=filter_text)
                http_status = OK
                request_status = '执行成功!'
            except Exception as e:
                http_status = BAD
                request_status = str(e)
            return XopsResponse(request_status, status=http_status)

        elif request.data['excu'] == 'tail_stop':
            # 日志监控停止
            try:
                webuser = request.user.username
                redis = RedisObj()
                redis.set('remote_tail_' + str(webuser), '1')
                http_status = OK
                request_status = '执行成功!'
            except Exception as e:
                http_status = BAD
                request_status = str(e)
            return XopsResponse(request_status, status=http_status)
Esempio n. 7
0
    def post(self, request, format=None):
        if request.data['excu'] == 'init':
            # 项目初始化
            id = request.data['id']
            result = self.repo_init(id)
            if result.exited == 0:
                Project.objects.filter(id=id).update(status='Succeed')
                info_logger.info('初始化项目:' + str(id) + ',执行成功!')
                http_status = OK
                msg = '初始化成功!'
            else:
                error_logger.error('初始化项目:%s 执行失败! 错误信息:%s' %
                                   (str(id), result.stderr))
                http_status = BAD
                msg = '初始化项目:%s 执行失败! 错误信息:%s' % (str(id), result.stderr)

            return XopsResponse(msg, status=http_status)

        elif request.data['excu'] == 'deploy':
            # 部署操作
            # request-data-injection.path-traversal.003.source
            id = request.data['id']
            webuser = request.user.username
            alias = request.data['alias']
            self.start_time = time.strftime("%Y%m%d%H%M%S", time.localtime())
            record_id = str(alias) + '_' + str(self.start_time)
            name = '部署_' + record_id
            DeployRecord.objects.create(name=name,
                                        alias=alias,
                                        status='Failed',
                                        project_id=int(id))
            Project.objects.filter(id=id).update(last_task_status='Failed')
            # request-data-injection.path-traversal.003.sink
            local_log_path = self._path.rstrip('/') + '/' + str(
                id) + '_' + str(request.data['alias']) + '/logs'
            log = local_log_path + '/' + record_id + '.log'
            version = request.data['version'].strip()
            serverid = request.data['server_ids']
            # 调用celery异步任务
            deploy.delay(id, log, version, serverid, record_id, webuser,
                         self.start_time)
            #deploy.run(id, log, version, serverid, record_id, webuser, self.start_time)
            return XopsResponse(record_id)

        elif request.data['excu'] == 'rollback':
            # 回滚
            id = request.data['id']
            project_id = request.data['project_id']
            alias = request.data['alias']
            self.start_time = time.strftime("%Y%m%d%H%M%S", time.localtime())
            record_id = str(alias) + '_' + str(self.start_time)
            log = self._path.rstrip('/') + '/' + str(project_id) + '_' + str(
                alias) + '/logs/' + record_id + '.log'
            self.do_rollback(id, log, record_id)
            return XopsResponse(record_id)

        elif request.data['excu'] == 'deploymsg':
            # 部署控制台消息读取
            try:
                # request-data-injection.path-traversal.004.source
                id = request.data['id']
                # request-data-injection.path-traversal.005.source
                alias = request.data['alias']
                # request-data-injection.path-traversal.006.source
                record = request.data['record']
                scenario = int(request.data['scenario'])
                # request-data-injection.path-traversal.004.sink
                # request-data-injection.path-traversal.005.sink
                # request-data-injection.path-traversal.006.sink
                logfile = self._path.rstrip('/') + '/' + str(id) + '_' + str(
                    alias) + '/logs/' + record + '.log'
                webuser = request.user.username
                if scenario == 0:
                    local_tailf.delay(logfile, webuser, id)
                http_status = OK
                request_status = '执行成功!'
            except Exception as e:
                http_status = BAD
                request_status = str(e)
            return XopsResponse(request_status, status=http_status)

        elif request.data['excu'] == 'readlog' and request.data[
                'scenario'] == 1:
            # 读取部署日志
            try:
                # request-data-injection.path-traversal.007.source
                id = request.data['id']
                # request-data-injection.path-traversal.008.source
                alias = request.data['alias']
                # request-data-injection.path-traversal.009.source
                record = request.data['record']
                # request-data-injection.path-traversal.007.source
                # request-data-injection.path-traversal.008.source
                # request-data-injection.path-traversal.009.source
                logfile = self._path.rstrip('/') + '/' + str(id) + '_' + str(
                    alias) + '/logs/' + record + '.log'
                response = FileResponse(open(logfile, 'rb'))
                response['Content-Type'] = 'text/plain'
                return response
            except Exception:
                http_status = BAD
                request_status = '执行错误:文件不存在!'
            return XopsResponse(request_status, status=http_status)

        elif request.data['excu'] == 'app_start':
            # 项目启动
            try:
                # request-data-injection.advanced-command-injection.001.source
                app_start = request.data['app_start']
                host = request.data['host']
                webuser = request.user.username
                connect = connect_init(host)
                app_start = app_start.strip()
                # Notes: This is a sink because it will eventually try to execute
                # 'app_start' as a command on a remote server. We can't detect this yet,
                # but I'm annotating here for future use.
                # request-data-injection.advanced-command-injection.001.sink
                connect.run(app_start, webuser=webuser)
                connect.close()
                http_status = OK
                request_status = '执行成功!'
            except Exception as e:
                http_status = BAD
                request_status = '执行错误:' + str(e)
            return XopsResponse(request_status, status=http_status)

        elif request.data['excu'] == 'app_stop':
            # 项目停止
            try:
                # request-data-injection.advanced-command-injection.002.source
                app_stop = request.data['app_stop']
                host = request.data['host']
                webuser = request.user.username
                connect = connect_init(host)
                app_stop = app_stop.strip()
                # request-data-injection.advanced-command-injection.002.sink
                connect.run(app_stop, webuser=webuser)
                connect.close()
                http_status = OK
                request_status = '执行成功!'
            except Exception as e:
                http_status = BAD
                request_status = '执行错误:' + str(e)
            return XopsResponse(request_status, status=http_status)

        elif request.data['excu'] == 'tail_start':
            # 日志监控
            try:
                filter_text = str(request.data['filter'])
                app_log_file = request.data['app_log_file']
                host = request.data['host']
                webuser = request.user.username
                device_info = DeviceInfo.objects.filter(id=int(host)).values()
                host = device_info[0]['hostname']
                auth_type = device_info[0]['auth_type']
                connect_info = ConnectionInfo.objects.filter(
                    hostname=host, auth_type=auth_type).values()
                user = connect_info[0]['username']
                passwd = connect_info[0]['password']
                port = connect_info[0]['port']
                tail = Tailf()
                tail.remote_tail(host,
                                 port,
                                 user,
                                 passwd,
                                 app_log_file,
                                 webuser,
                                 filter_text=filter_text)
                http_status = OK
                request_status = '执行成功!'
            except Exception as e:
                http_status = BAD
                request_status = str(e)
            return XopsResponse(request_status, status=http_status)

        elif request.data['excu'] == 'tail_stop':
            # 日志监控停止
            try:
                webuser = request.user.username
                redis = RedisObj()
                redis.set('remote_tail_' + str(webuser), '1')
                http_status = OK
                request_status = '执行成功!'
            except Exception as e:
                http_status = BAD
                request_status = str(e)
            return XopsResponse(request_status, status=http_status)