Exemple #1
0
def deploy_detail(request, id, format=None):
    """
    Retrieve, update or delete a server assets instance.
    """
    try:
        snippet = Project_Config.objects.get(id=id)
    except Project_Config.DoesNotExist:
        return Response(status=status.HTTP_404_NOT_FOUND)

    if request.method == 'GET':
        serializer = ProjectConfigSerializer(snippet)
        return Response(serializer.data)


#     elif request.method == 'PUT':
#         serializer = ProjectConfigSerializer(snippet, data=request.data)
#         if serializer.is_valid():
#             serializer.save()
#             return Response(serializer.data)
#         return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    elif request.method == 'DELETE':
        if not request.user.has_perm('OpsManage.delete_project_config'):
            return Response(status=status.HTTP_403_FORBIDDEN)
        recordProject.delay(project_user=str(request.user),
                            project_id=id,
                            project_name=snippet.project_name,
                            project_content="删除项目")
        snippet.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)
Exemple #2
0
def deploy_add(request):
    if request.method == "GET":
        serverList = Server_Assets.objects.all()
        groupList = RoleList.objects.all()
        return render(request, 'deploy/deploy_add.html', {"user": request.user, "groupList": groupList,
                                                          "serverList": serverList})
    elif request.method == "POST":
        serverList = Server_Assets.objects.all()
        ipList = request.POST.getlist('server')
        try:
            print(request.POST)
            project = Project_Config.objects.create(
                project_name=request.POST.get('project_name'),
                project_env=request.POST.get('project_env'),
                project_repertory=request.POST.get('project_repertory'),
                project_address=request.POST.get('project_address'),
                project_repo_dir=request.POST.get('project_repo_dir'),
                project_remote_command=request.POST.get('project_remote_command'),
                project_local_command=request.POST.get('project_local_command'),
                project_dir=request.POST.get('project_dir'),
                project_uuid=uuid.uuid4(),
                project_exclude=request.POST.get('project_exclude', '.git').rstrip(),
                project_user=request.POST.get('project_user', 'root'),
                project_model=request.POST.get('project_model'),
                project_status=0,
                project_repo_user=request.POST.get('project_repo_user'),
                project_repo_passwd=request.POST.get('project_repo_passwd'),
                project_audit_group=request.POST.get('project_audit_group', None),
            )
            recordProject.delay(project_user=str(request.user), project_id=project.id,
                                project_name=project.project_name, project_content="添加项目")
        except Exception as e:
            return render(request, 'deploy/deploy_add.html', {"user": request.user,
                                                              "serverList": serverList,
                                                              "errorInfo": "部署服务器信息添加错误:%s" % str(e)},
                          )
        if ipList:
            for sid in ipList:
                try:
                    server = Server_Assets.objects.get(id=sid)
                    Project_Number.objects.create(dir=request.POST.get('dir'),
                                                  server=server.ip,
                                                  project=project)
                except Exception as e:
                    project.delete()
                    return render(request, 'deploy/deploy_add.html', {"user": request.user,
                                                                      "serverList": serverList,
                                                                      "errorInfo": "目标服务器信息添加错误:%s" % str(e)},
                                  )

        return HttpResponseRedirect('/deploy_add')
Exemple #3
0
def deploy_init(request, pid):
    if request.method == "POST":
        project = Project_Config.objects.select_related().get(id=pid)
        if project.project_repertory == 'git':
            version = GitTools()
        elif project.project_repertory == 'svn':
            version = SvnTools()
        version.mkdir(dir=project.project_repo_dir)
        version.mkdir(dir=project.project_dir)
        result = version.clone(url=project.project_address, dir=project.project_repo_dir,
                               user=project.project_repo_user, passwd=project.project_repo_passwd)
        if result[0] > 0:
            return JsonResponse({'msg': result[1], "code": 500, 'data': []})
        else:
            Project_Config.objects.filter(id=pid).update(project_status=1)
            recordProject.delay(project_user=str(request.user), project_id=project.id,
                                project_name=project.project_name, project_content="初始化项目")
            return JsonResponse({'msg': "初始化成功", "code": 200, 'data': []})
Exemple #4
0
def deploy_modf(request, pid):
    try:
        project = Project_Config.objects.select_related().get(id=pid)
        tagret_server = Project_Number.objects.filter(project=project)
    except:
        return render(
            request,
            'deploy/deploy_modf.html',
            {
                "user": request.user,
                "errorInfo": "项目不存在,可能已经被删除."
            },
        )
    if request.method == "GET":
        groupList = Group.objects.all()
        serverList = Server_Assets.objects.all()
        server = [s.server for s in tagret_server]
        for ds in serverList:
            if ds.ip in server:
                ds.count = 1
            else:
                ds.count = 0
        return render(
            request,
            'deploy/deploy_modf.html',
            {
                "user": request.user,
                "project": project,
                "server": tagret_server,
                "serverList": serverList,
                "groupList": groupList
            },
        )
    elif request.method == "POST":
        ipList = request.POST.getlist('server', None)
        try:
            Project_Config.objects.filter(id=pid).update(
                project_name=request.POST.get('project_name'),
                project_env=request.POST.get('project_env'),
                project_repertory=request.POST.get('project_repertory'),
                project_address=request.POST.get('project_address'),
                project_repo_dir=request.POST.get('project_repo_dir'),
                project_remote_command=request.POST.get(
                    'project_remote_command'),
                project_local_command=request.POST.get(
                    'project_local_command'),
                project_dir=request.POST.get('project_dir'),
                project_exclude=request.POST.get('project_exclude',
                                                 '.git').rstrip(),
                project_user=request.POST.get('project_user'),
                project_audit_group=request.POST.get('project_audit_group'),
                project_repo_user=request.POST.get('project_repo_user'),
                project_repo_passwd=request.POST.get('project_repo_passwd'),
            )
            recordProject.delay(project_user=str(request.user),
                                project_id=pid,
                                project_name=project.project_name,
                                project_content="修改项目")
        except Exception as e:
            return render(
                request,
                'deploy/deploy_modf.html',
                {
                    "user": request.user,
                    "errorInfo": "更新失败:" + str(e)
                },
            )
        if ipList:
            tagret_server_list = [s.server for s in tagret_server]
            postServerList = []
            for sid in ipList:
                try:
                    server = Server_Assets.objects.get(id=sid)
                    postServerList.append(server.ip)
                    if server.ip in tagret_server_list:
                        Project_Number.objects.filter(id=pid).update(
                            dir=request.POST.get('dir'),
                            server=server.ip,
                            project=project)
                    else:
                        Project_Number.objects.create(
                            dir=request.POST.get('dir'),
                            server=server.ip,
                            project=project)
                except Exception as e:
                    return render(
                        request,
                        'deploy/deploy_modf.html',
                        {
                            "user": request.user,
                            "serverList": postServerList,
                            "errorInfo": "目标服务器信息添加错误:%s" % str(e)
                        },
                    )
                    # 清除目标主机 -
            delList = list(
                set(tagret_server_list).difference(set(postServerList)))
            for ip in delList:
                Project_Number.objects.filter(project=project,
                                              server=ip).delete()
        return HttpResponseRedirect('/deploy_mod/{id}/'.format(id=pid))
Exemple #5
0
def deploy_run(request, pid):
    try:
        project = Project_Config.objects.get(id=pid)
        serverList = Project_Number.objects.filter(project=project)
        if project.project_repertory == 'git':
            version = GitTools()
        elif project.project_repertory == 'svn':
            version = SvnTools()
    except:
        return render(
            request,
            'deploy/deploy_run.html',
            {
                "user": request.user,
                "errorInfo": "项目不存在,可能已经被删除."
            },
        )
    if request.method == "GET":
        if project.project_model == 'branch':
            bList = version.branch(path=project.project_repo_dir)
        elif project.project_model == 'tag':
            bList = version.tag(path=project.project_repo_dir)
        # 获取最新版本
        version.pull(path=project.project_repo_dir)
        vList = version.log(path=project.project_repo_dir, number=50)
        return render(
            request,
            'deploy/deploy_run.html',
            {
                "user": request.user,
                "project": project,
                "bList": bList,
                "vList": vList
            },
        )

    elif request.method == "POST":
        if DsRedis.OpsProject.get(redisKey=project.project_uuid +
                                  "-locked") is None:  # 判断该项目是否有人在部署
            # 给项目部署加上锁
            DsRedis.OpsProject.set(redisKey=project.project_uuid + "-locked",
                                   value=request.user)
            DsRedis.OpsDeploy.delete(project.project_uuid)
            if request.POST.get('project_mode', None) == "rollback":
                if project.project_model == 'branch':
                    trueDir = project.project_dir + project.project_env + '/' + request.POST.get(
                        'project_version') + '/'
                    DsRedis.OpsDeploy.lpush(
                        project.project_uuid,
                        data="[Start] Start Rollback branch:%s  vesion: %s" %
                        (request.POST.get('project_branch'),
                         request.POST.get('project_version')))
                elif project.project_model == 'tag':
                    trueDir = project.project_dir + project.project_env + '/' + request.POST.get(
                        'project_branch') + '/'
                    DsRedis.OpsDeploy.lpush(
                        project.project_uuid,
                        data="[Start] Start Rollback tag:%s" %
                        request.POST.get('project_branch'))
            else:
                # 判断版本上线类型再切换分支到指定的分支/Tag
                if project.project_model == 'branch':
                    bName = request.POST.get('project_branch')
                    result = version.checkOut(path=project.project_repo_dir,
                                              name=bName)
                    DsRedis.OpsDeploy.lpush(
                        project.project_uuid,
                        data="[Start] Switched to branch %s" % bName)
                    # reset到指定版本
                    result = version.reset(
                        path=project.project_repo_dir,
                        commintId=request.POST.get('project_version'))
                    DsRedis.OpsDeploy.lpush(
                        project.project_uuid,
                        data="[Running] Git reset to {comid} info: {info}".
                        format(comid=request.POST.get('project_version'),
                               info=result[1]))
                    trueDir = project.project_dir + project.project_env + '/' + request.POST.get(
                        'project_version') + '/'
                elif project.project_model == 'tag':
                    bName = request.POST.get('project_branch')
                    result = version.checkOut(path=project.project_repo_dir,
                                              name=bName)
                    DsRedis.OpsDeploy.lpush(project.project_uuid,
                                            data="[Start] Switched to tag %s" %
                                            bName)
                    trueDir = project.project_dir + project.project_env + '/' + bName + '/'
                # 创建版本目录
                base.mkdir(dirPath=trueDir)
                DsRedis.OpsDeploy.lpush(
                    project.project_uuid,
                    data="[Running] Mkdir version dir: {dir} ".format(
                        dir=trueDir))
                # 创建快捷方式
                softdir = project.project_dir + project.project_name + '/'
                result = base.lns(spath=trueDir, dpath=softdir.rstrip('/'))
                DsRedis.OpsDeploy.lpush(
                    project.project_uuid,
                    data=
                    "[Running] Make softlink cmd:  ln -s  {sdir} {ddir} info: {info}"
                    .format(sdir=trueDir, ddir=softdir, info=result[1]))
                if result[0] > 0:
                    return JsonResponse({
                        'msg': result[1],
                        "code": 500,
                        'data': []
                    })
                # 执行部署命令  - 编译型语言
                if project.project_local_command:
                    result = base.cmds(cmds=project.project_local_command)
                    DsRedis.OpsDeploy.lpush(
                        project.project_uuid,
                        data=
                        "[Running] Execute local command: {cmds} info: {info}".
                        format(cmds=project.project_local_command,
                               info=result[1]))
                    if result[0] > 0:
                        return JsonResponse({
                            'msg': result[1],
                            "code": 500,
                            'data': []
                        })
                    # 非编译型语言
                else:
                    # 获取要排除的文件
                    exclude = None
                    ansible_exclude_list = None
                    if project.project_exclude:
                        try:
                            exclude = ''
                            ansible_exclude_list = []
                            for s in project.project_exclude.split(','):
                                exclude = '--exclude "{file}"'.format(
                                    file=s.replace('\r\n', '').replace(
                                        '\n', '').strip()) + ' ' + exclude
                                exclude_str = '--exclude="{file}"'.format(
                                    file=s.replace('\r\n', '').replace(
                                        '\n', '').strip())
                                ansible_exclude_list.append(exclude_str)
                        except Exception as e:
                            return JsonResponse({
                                'msg': str(e),
                                "code": 500,
                                'data': []
                            })
                    # 配置rsync同步文件到本地目录
                    result = base.rsync(sourceDir=project.project_repo_dir,
                                        destDir=trueDir,
                                        exclude=exclude)
                    DsRedis.OpsDeploy.lpush(
                        project.project_uuid,
                        data="[Running] Rsync {sDir} to {dDir} exclude {exclude}"
                        .format(sDir=project.project_repo_dir,
                                dDir=trueDir,
                                exclude=exclude))
                    if result[0] > 0:
                        return JsonResponse({
                            'msg': result[1],
                            "code": 500,
                            'data': []
                        })
                    # 授权文件
            result = base.chown(user=project.project_user, path=trueDir)
            DsRedis.OpsDeploy.lpush(
                project.project_uuid,
                data="[Running] Chown {user} to {path}".format(
                    user=project.project_user, path=trueDir))
            if result[0] > 0:
                return JsonResponse({
                    'msg': result[1],
                    "code": 500,
                    'data': []
                })
            # 调用ansible同步代码到远程服务器上
            resource = []
            hostList = []
            for ds in serverList:
                server = Server_Assets.objects.get(ip=ds.server)
                hostList.append(ds.server)
                data = dict()
                if server.keyfile == 1:
                    data['port'] = int(server.port)
                    data["hostname"] = server.ip
                else:
                    data["hostname"] = server.ip
                    data["port"] = int(server.port)
                    data["username"] = server.username
                    data["password"] = server.passwd
                resource.append(data)
            if resource and hostList:
                if ansible_exclude_list:
                    ansible_exclude = ','.join(ansible_exclude_list)
                    args = '''src={srcDir} dest={desDir} links=yes recursive=yes compress=yes delete=yes rsync_opts="{exclude}"'''.format(
                        srcDir=softdir, desDir=ds.dir, exclude=ansible_exclude)
                else:
                    args = '''src={srcDir} dest={desDir} links=yes recursive=yes compress=yes delete=yes'''.format(
                        srcDir=softdir, desDir=ds.dir)
                ANS = ANSRunner(resource)
                ANS.run_model(host_list=hostList,
                              module_name='synchronize',
                              module_args=args)
                # 精简返回的结果
                dataList = ANS.handle_model_data(ANS.get_model_result(),
                                                 'synchronize',
                                                 module_args=args)
                for ds in dataList:
                    DsRedis.OpsDeploy.lpush(
                        project.project_uuid,
                        data=
                        "[Running] Rsync project to {host} status: {status} msg: {msg}"
                        .format(host=ds.get('ip'),
                                status=ds.get('status'),
                                msg=ds.get('msg')))
                    if ds.get('status') == 'failed':
                        result = (1, ds.get('ip') + ds.get('msg'))
            # 目标服务器执行后续命令
            if project.project_remote_command:
                ANS.run_model(host_list=hostList,
                              module_name='raw',
                              module_args=project.project_remote_command)
                # 精简返回的结果
                dataList = ANS.handle_model_data(
                    ANS.get_model_result(),
                    'raw',
                    module_args=project.project_remote_command)
                for ds in dataList:
                    DsRedis.OpsDeploy.lpush(
                        project.project_uuid,
                        data=
                        "[Running] Execute command to {host} status: {status} msg: {msg}"
                        .format(host=ds.get('ip'),
                                status=ds.get('status'),
                                msg=ds.get('msg')))
                    if ds.get('status') == 'failed':
                        result = (1, "部署错误: " + ds.get('msg'))
            if result[0] > 0:
                DsRedis.OpsProject.delete(redisKey=project.project_uuid +
                                          "-locked")
                return JsonResponse({
                    'msg': result[1],
                    "code": 500,
                    'data': []
                })
            DsRedis.OpsDeploy.lpush(project.project_uuid,
                                    data="[Done] Deploy Success.")
            # 切换版本之后取消项目部署锁
            DsRedis.OpsProject.delete(redisKey=project.project_uuid +
                                      "-locked")
            # 异步记入操作日志
            if request.POST.get('project_version'):
                bName = request.POST.get('project_version')
            recordProject.delay(project_user=str(request.user),
                                project_id=project.id,
                                project_name=project.project_name,
                                project_content="部署项目",
                                project_branch=bName)
            return JsonResponse({'msg': "项目部署成功", "code": 200, 'data': []})
        else:
            return JsonResponse({
                'msg':
                "项目部署失败:{user}正在部署改项目,请稍后再提交部署。".format(
                    user=DsRedis.OpsProject.get(redisKey=project.project_uuid +
                                                "-locked")),
                "code":
                500,
                'data': []
            })