Beispiel #1
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())
Beispiel #2
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())
Beispiel #3
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())
Beispiel #4
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="权限不足"))
Beispiel #5
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))