Ejemplo n.º 1
0
 def destroy(self, request, *args, **kwargs):
     """
     删除镜像信息
     :param request:
     :param args:
     :param kwargs:
     :return:
     """
     user = request.user
     if not user.is_superuser:
         return JsonResponse(R.build(msg="权限不足"))
     network = self.get_object()
     count = LayoutServiceNetwork.objects.filter(network_id=network).count()
     if count == 0:
         try:
             docker_network = client.networks.get(
                 network.net_work_client_id)
             docker_network.remove()
         except Exception as e:
             try:
                 network_list = client.networks.list()
                 for network in network_list:
                     network_configs = network.attrs['IPAM']['Config']
                     if len(network_configs) > 0:
                         subnet = network_configs[0]['Subnet']
                         if subnet != network.net_work_subnet:
                             continue
                         network.remove()
             except Exception as e:
                 pass
         network.delete()
         return JsonResponse(R.ok())
     else:
         return JsonResponse(
             R.build(msg="网卡 %s 正在使用无法删除" % (network.net_work_subnet, )))
Ejemplo n.º 2
0
 def get_layout(self, request, pk=None):
     if not pk or pk == "undefined":
         return JsonResponse(R.build(msg="环境不存在"))
     user = request.user
     if user.is_superuser:
         layout_info = Layout.objects.filter(layout_id=pk).first()
     else:
         layout_info = Layout.objects.filter(layout_id=pk, is_release=True).first()
     if not layout_info:
         return JsonResponse(R.build(msg="环境不存在或未发布"))
     layout_path = os.path.join(DOCKER_COMPOSE, str(layout_info.layout_id))
     layout_data = LayoutData.objects.filter(layout_id=layout_info,
                                             file_path="docker-compose" + layout_path.replace(DOCKER_COMPOSE,
                                                                                              ""), ).first()
     open_host_list = []
     is_run = False
     if layout_data and layout_data.status == 'running':
         service_container_list = LayoutServiceContainer.objects.filter(layout_user_id=layout_data)
         for service_container in service_container_list:
             service_info = service_container.service_id
             container_host = service_container.container_host
             if service_info.is_exposed:
                 if container_host:
                     open_host_list.extend(container_host.split(","))
         is_run = True
     result_data = {
         "layout": {
             "name": layout_info.layout_name,
             "desc": layout_info.layout_desc,
         },
         "open": open_host_list,
         "is_run": is_run
     }
     return JsonResponse(R.ok(data=result_data))
Ejemplo n.º 3
0
 def del_comment(self, request, pk=None):
     user = request.user
     if not pk:
         return JsonResponse(R.build(msg="参数不能为空"))
     comment_info = Comment.objects.filter(comment_id=pk).first()
     if not comment_info:
         return JsonResponse(R.build(msg="评论不存在"))
     if not user.is_superuser and comment_info.user != user:
         return JsonResponse(R.build(msg="权限不足"))
     comment_info.delete()
     return JsonResponse(R.ok())
Ejemplo n.º 4
0
 def delete_image(self, request, pk=None):
     user = request.user
     if not pk or pk == "undefined":
         return JsonResponse(R.build(msg="环境不存在"))
     if not user.is_superuser:
         return JsonResponse(R.build(msg="权限不足"))
     try:
         layout = Layout.objects.filter(layout_id=pk).first()
         if not layout:
             return JsonResponse(R.build(msg="环境不存在"))
         layout_name = layout.layout_name
         layout_id = str(layout.layout_id)
         layout_path = os.path.join(DOCKER_COMPOSE, layout_id)
         with transaction.atomic():
             _tmp_file_path = "docker-compose" + layout_path.replace(
                 DOCKER_COMPOSE, "")
             layout_data = LayoutData.objects.filter(
                 layout_id=layout, file_path=_tmp_file_path).first()
             if layout_data and layout_data.status == 'running':
                 return JsonResponse(R.build(msg="环境正在运行中,请首先停止运行"))
             # 删除分数
             LayoutServiceContainerScore.objects.filter(
                 layout_id=layout).delete()
             # 删除容器
             if layout_data:
                 LayoutServiceContainer.objects.filter(
                     layout_user_id=layout_data)
             # 删除服务网卡
             service_list = LayoutService.objects.filter(layout_id=layout)
             if len(service_list) > 0:
                 for service in service_list:
                     # service_id = service.service_id
                     LayoutServiceNetwork.objects.filter(
                         service_id=service).delete()
             # 删除服务
             LayoutService.objects.filter(layout_id=layout).delete()
             # 删除内容
             layout.delete()
             # 删除文件和文件夹
             shutil.rmtree(layout_path)
             request_ip = get_request_ip(request)
             sys_log = SysLog(user_id=user.id,
                              operation_type="编排环境",
                              operation_name="删除",
                              operation_value=layout_name,
                              operation_args=json.dumps(
                                  LayoutSerializer(layout).data),
                              ip=request_ip)
             sys_log.save()
     except Exception as e:
         traceback.print_exc()
         return JsonResponse(R.err())
     return JsonResponse(R.ok())
Ejemplo n.º 5
0
 def update(self, request, *args, **kwargs):
     user = request.user
     if not user.is_superuser:
         return JsonResponse(R.build(msg="权限不足"))
     new_pwd = request.data.get("pwd", "")
     new_pwd = new_pwd.strip()
     if len(new_pwd) < 6:
         return JsonResponse(R.build(msg="密码格式不正确"))
     user_info = self.get_object()
     user_info.set_password(new_pwd)
     user_info.save()
     return JsonResponse(R.ok())
Ejemplo n.º 6
0
 def flag_layout(self, request, pk=None):
     if not pk or pk == "undefined":
         return JsonResponse(R.build(msg="环境不存在"))
     user = request.user
     layout_info = Layout.objects.filter(layout_id=pk,
                                         is_release=True).first()
     if not layout_info:
         return JsonResponse(R.build(msg="环境不存在或未发布"))
     flag = str(request.GET.get("flag", ""))
     if not flag:
         return JsonResponse(R.build(msg="Flag 不能为空"))
     if not flag.startswith("flag-{bmh"):
         return JsonResponse(R.build(msg="Flag 格式不正确"))
     layout_path = os.path.join(DOCKER_COMPOSE, str(layout_info.layout_id))
     layout_data = LayoutData.objects.filter(
         layout_id=layout_info,
         file_path="docker-compose" +
         layout_path.replace(DOCKER_COMPOSE, ""),
     ).first()
     service_container = LayoutServiceContainer.objects.filter(
         layout_user_id=layout_data, container_flag=flag).first()
     if not service_container:
         return JsonResponse(R.build(msg="Flag 不正确"))
     service_container_score = LayoutServiceContainerScore.objects.filter(
         user_id=user.id, flag=flag,
         service_container_id=service_container).first()
     if not service_container_score:
         service_info = service_container.service_id
         image_info = service_container.image_id
         service_container_score = LayoutServiceContainerScore(
             layout_service_container_score_id=uuid.uuid4(),
             user_id=user.id,
             layout_id=layout_info,
             layout_data_id=layout_data,
             service_id=service_info,
             image_id=image_info,
             create_date=timezone.now(),
             service_container_id=service_container,
             flag=flag,
             update_date=timezone.now())
     service_container_score.save()
     request_ip = get_request_ip(request)
     sys_log = SysLog(user_id=user.id,
                      operation_type="编排环境",
                      operation_name="提交Flag",
                      operation_value=layout_info.layout_name,
                      operation_args=json.dumps({"flag": flag}),
                      ip=request_ip)
     sys_log.save()
     return JsonResponse(R.ok())
Ejemplo n.º 7
0
 def release_layout(self, request, pk=None):
     """
     发布环境
     """
     if not pk or pk == "undefined":
         return JsonResponse(R.build(msg="环境不存在"))
     user = request.user
     if not user.is_superuser:
         return JsonResponse(R.build(msg="权限不足"))
     layout_info = Layout.objects.filter(layout_id=pk).first()
     if not layout_info:
         return JsonResponse(R.build(msg="环境不存在"))
     layout_info.is_release = True
     layout_info.save()
     return JsonResponse(R.ok())
Ejemplo n.º 8
0
def create_container_task(container_vul, user_info, request_ip):
    """
    创建漏洞容器
    :param container_vul: container vul
    :param user_info: user info
    :param request_ip: request ip
    :return:
    """
    image_info = container_vul.image_id
    user_id = user_info.id
    task_id = create_run_container_task(container_vul, user_info)
    if user_info.is_superuser or user_id == container_vul.user_id:
        operation_args = ImageInfoSerializer(image_info).data
        sys_log = SysLog(user_id=user_id, operation_type="容器", operation_name="启动", ip=request_ip,
                         operation_value=operation_args["image_vul_name"], operation_args=json.dumps(operation_args))
        sys_log.save()
        setting_config = get_setting_config()
        try:
            countdown = int(setting_config["time"])
        except:
            countdown = int(DEFAULT_CONFIG["time"])
        if countdown == 0:
            run_container.delay(container_vul.container_id, user_id, task_id, countdown)
        elif countdown != 0 and countdown > 60:
            # run_container(container_vul.container_id, user_id, task_id, countdown)
            setting_config = get_setting_config()
            if 'del_container' in setting_config:
                del_container = setting_config['del_container']
                if not del_container or del_container == 0 or del_container == '0':
                    add_chain_sig = chain(run_container.s(container_vul.container_id, user_id, task_id, countdown) |
                                          stop_container.s().set(countdown=countdown))
                else:
                    add_chain_sig = chain(run_container.s(container_vul.container_id, user_id, task_id, countdown) |
                                          delete_container.s().set(countdown=countdown))
                add_chain_sig.apply_async()
        else:
            task_info = TaskInfo.objects.filter(task_id=task_id).first()
            task_info.task_msg = json.dumps(R.build(msg="停止时间最小为 1 分钟"))
            task_info.task_status = 4
            task_info.update_date = timezone.now()
            task_info.save()
    else:
        task_info = TaskInfo.objects.filter(task_id=task_id).first()
        task_info.task_msg = json.dumps(R.build(msg="权限不足"))
        task_info.task_status = 3
        task_info.update_date = timezone.now()
        task_info.save()
    return task_id
Ejemplo n.º 9
0
 def create(self, request, *args, **kwargs):
     user = request.user
     if not user.is_superuser:
         return JsonResponse(R.build(msg="权限不足"))
     now_time = datetime.datetime.now()
     data = request.data
     notice_data = data['notice_content']
     title = data["title"]
     if not notice_data:
         return JsonResponse({"code": 400, "message": "公告内容不能为空"})
     if not title:
         return JsonResponse({"code": 400, "message": "公告标题不能为空"})
     if "update_notice" in data and data["update_notice"] == True:
         notice_id = data['notice_id']
         update_noticeinfo = Notice.objects.filter(notice_id=notice_id,
                                                   is_public=False).first()
         update_noticeinfo.update_date = now_time
         update_noticeinfo.notice_content = json.dumps(notice_data)
         update_noticeinfo.title = title
         update_noticeinfo.save()
         return JsonResponse({"code": 200, "msg": "公告修改成功"})
     else:
         notice_info = Notice(notice_id=str(uuid.uuid4()),
                              title=title,
                              notice_content=json.dumps(notice_data),
                              create_date=now_time)
         notice_info.save()
     return JsonResponse({"code": 200, "msg": "提交成功"})
Ejemplo n.º 10
0
def delete_container_task(container_vul, user_info, request_ip):
    """
    删除漏洞容器
    :param container_vul: container vul
    :param user_info: user info
    :param request_ip: request ip
    :return:
    """
    user_id = user_info.id
    task_id = create_delete_container_task(container_vul=container_vul,
                                           user_info=user_info)
    if user_info.is_superuser or user_id == container_vul.user_id:
        operation_args = ContainerVulSerializer(container_vul).data
        sys_log = SysLog(user_id=user_id,
                         operation_type="容器",
                         operation_name="删除",
                         ip=request_ip,
                         operation_value=operation_args["vul_name"],
                         operation_args=json.dumps(operation_args))
        sys_log.save()
        # 下发停止容器任务
        delete_container.delay(task_id)
    else:
        task_info = TaskInfo.objects.filter(task_id=task_id).first()
        task_info.task_msg = json.dumps(R.build(msg="权限不足"))
        task_info.task_status = 3
        task_info.update_date = timezone.now()
        task_info.save()
    return task_id
Ejemplo n.º 11
0
 def rank_layout(self, request, pk=None):
     """
     排行
     """
     user = request.user
     page_no = int(request.GET.get("page", 1))
     if not pk or pk == "undefined":
         return JsonResponse(R.build(msg="环境不存在"))
     layout_info = Layout.objects.filter(layout_id=pk, is_release=True).first()
     if not layout_info:
         return JsonResponse(R.build(msg="环境不存在"))
     score_list = LayoutServiceContainerScore.objects.filter(layout_id=layout_info).values('user_id').annotate(
         score=Sum("image_id__rank")).values('user_id', 'score').order_by("-score")
     try:
         pages = Paginator(score_list, 20)
         page = pages.page(page_no)
     except Exception as e:
         return JsonResponse(R.err())
     current_rank = 0
     current_score = 0
     for i, _score in enumerate(score_list):
         user_id = _score["user_id"]
         if user.id != user_id:
             continue
         current_rank = i + 1
         current_score = _score["score"]
         break
     layout_path = os.path.join(DOCKER_COMPOSE, str(layout_info.layout_id))
     layout_data = LayoutData.objects.filter(layout_id=layout_info,
                                             file_path="docker-compose" + layout_path.replace(DOCKER_COMPOSE,
                                                                                              ""), ).first()
     score_count = LayoutServiceContainerScore.objects.filter(layout_id=layout_info, user_id=user.id).count()
     score_total_count = LayoutServiceContainer.objects.filter(layout_user_id=layout_data).count()
     result = []
     for _data in list(page):
         user_info = UserProfile.objects.filter(id=_data["user_id"]).first()
         username = ""
         if user_info:
             username = user_info.username
         result.append({"score": _data["score"], "username": username})
     return JsonResponse({
         "result": result,
         "count": pages.count,
         "current": current_rank,
         "progress": "%s/%s" % (score_count, score_total_count,),
         "score": current_score
     })
Ejemplo n.º 12
0
 def stop_layout(self, request, pk=None):
     if not pk or pk == "undefined":
         return JsonResponse(R.build(msg="环境不存在"))
     user = request.user
     if not user.is_superuser:
         return JsonResponse(R.build(msg="权限不足"))
     layout_info = Layout.objects.filter(layout_id=pk,
                                         is_release=True).first()
     if not layout_info:
         return JsonResponse(R.build(msg="环境不存在或未发布"))
     layout_id = str(layout_info.layout_id)
     layout_path = os.path.join(DOCKER_COMPOSE, layout_id)
     layout_data = LayoutData.objects.filter(
         layout_id=layout_info,
         file_path="docker-compose" +
         layout_path.replace(DOCKER_COMPOSE, ""),
     ).first()
     if not layout_data:
         return JsonResponse(R.build(msg="环境未启动,无法停止"))
     if not os.path.exists(layout_path):
         return JsonResponse(R.ok())
     if layout_data.status == "stop":
         return JsonResponse(R.ok())
     try:
         with transaction.atomic():
             container_list = get_project(layout_path).stop()
             if container_list:
                 for container in container_list:
                     container_id = container.id
                     LayoutServiceContainer.objects.filter(docker_container_id=container_id) \
                         .update(container_status="stop")
             LayoutServiceContainer.objects.filter(
                 layout_user_id=layout_data).update(container_status="stop")
             layout_data.status = "stop"
             layout_data.save()
     except Exception as e:
         return JsonResponse(R.err())
     request_ip = get_request_ip(request)
     sys_log = SysLog(user_id=user.id,
                      operation_type="编排环境",
                      operation_name="停止",
                      operation_value=layout_info.layout_name,
                      operation_args=json.dumps(
                          LayoutSerializer(layout_info).data),
                      ip=request_ip)
     sys_log.save()
     return JsonResponse(R.ok())
Ejemplo n.º 13
0
def create_image(task_id):
    """
    创建镜像名称
    """
    task_info = TaskInfo.objects.filter(task_id=task_id, task_status=1).first()
    if not task_info:
        return
    operation_args = task_info.operation_args
    args = json.loads(operation_args)
    image_name = args["image_name"].strip()
    image_desc = args["image_desc"].strip()
    image_rank = args["rank"]
    image_vul_name = args["image_vul_name"].strip()
    image_info = ImageInfo.objects.filter(image_name=image_name).first()
    if not image_info:
        image_info = ImageInfo(image_name=image_name,
                               image_desc=image_desc,
                               rank=image_rank,
                               image_vul_name=image_vul_name)
    image = None
    msg = {}
    try:
        image = client.images.get(image_name)
    except Exception as e:
        image_info.is_ok = False
        image_info.save()
        try:
            images = client.images.pull(image_name)
            if Image == type(images):
                image = images
            else:
                if len(images) > 0:
                    image = images[0]
        except ImageNotFound:
            msg = R.build(msg="%s 不存在")
        except Exception:
            traceback.print_exc()
            msg = R.err(msg="%s 添加失败" % (image_name, ))
    if image:
        config = image.attrs["ContainerConfig"]
        port_list = []
        if "ExposedPorts" in config:
            port_list = config["ExposedPorts"]
        ports = []
        for port in port_list:
            port = port.replace("/", "").replace("tcp", "").replace("udp", "")
            ports.append(port)
        image_port = ",".join(ports)
        image_info.image_port = image_port
        image_info.is_ok = True
        image_info.save()
        msg = R.ok(msg="%s 添加成功" % (image_name, ),
                   data=json.dumps({"image_port": image_port}))
        task_info.task_status = 3
    else:
        task_info.task_status = 4
    task_info.task_msg = json.dumps(msg)
    task_info.save()
Ejemplo n.º 14
0
def upload_img(request):
    """
    上传文件图片
    """
    user = request.user
    if not user.is_superuser:
        return JsonResponse(R.build(msg="权限不足"))
    img = request.data["img"]
    if not img:
        return JsonResponse(R.build(msg="请上传图片"))
    img_name = img.name
    img_suffix = img_name.split(".")[-1]
    if img_suffix not in ALLOWED_IMG_SUFFIX:
        return JsonResponse(
            R.build(msg="不支持此格式图片文件,请上传%s格式文件" %
                    ("、".join(ALLOWED_IMG_SUFFIX), )))
    image_name = str(uuid.uuid4()).replace('-', '') + "." + img_suffix
    with open(os.path.join(BASE_DIR, "static", image_name), "wb") as f:
        for chunk in img.chunks():
            f.write(chunk)
        return JsonResponse(R.ok(data=image_name))
Ejemplo n.º 15
0
def publish_notice(request):
    user = request.user
    if not user.is_superuser:
        return JsonResponse(R.build("权限不足"))
    if "id" in request.data:
        try:
            notice_info = Notice.objects.filter(notice_id=request.data["id"]).first()
            notice_info.is_public = True
            notice_info.is_newest = True
            notice_info.save()
            notify.send(request.user,
                        recipient=UserProfile.objects.all(),
                        verb="public notice", target=notice_info)
            return JsonResponse({"code": 200, "message": "发布成功"})
        except Exception as e:
            return JsonResponse({"code": 400, "message": "发布失败"})
    return JsonResponse({"code": 400, "message": "发布失败"})
Ejemplo n.º 16
0
 def destroy(self, request, *args, **kwargs):
     user = request.user
     if not user.is_superuser:
         return JsonResponse(R.build("权限不足"))
     if "id" in request.data:
         notice_id = request.data["id"]
     else:
         notice = self.get_object()
         notice_id = notice.notice_id
     if notice_id:
         notice_instance = Notice.objects.filter(notice_id=notice_id).first()
         notice_instance.delete()
         notifications = Notification.objects.all()
         for single_notification in notifications:
             if single_notification.target_object_id ==notice_id:
                 single_notification.delete()
         return JsonResponse({"code": 200, "message": "删除成功"})
     return JsonResponse({"code": 400, "message": "删除失败"})
Ejemplo n.º 17
0
 def get_queryset(self):
     user = self.request.user
     if not user.is_superuser:
         return JsonResponse(R.build("权限不足"))
     query = self.request.GET.get("query", "")
     if query:
         query = query.strip()
         seven_days_ago = datetime.datetime.now()-datetime.timedelta(days=7)
         nots = Notice.objects.filter(title__contains=query).all()
         for single_not in nots:
             if single_not.update_date < seven_days_ago:
                 single_not.is_newest = False
         return nots
     else:
         seven_days_ago = datetime.datetime.now() - datetime.timedelta(days=7)
         nots = Notice.objects.all()
         for single_not in nots:
             if single_not.update_date < seven_days_ago:
                 single_not.is_newest = False
         return nots
Ejemplo n.º 18
0
def create_image_task(image_info, user_info, request_ip, image_file=None):
    """
    创建镜像任务
    """
    user_id = user_info.id
    task_id = create_create_image_task(image_info=image_info, user_info=user_info)
    if user_info.is_superuser:
        image_name = image_info.image_name
        image_desc = image_info.image_desc
        image_vul_name = image_info.image_vul_name
        image_rank = image_info.rank
        task_info = TaskInfo.objects.filter(task_id=task_id).first()
        if image_file:
            task_msg = {}
            try:
                file_info = image_file.read()
                images = client.images.load(file_info)
                image = images[0]
                repo_tags = image.attrs["RepoTags"]
                if len(repo_tags) == 0:
                    # 移除本地镜像
                    try:
                        client.images.remove(image.id)
                    except Exception as e:
                        pass
                    task_msg = R.build(msg="文件镜像 Tag 不能为空")
                else:
                    config = image.attrs["ContainerConfig"]
                    port_list = []
                    if "ExposedPorts" in config:
                        port_list = config["ExposedPorts"]
                    ports = []
                    for port in port_list:
                        port = port.replace("/", "").replace("tcp", "").replace("udp", "")
                        ports.append(port)
                    image_name = repo_tags[0]
                    image_port = ",".join(ports)
                    image_info = ImageInfo.objects.filter(image_name=image_name).first()
                    if not image_info:
                        image_info = ImageInfo()
                    image_info.image_name = image_name
                    image_info.image_port = image_port
                    # image_vul_name
                    image_info.image_vul_name = image_name.replace("vulfocus/","") if not image_vul_name else image_vul_name
                    # image_desc
                    image_info.image_desc = image_name.replace("vulfocus/","") if not image_desc else image_desc
                    # rank
                    image_info.rank = 2.5 if image_rank > 5 or image_rank < 0.5 else image_rank
                    image_info.is_ok = True
                    image_info.save()
                    task_info.task_name = "拉取镜像:"+image_name
                    task_info.task_status = 3
                    task_msg = R.ok(data="%s 添加成功" % (image_name, ))
            except Exception as e:
                traceback.print_exc()
                task_msg = R.err()
                try:
                    image_info.delete()
                except:
                    pass
                task_info.task_status = 4
            finally:
                task_info.task_msg = json.dumps(task_msg)
                task_info.update_date = timezone.now()
                task_info.save()
        elif image_name:
            # 创建任务
            # create_image(task_id=task_id)
            create_image.delay(task_id)
        else:
            R.build(msg="镜像文件或镜像名称不能为空")
        operation_args = ImageInfoSerializer(image_info).data
        sys_log = SysLog(user_id=user_id, operation_type="镜像", operation_name="创建", ip=request_ip,
                         operation_value=operation_args["image_vul_name"], operation_args=json.dumps(operation_args))
        sys_log.save()
    else:
        task_info = TaskInfo.objects.filter(task_id=task_id).first()
        task_info.task_msg = json.dumps(R.build(msg="权限不足"))
        task_info.task_status = 3
        task_info.update_date = timezone.now()
        task_info.save()
    return task_id
Ejemplo n.º 19
0
def run_container(container_id, user_id, tmp_task_id, countdown):
    """
    运行 docker 容器
    :param container_id: 漏洞容器数据库 id
    :param user_id: 用户ID
    :param tmp_task_id: 任务ID
    :param countdown 定时
    """
    # docker container id
    container_vul = ContainerVul.objects.filter(container_id=container_id).first()
    user_info = UserProfile.objects.filter(id=user_id).first()
    container_id = container_vul.docker_container_id
    image_info = container_vul.image_id
    image_name = image_info.image_name
    image_port = image_info.image_port
    user_id = user_info.id
    docker_container = None
    msg = {}
    """
    创建启动任务
    """
    args = {
        "image_name": image_name,
        "user_id": user_id,
        "image_port": image_port
    }
    task_id = ""
    task_info = TaskInfo.objects.filter(task_id=tmp_task_id).first()
    # run container execute command
    command = ""
    vul_flag = container_vul.container_flag
    container_port = container_vul.container_port
    vul_port = {}
    if container_vul.vul_port:
        vul_port = json.loads(container_vul.vul_port)
    vul_host = container_vul.vul_host
    if container_id:
        # check container
        check_rsp = check_container(container_id)
        if check_rsp["flag"]:
            docker_container = check_rsp["container"]
            # set container_flag
            vul_flag = container_vul.container_flag
    # if container by delete , create a container
    if not docker_container:
        port_list = image_port.split(",")
        port_dict = {}
        random_list = []
        for port in port_list:
            random_port = ''
            for i in range(20):
                # random port
                random_port = str(random.randint(8000, 65536))
                if random_port in random_list or ContainerVul.objects.filter(container_port=random_port).first():
                    continue
                break
            if not random_port:
                msg = R.err(msg="端口无效")
                break
            random_list.append(random_port)
            port_dict['%s/tcp' % (port,)] = int(random_port)
        # 端口重复,无法进行创建
        if len(msg) > 0 or msg:
            task_info.task_msg = json.dumps(msg)
            task_info.update_date = timezone.now()
            # except
            task_info.task_status = 4
            task_info.save()
            return str(task_info.task_id)
        container_port = ",".join(random_list)
        """
        random port
        """
        for tmp_port in port_dict:
            tmp_random_port = port_dict[tmp_port]
            tmp_port = tmp_port.replace("/tcp", "")
            vul_port[tmp_port] = str(tmp_random_port)
        try:
            client.images.get(image_name)
        except Exception as e:
            msg = R.build(msg="镜像不存在")
            task_info.task_msg = json.dumps(msg)
            task_info.update_date = timezone.now()
            # except
            task_info.task_status = 4
            task_info.save()
            image_info.is_ok = False
            image_info.save()
            return str(task_info.task_id)
        vul_flag = "flag-{bmh%s}" % (uuid.uuid4(),)
        if container_vul.container_flag:
            vul_flag = container_vul.container_flag
        try:
            docker_container = client.containers.run(image_name, ports=port_dict, detach=True, environment={"vul_flag": vul_flag})
        except ImageNotFound:
            msg = R.build(msg="镜像不存在")
            task_info.task_msg = json.dumps(msg)
            task_info.update_date = timezone.now()
            # except
            task_info.task_status = 4
            task_info.save()
            image_info.is_ok = False
            image_info.save()
            return str(task_info.task_id)

        command = 'touch /tmp/%s' % (vul_flag,)
        vul_host = get_local_ip() + ":" + container_port
    task_start_date = timezone.now()
    if countdown != 0 and countdown >= 60:
        task_end_date = task_start_date + datetime.timedelta(seconds=countdown)
    elif countdown == 0:
        task_end_date = None
    else:
        countdown = int(DEFAULT_CONFIG["time"])
        task_end_date = task_start_date + datetime.timedelta(seconds=countdown)
    if "running" == docker_container.status:
        msg_data = R.ok(data={
            "host": container_vul.vul_host,
            "port": container_vul.vul_port,
            "id": str(container_vul.container_id),
            "status": "running",
            "start_date": int(task_start_date.timestamp()),
            "end_date": 0 if not task_end_date else int(task_end_date.timestamp())
        })
        search_task = TaskInfo.objects.filter(user_id=user_id, task_msg=json.dumps(msg_data), operation_type=2,
                                              operation_args=json.dumps(args), task_end_date=task_end_date,
                                              task_name="运行容器:" + image_name).order_by("-create_date").first()
        if not search_task:
            task_info.task_status = 3
            task_info.task_msg = json.dumps(msg_data)
            task_info.update_date = timezone.now()
            task_info.operation_args = json.dumps(args)
            task_info.save()
            task_id = str(task_info.task_id)
        else:
            task_info.delete()
            search_task.task_id = tmp_task_id
            search_task.task_status = 3
            search_task.update_date = timezone.now()
            search_task.save()
            task_id = str(search_task.task_id)
    else:
        task_info.save()
        docker_container.start()
        msg = docker_container_run(docker_container, command=command)
        if msg["status"] == HTTP_ERR:
            try:
                container_vul.delete()
            except Exception:
                pass
            # except
            task_info.task_status = 4
        else:
            container_status = msg["data"]["status"]
            msg["data"]["host"] = vul_host
            msg["data"]["port"] = vul_port
            msg["data"]["id"] = str(container_vul.container_id)
            msg["data"]["status"] = container_status
            msg["data"]["start_date"] = int(task_start_date.timestamp())
            msg["data"]["end_date"] = 0 if not task_end_date else int(task_end_date.timestamp())
            # 容器状态
            container_vul.container_status = container_status
            # 容器 id
            container_vul.docker_container_id = str(docker_container.id)
            # 漏洞 HOST
            container_vul.vul_host = vul_host
            # 漏洞端口
            container_vul.vul_port = json.dumps(vul_port)
            # 容器端口映射关系
            container_vul.container_port = container_port
            # 验证 flag
            container_vul.container_flag = vul_flag
            container_vul.save()
            task_start_date = timezone.now()
            # start 时间
            task_info.task_start_date = task_start_date
            task_info.task_end_date = task_end_date
            task_info.task_status = 3
        task_info.task_msg = json.dumps(msg)
        task_info.update_date = timezone.now()
        task_info.save()
        task_id = str(task_info.task_id)
    print("启动漏洞容器成功,任务ID:%s" % (task_id, ))
    return create_stop_container_task(container_vul,user_info)
Ejemplo n.º 20
0
 def create(self, request, *args, **kwargs):
     data_dict = request.data
     user_id = request.user.id
     try:
         net_work_name = data_dict['net_work_name']
     except Exception as e:
         return Response(R.build(msg="网卡名称不能为空"))
     try:
         net_work_subnet = data_dict['net_work_subnet']
     except Exception as e:
         return Response(R.build(msg="子网不能为空"))
     try:
         net_work_gateway = data_dict['net_work_gateway']
     except Exception as e:
         return Response(R.build(msg="网关不能为空"))
     try:
         net_work_scope = data_dict['net_work_scope']
     except Exception as e:
         net_work_scope = 'local'
     try:
         net_work_driver = data_dict['net_work_driver']
     except Exception as e:
         net_work_driver = 'bridge'
     try:
         enable_ipv6 = data_dict['enable_ipv6']
     except Exception as e:
         enable_ipv6 = False
     try:
         rs = NetWorkInfo.objects.filter(net_work_name=net_work_name)
         if len(rs) > 0:
             return Response(R.build(msg="网卡名称不能重复"))
         rs = NetWorkInfo.objects.filter(net_work_subnet=net_work_subnet)
         if len(rs) > 0:
             return Response(R.build(msg="子网不能重复"))
         rs = NetWorkInfo.objects.filter(net_work_gateway=net_work_gateway)
         if len(rs) > 0:
             return Response(R.build(msg="网关不能重复"))
     except Exception as e:
         print(e)
     if not net_work_subnet:
         network_list = client.networks.list()
         for network in network_list:
             network_configs = network.attrs['IPAM']['Config']
             if len(network_configs) > 0:
                 subnet = network_configs[0]['Subnet']
                 net_work_gateway = network_configs[0]['Gateway']
                 if subnet != net_work_subnet:
                     continue
                 net_work_client_id = network.attrs["Id"]
                 net_work_scope = network.attrs["Scope"]
                 net_work_driver = network.attrs["Driver"]
                 enable_ipv6 = network.attrs["EnableIPv6"]
                 break
     else:
         if net_work_subnet == "192.168.10.10/24":
             return JsonResponse(R.err(msg="该网段已在服务器内部使用,请更换网段"))
         if net_work_gateway == "192.168.10.10":
             return JsonResponse(R.err(msg="该网关已在服务器内部使用,请更换网关"))
         try:
             ipam_pool = docker.types.IPAMPool(subnet=net_work_subnet,
                                               gateway=net_work_gateway)
             ipam_config = docker.types.IPAMConfig(pool_configs=[ipam_pool])
             if not net_work_name:
                 return JsonResponse(R.err(msg="网卡名称不能为空"))
             try:
                 net_work = client.networks.create(net_work_name,
                                                   driver=net_work_driver,
                                                   ipam=ipam_config,
                                                   scope=net_work_scope)
             except Exception as e:
                 return JsonResponse(R.err(msg="子网或者网关设置错误"))
             net_work_client_id = str(net_work.id)
             if not net_work_gateway:
                 net_work_gateway = net_work.attrs['IPAM']['Config'][
                     'Gateway']
         except Exception as e:
             traceback.print_exc()
             return JsonResponse(R.err(msg="服务器内部错误"))
     network_info = NetWorkInfo(net_work_id=str(uuid.uuid4()),
                                net_work_client_id=net_work_client_id,
                                create_user=user_id,
                                net_work_name=net_work_name,
                                net_work_driver=net_work_driver,
                                net_work_subnet=net_work_subnet,
                                net_work_gateway=net_work_gateway,
                                net_work_scope=net_work_scope,
                                enable_ipv6=enable_ipv6)
     network_info.save()
     data = NetWorkInfoSerializer(network_info).data
     return JsonResponse(R.ok(data=data))
Ejemplo n.º 21
0
def create_image(task_id):
    """
    创建镜像名称
    """
    task_info = TaskInfo.objects.filter(task_id=task_id, task_status=1).first()
    if not task_info:
        return
    operation_args = task_info.operation_args
    args = json.loads(operation_args)
    image_name = args["image_name"].strip()
    image_info = ImageInfo.objects.filter(image_name=image_name).first()
    if not image_info:
        image_desc = image_name
        image_rank = 2.5
        image_vul_name = image_desc
        image_info = ImageInfo(image_name=image_name, image_desc=image_desc, rank=image_rank, image_vul_name=image_vul_name)
    image = None
    msg = {}
    try:
        image = client.images.get(image_name)
    except Exception as e:
        image_info.is_ok = False
        image_info.save()
        try:
            last_info = {}
            progress_info = {
                "total": 0,
                "progress_count": 0,
                "progress": round(0.0, 2),
            }
            black_list = ["total", "progress_count", "progress"]
            for line in api_docker_client.pull(image_name, stream=True, decode=True):
                if "status" in line and "progressDetail" in line and "id" in line:
                    id = line["id"]
                    status = line["status"]
                    if len(line["progressDetail"]) > 0:
                        try:
                            current = line["progressDetail"]["current"]
                            total = line["progressDetail"]["total"]
                            line["progress"] = round((current / total) * 100, 2)
                            if (current / total) > 1:
                                line["progress"] = round(0.99 * 100, 2)
                        except:
                            line["progress"] = round(1 * 100, 2)
                    else:
                        if (("Download" in status or "Pull" in status) and ("complete" in status)) or ("Verifying" in status) or \
                                ("Layer" in status and "already" in status and "exists" in status):
                            line["progress"] = round(100.00, 2)
                        else:
                            line["progress"] = round(0.00, 2)
                    progress_info[id] = line
                    progress_info["total"] = len(progress_info) - len(black_list)
                    progress_count = 0
                    for key in progress_info:
                        if key in black_list:
                            continue
                        if 100.00 != progress_info[key]["progress"]:
                            continue
                        progress_count += 1
                    progress_info["progress_count"] = progress_count
                    progress_info["progress"] = round((progress_count/progress_info["total"])*100, 2)
                    r.set(str(task_id), json.dumps(progress_info,ensure_ascii=False))
                    print(json.dumps(progress_info, ensure_ascii=False))
                last_info = line
            if "status" in last_info and ("Downloaded newer image for" in last_info["status"] or "Image is up to date for" in last_info["status"]):
                image = client.images.get(image_name)
            else:
                raise Exception
        except ImageNotFound:
            msg = R.build(msg="%s 不存在" % (image_name,))
        except Exception:
            traceback.print_exc()
            msg = R.err(msg="%s 添加失败" % (image_name,))
    if image:
        config = image.attrs["ContainerConfig"]
        port_list = []
        if "ExposedPorts" in config:
            port_list = config["ExposedPorts"]
        ports = []
        for port in port_list:
            port = port.replace("/", "").replace("tcp", "").replace("udp", "")
            ports.append(port)
        image_port = ",".join(ports)
        image_info.image_port = image_port
        image_info.is_ok = True
        image_info.save()
        msg = R.ok(msg="%s 添加成功" % (image_name,), data=json.dumps({"image_port": image_port}))
        task_info.task_status = 3
    else:
        task_info.task_status = 4
    task_info.task_msg = json.dumps(msg)
    task_info.save()
Ejemplo n.º 22
0
 def run_layout(self, request, pk=None):
     if not pk or pk == "undefined":
         return JsonResponse(R.build(msg="环境不存在"))
     """
     运行环境
     """
     user = request.user
     if not user.is_superuser:
         return JsonResponse(R.build(msg="权限不足"))
     layout_info = Layout.objects.filter(layout_id=pk,
                                         is_release=True).first()
     if not layout_info:
         return JsonResponse(R.build(msg="环境不存在或未发布"))
     yml_content = layout_info.yml_content
     env_content = layout_info.env_content
     layout_id = str(layout_info.layout_id)
     layout_path = os.path.join(DOCKER_COMPOSE, layout_id)
     try:
         env_content = get_random_port(env_content)
     except Exception as e:
         return JsonResponse(R.build(msg=str(e)))
     open_host_list = []
     raw_con = json.loads(layout_info.raw_content)
     network_list = client.networks.list()
     net_list = []
     network_names = [
         item['attrs']['name'] for item in raw_con['nodes']
         if item['name'] == "Network"
     ]
     for i in network_list:
         net_list.append(i.attrs['Name'])
     for network_name in network_names:
         if network_name in net_list:
             pass
         else:
             try:
                 network_det = NetWorkInfo.objects.filter(
                     net_work_name=network_name).first()
                 ipam_pool = docker.types.IPAMPool(
                     subnet=network_det.net_work_subnet,
                     gateway=network_det.net_work_gateway)
                 ipam_config = docker.types.IPAMConfig(
                     pool_configs=[ipam_pool])
                 net_work = client.networks.create(
                     network_det.net_work_name,
                     driver=network_det.net_work_driver,
                     ipam=ipam_config,
                     scope=network_det.net_work_scope)
                 net_work_client_id = str(net_work.id)
                 if not network_det.net_work_gateway:
                     net_work_gateway = net_work.attrs['IPAM']['Config'][
                         'Gateway']
                     network_det.net_work_gateway = net_work_gateway
                 network_det.net_work_client_id = net_work_client_id
                 network_det.save()
             except Exception as e:
                 return JsonResponse(R.build(msg=str(e)))
     try:
         with transaction.atomic():
             _tmp_file_path = "docker-compose" + layout_path.replace(
                 DOCKER_COMPOSE, "")
             layout_data = LayoutData.objects.filter(
                 layout_id=layout_info, file_path=_tmp_file_path).first()
             if not layout_data:
                 layout_data = LayoutData(
                     layout_user_id=uuid.uuid4(),
                     create_user_id=user.id,
                     layout_id=layout_info,
                     status="running",
                     file_path="docker-compose" +
                     layout_path.replace(DOCKER_COMPOSE, ""),
                     create_date=timezone.now(),
                     update_date=timezone.now())
             else:
                 layout_data.status = "running"
             if not os.path.exists(layout_path):
                 os.makedirs(layout_path)
             docker_compose_file = os.path.join(layout_path,
                                                "docker-compose.yml")
             with open(docker_compose_file, "w", encoding="utf-8") as f:
                 f.write(yml_content)
             env_file = os.path.join(layout_path, ".env")
             with open(env_file, "w", encoding="utf-8") as f:
                 f.write("\n".join(env_content))
             # 启动
             container_list = get_project(layout_path).up()
             # 保存
             layout_data.save()
             for container in container_list:
                 docker_container_id = container.id
                 service_id = container.service
                 container_host = ""
                 container_port = ""
                 container_flag = "flag-{bmh%s}" % (uuid.uuid4(), )
                 docker_container = client.containers.get(container.id)
                 service_info = LayoutService.objects.filter(
                     service_name=service_id,
                     layout_id=layout_info).first()
                 if not service_info:
                     raise Exception("环境服务不存在")
                 image_info = service_info.image_id
                 service_container = LayoutServiceContainer.objects.filter(
                     service_id=service_info,
                     user_id=user.id,
                     layout_user_id=layout_data,
                     image_id=image_info).first()
                 if not service_container:
                     service_container = LayoutServiceContainer(
                         service_container_id=uuid.uuid4(),
                         user_id=user.id,
                         service_id=service_info,
                         layout_user_id=layout_data,
                         image_id=image_info,
                         container_flag=container_flag,
                         create_date=timezone.now())
                 else:
                     container_flag = service_container.container_flag
                 """
                 写入 flag
                 """
                 command = 'touch /tmp/%s' % (container_flag, )
                 execute_result = tasks.docker_container_run(
                     docker_container, command)
                 if execute_result["status"] == 500:
                     raise Exception(execute_result["msg"])
                 container_ports = container.ports
                 if len(container_ports) == 0:
                     try:
                         container_ports = docker_container.attrs[
                             "NetworkSettings"]["Ports"]
                     except Exception as e:
                         pass
                 vul_host_list = []
                 if service_info.is_exposed:
                     vul_ip = tasks.get_local_ip()
                 else:
                     vul_ip = "127.0.0.1"
                 port_dict = {}
                 if len(container_ports) > 0:
                     for _tmp_port in container_ports:
                         source_port = str(_tmp_port).replace(
                             "/", "").replace("tcp", "").replace("udp", "")
                         if container_ports[_tmp_port]:
                             target_port = container_ports[_tmp_port][0][
                                 "HostPort"]
                         else:
                             target_port = source_port
                         port_dict[source_port] = target_port
                         vul_host_list.append(vul_ip + ":" + target_port)
                 if len(vul_host_list) > 0:
                     container_host = ",".join(vul_host_list)
                     if service_info.is_exposed:
                         open_host_list.extend(vul_host_list)
                 if len(port_dict) > 0:
                     container_port = json.dumps(port_dict,
                                                 ensure_ascii=False)
                 # 连接 host
                 service_container.container_host = container_host
                 # 连接 端口
                 service_container.container_port = container_port
                 container_status = execute_result["data"]["status"]
                 service_container.docker_container_id = docker_container_id
                 service_container.container_status = container_status
                 service_container.update_date = timezone.now()
                 service_container.save()
     except Exception as e:
         traceback.print_exc()
         return JsonResponse(R.build(msg=str(e)))
     result_data = {
         "layout": {
             "name": layout_info.layout_name,
             "desc": layout_info.layout_desc,
         },
         "open": open_host_list
     }
     request_ip = get_request_ip(request)
     sys_log = SysLog(user_id=user.id,
                      operation_type="编排环境",
                      operation_name="启动",
                      operation_value=layout_info.layout_name,
                      operation_args=json.dumps(
                          LayoutSerializer(layout_info).data),
                      ip=request_ip)
     sys_log.save()
     return JsonResponse(R.ok(data=result_data))
Ejemplo n.º 23
0
def share_image(task_id):
    """
    贡献镜像
    :param task_id: 任务 id
    :return:
    """
    task_info = TaskInfo.objects.filter(task_id=task_id, task_status=1).first()
    operation_args = task_info.operation_args
    args = json.loads(operation_args)
    share_username = args["share_username"].strip()
    image_name = args["image_name"].strip()
    username = args["username"].strip()
    password = args["pwd"].strip()
    msg = R.ok(msg="分享成功")
    try:
        client.login(username, password)
        new_image_name = image_name.split(":")[0]+":"+share_username
        if new_image_name.rfind("/") > -1:
            r_image_info = new_image_name[:new_image_name.rfind("/")]
            if r_image_info.rfind("/") > -1:
                repo_tmp = r_image_info[:r_image_info.rfind("/")]
                repo_name = "/".join([repo_tmp, username, new_image_name[new_image_name.rfind("/")+1:]])
            else:
                repo_name = "/".join([username, new_image_name[new_image_name.rfind("/")+1:]])
        else:
            repo_name = "/".join([username, new_image_name])
        new_image_name = repo_name
        tag_flag = api_docker_client.tag(image_name, new_image_name)
        if tag_flag:
            last_info = {}
            progress_info = {
                "total": 0,
                "progress_count": 0,
                "progress": round(0.0, 2),
            }
            black_list = ["total", "progress_count", "progress"]
            for line in api_docker_client.push(new_image_name, stream=True, decode=True, auth_config={"username": username, "password": password}):
                if "status" in line and "progressDetail" in line and "id" in line:
                    id = line["id"]
                    status = line["status"]
                    if len(line["progressDetail"]) > 0:
                        try:
                            current = line["progressDetail"]["current"]
                            total = line["progressDetail"]["total"]
                            line["progress"] = round((current / total) * 100, 2)
                            if (current / total) > 1:
                                line["progress"] = round(0.99 * 100, 2)
                        except:
                            line["progress"] = round(1 * 100, 2)
                    else:
                        if ("Pushed" in status) or ("Verifying" in status) or \
                                ("Layer" in status and "already" in status and "exists" in status) or ("Mounted" in status and "from" in status):
                            line["progress"] = round(100.00, 2)
                        else:
                            line["progress"] = round(0.00, 2)
                    progress_info[id] = line
                    progress_info["total"] = len(progress_info) - len(black_list)
                    progress_count = 0
                    for key in progress_info:
                        if key in black_list:
                            continue
                        if 100.00 != progress_info[key]["progress"]:
                            continue
                        progress_count += 1
                    progress_info["progress_count"] = progress_count
                    progress_info["progress"] = round((progress_count/progress_info["total"])*100, 2)
                    r.set(str(task_id), json.dumps(progress_info,ensure_ascii=False))
                    print(json.dumps(progress_info, ensure_ascii=False))
                last_info = line
            # print("last_info")
            # print("==========================")
            # print(json.dumps(last_info, ensure_ascii=False))
            if "error" in last_info and last_info["error"]:
                task_info.task_msg = R.build(msg="原%s构建新镜像%s失败,错误信息:%s" % (image_name, new_image_name, str(last_info["error"]),))
                task_info.task_status = 4
            elif "progressDetail" in last_info and "aux" in last_info and share_username in last_info["aux"]["Tag"]:
                image_info = ImageInfo.objects.filter(image_name=image_name).first()
                if image_info:
                    image_info.is_share = True
                    image_info.save()
                msg = R.ok(msg="%s 分享成功" % (image_name,))
            else:
                msg = R.build(msg="%s 分享失败" % (image_name,))
        else:
            task_info.task_msg = R.build(msg="原%s构建新镜像%s失败" % (image_name, new_image_name,))
            task_info.task_status = 4
    except docker.errors.APIError as api_error:
        msg = R.build(msg="Dockerhub 用户名或 Dockerhub Token 错误")
        task_info.task_status = 4
    except Exception as e:
        msg = R.build(msg="%s 分享失败,错误信息:%s" % (image_name, str(e),))
        task_info.task_status = 4
    task_info.task_status = 3
    task_info.task_msg = json.dumps(msg)
    task_info.save()
Ejemplo n.º 24
0
 def create(self, request, *args, **kwargs):
     """
     创建编排环境信息
     """
     user = request.user
     if user.is_superuser:
         data = request.POST.get("data", "")
         id = request.POST.get("id", "")
         name = request.POST.get("name", "")
         if not name:
             return JsonResponse(R.build(msg="名称不能为空"))
         desc = request.POST.get("desc", "")
         img = request.POST.get("img", "")
         if not data:
             return JsonResponse(R.build(msg="参数不能为空"))
         topo_data = json.loads(data)
         if topo_data == {}:
             return JsonResponse(R.build(msg="编排环境不能为空"))
         nodes = topo_data["nodes"]
         if not nodes or len(nodes) == 0:
             return JsonResponse(R.build(msg="节点不能为空"))
         connectors = topo_data["connectors"]
         check_open = False
         container_list = []
         network_dict = {}
         check_network_name_list = []
         for node in nodes:
             node_id = node["id"]
             node_type = node["type"]
             node_attrs = node["attrs"]
             if len(node_attrs) == 0:
                 return JsonResponse(R.build(msg="节点属性不能为空"))
             if node_type == "Container":
                 node_open = node_attrs["open"]
                 node_port = node_attrs["port"]
                 if node_open and node_port:
                     check_open = True
                 container_list.append(node)
             elif node_type == "Network":
                 network_name = node_attrs["name"]
                 if not network_name:
                     return JsonResponse(R.build(msg="网卡不能为空"))
                 if network_name in check_network_name_list:
                     return JsonResponse(R.build(msg="不能重复设置网卡"))
                 check_network_name_list.append(network_name)
                 network_dict[node_id] = node
             if node_attrs == {}:
                 return JsonResponse(R.build(msg="网卡或容器属性不能为空"))
         if not check_open:
             return JsonResponse(R.build(msg="请开放可访问入口"))
         if len(container_list) == 0:
             return JsonResponse(R.build(msg="容器环境不能为空"))
         if len(network_dict) == 0:
             for container in container_list:
                 if not container["attrs"]["open"]:
                     return JsonResponse(
                         R.build(msg="在不配置网卡段情况下请保证所有的环境开放访问权限"))
         else:
             if not connectors or len(connectors) == 0:
                 return JsonResponse(R.build(msg="在配置网卡的情况下连接点不能为空"))
         try:
             yml_content = build_yml(container_list=container_list,
                                     network_dict=network_dict,
                                     connector_list=connectors)
             yml_data = yml_content["content"]
             env_data = yml_content["env"]
             env_content = ""
             if len(env_data) > 0:
                 env_content = "\n".join(env_data)
             with transaction.atomic():
                 operation_name = "创建"
                 if id:
                     layout = Layout.objects.filter(layout_id=id).first()
                     operation_name = "修改"
                 else:
                     layout = Layout(layout_id=uuid.uuid4(),
                                     create_date=timezone.now(),
                                     update_date=timezone.now())
                 layout_data = LayoutData.objects.filter(
                     layout_id=layout).first()
                 if layout_data and layout_data.status == 'running':
                     return JsonResponse(R.build(msg="环境正在运行中,请首先停止运行"))
                 layout.layout_name = name
                 layout.layout_desc = desc
                 layout.create_user_id = user.id
                 layout.image_name = img
                 layout.raw_content = json.dumps(topo_data,
                                                 ensure_ascii=False)
                 layout.yml_content = yaml.dump(yml_content["content"])
                 layout.env_content = env_content
                 # 保存到数据库中
                 layout.save()
                 # 删除相关原有的服务数据
                 layout_service_list = list(
                     LayoutService.objects.filter(
                         layout_id=layout).values("service_id"))
                 # 删除网卡相关数据
                 services = yml_data["services"]
                 for service_name in services:
                     service = services[service_name]
                     image = service["image"]
                     image_info = ImageInfo.objects.filter(
                         image_name=image).first()
                     if not image_info:
                         return JsonResponse(
                             R.build(msg="%s 镜像不存在" % (image, )))
                     is_exposed = False
                     ports = ""
                     if "ports" in service and len(service["ports"]) > 0:
                         is_exposed = True
                     if image_info.image_port:
                         ports = ",".join(
                             str(image_info.image_port).split(","))
                     layout_service = LayoutService.objects.filter(
                         layout_id=layout,
                         service_name=service_name).first()
                     if not layout_service:
                         layout_service = LayoutService(
                             service_id=uuid.uuid4(),
                             layout_id=layout,
                             service_name=service_name,
                             create_date=timezone.now(),
                             update_date=timezone.now())
                     if {
                             "service_id": layout_service.service_id
                     } in layout_service_list:
                         layout_service_list.remove(
                             {"service_id": layout_service.service_id})
                     layout_service.image_id = image_info
                     layout_service.service_name = service_name
                     layout_service.is_exposed = is_exposed
                     layout_service.exposed_source_port = ports
                     layout_service.save()
                     if "networks" not in service:
                         continue
                     networks = service["networks"]
                     service_network_list = list(
                         LayoutServiceNetwork.objects.filter(
                             service_id=layout_service).values(
                                 'layout_service_network_id'))
                     for network in networks:
                         network_info = NetWorkInfo.objects.filter(
                             net_work_name=network).first()
                         if not network_info:
                             return JsonResponse(
                                 R.build(msg="%s 网卡不存在" % (network, )))
                         service_network = LayoutServiceNetwork.objects.filter(
                             service_id=layout_service,
                             network_id=network_info,
                         ).first()
                         if not service_network:
                             service_network = LayoutServiceNetwork(
                                 layout_service_network_id=uuid.uuid4(),
                                 service_id=layout_service,
                                 network_id=network_info,
                                 create_date=timezone.now(),
                                 update_date=timezone.now())
                         if {
                                 "layout_service_network_id":
                                 service_network.layout_service_network_id
                         } in service_network_list:
                             service_network_list.remove({
                                 "layout_service_network_id":
                                 service_network.layout_service_network_id
                             })
                         service_network.save()
                     # 删除已经不存在的网卡
                     if len(service_network_list) > 0:
                         for service_network in service_network_list:
                             LayoutServiceNetwork.objects.filter(
                                 layout_service_network_id=service_network[
                                     'layout_service_network_id']).delete()
                 # 删除服务数据
                 for layout_service in layout_service_list:
                     service_id = layout_service['service_id']
                     # 删除服务数据
                     LayoutService.objects.filter(
                         service_id=service_id, layout_id=layout).delete()
                     if layout_data:
                         # 删除启动容器
                         LayoutServiceContainer.objects.filter(service_id=service_id, layout_user_id=layout_data). \
                             delete()
                         # 删除分数
                         LayoutServiceContainerScore.objects.filter(
                             layout_id=layout,
                             layout_data_id=layout_data,
                             service_id=service_id).delete()
                     else:
                         # 删除启动容器
                         LayoutServiceContainer.objects.filter(
                             service_id=service_id).delete()
                         # 删除分数
                         LayoutServiceContainerScore.objects.filter(
                             layout_id=layout,
                             service_id=service_id).delete()
                 request_ip = get_request_ip(request)
                 sys_log = SysLog(user_id=user.id,
                                  operation_type="编排环境",
                                  operation_name=operation_name,
                                  operation_value=name,
                                  operation_args=json.dumps(
                                      LayoutSerializer(layout).data),
                                  ip=request_ip)
                 sys_log.save()
         except Exception as e:
             return JsonResponse(R.err(msg="服务器内部错误,请联系管理员"))
         return JsonResponse(R.ok())
     else:
         return JsonResponse(R.build(msg="权限不足"))