class RegionInfo(BaseOpenAPIView): @swagger_auto_schema( operation_description="获取指定数据中心数据", responses={ status.HTTP_200_OK: RegionInfoSerializer(), status.HTTP_404_NOT_FOUND: FailSerializer(), }, tags=['openapi-region'], ) def get(self, request, region_id): try: queryset = region_services.get_region_by_region_id(region_id) serializer = RegionInfoSerializer(queryset) return Response(serializer.data) except RegionConfig.DoesNotExist: return Response({"msg": "数据中心不存在"}, status=status.HTTP_404_NOT_FOUND) @swagger_auto_schema( operation_description="更新指定数据中心元数据", request_body=UpdateRegionReqSerializer(), responses={ 200: RegionInfoSerializer(), 400: FailSerializer(), 404: FailSerializer(), }, tags=['openapi-region'], ) def put(self, request, region_id): serializer = UpdateRegionReqSerializer(data=request.data) serializer.is_valid(raise_exception=True) region_data = serializer.data if not region_id: return Response({"msg": "RegionID不能为空"}, status=status.HTTP_400_BAD_REQUEST) try: region_services.get_region_by_region_id(region_id) except RegionConfig.DoesNotExist: # TODO: raise exception or return Response return Response({"msg": "修改的数据中心不存在"}, status=status.HTTP_404_NOT_FOUND) region_data["region_id"] = region_id new_region = region_services.update_region(region_data) serializer = RegionInfoSerializer(new_region) return Response(serializer.data, status.HTTP_200_OK) @swagger_auto_schema( operation_description="删除指定数据中心元数据", responses={ 200: RegionInfoSerializer(), 404: FailSerializer(), }, tags=['openapi-region'], ) def delete(self, request, region_id): try: region = region_services.del_by_region_id(region_id) serializer = RegionInfoSerializer(data=region) serializer.is_valid(raise_exception=True) return Response(serializer.data, status.HTTP_200_OK) except RegionConfig.DoesNotExist: # TODO: raise exception or return Response return Response({"msg": "修改的数据中心不存在"}, status=status.HTTP_404_NOT_FOUND)
class TokenInfoView(APIView): authentication_classes = [] permission_classes = [] @swagger_auto_schema(responses={ 200: TokenSerializer(), status.HTTP_400_BAD_REQUEST: FailSerializer(), status.HTTP_404_NOT_FOUND: FailSerializer(), }, request_body=openapi.Schema( title="AuthRequest", type=openapi.TYPE_OBJECT, required=['username', 'password'], properties={ 'username': openapi.Schema(type=openapi.TYPE_STRING, description="管理员用户名"), 'password': openapi.Schema(type=openapi.TYPE_STRING, description="管理员密码"), }, ), tags=['openapi-auth'], operation_description="企业管理员账号密码获取API-Token") def post(self, request): username = request.data.get("username", None) password = request.data.get("password", None) if not username or not password: return Response({"msg": "用户名或密码不能为空"}, status=status.HTTP_400_BAD_REQUEST) token = apiUserService.login_api_user(username, password) if token: return Response({"token": token}, status=status.HTTP_200_OK) return Response({"msg": "用户名或密码错误或用户不是管理员用户"}, status=status.HTTP_400_BAD_REQUEST)
class RegionStatusView(BaseOpenAPIView): @swagger_auto_schema( operation_description="修改数据中心的状态(上线, 下线, 设为维护)", request_body=UpdateRegionStatusReqSerializer(), responses={ status.HTTP_200_OK: RegionInfoSerializer(), status.HTTP_404_NOT_FOUND: FailSerializer(), status.HTTP_400_BAD_REQUEST: FailSerializer(), }, tags=['openapi-region'], ) def put(self, req, region_id): serializer = UpdateRegionStatusReqSerializer(data=req.data) serializer.is_valid(raise_exception=True) try: region = region_services.update_region_status(region_id, req.data["status"]) serializer = RegionInfoSerializer(region) return Response(serializer.data, status.HTTP_200_OK) except RegionConfig.DoesNotExist: fs = FailSerializer({"msg": "数据中心不存在"}) return Response(fs.data, status.HTTP_404_NOT_FOUND) except RegionUnreachableError as e: fs = FailSerializer({"msg": e.message}) return Response(fs.data, status.HTTP_400_BAD_REQUEST)
class TeamUserInfoView(TeamAPIView): @swagger_auto_schema( operation_description="将用户从团队中移除", responses={ status.HTTP_404_NOT_FOUND: FailSerializer(), }, tags=['openapi-team'], ) def delete(self, req, team_id, user_id): if req.user.user_id == user_id: raise serializers.ValidationError("不能删除自己", status.HTTP_400_BAD_REQUEST) try: user_services.get_user_by_tenant_id(team_id, user_id) user_services.batch_delete_users(team_id, [user_id]) return Response(None, status.HTTP_200_OK) except UserNotExistError as e: return Response({"msg": e.message}, status.HTTP_404_NOT_FOUND) except Tenants.DoesNotExist: return Response({"msg": "团队不存在"}, status.HTTP_404_NOT_FOUND) @swagger_auto_schema( operation_description="add team user", request_body=CreateTeamUserReqSerializer(), responses={}, tags=['openapi-team'], ) def post(self, req, team_id, user_id): serializer = CreateTeamUserReqSerializer(data=req.data) serializer.is_valid(raise_exception=True) role_ids = req.data["role_ids"].replace(" ", "").split(",") team_services.add_user_role_to_team(tenant=self.team, user_ids=[user_id], role_ids=role_ids) return Response(None, status.HTTP_201_CREATED) @swagger_auto_schema( operation_description="update team user", request_body=CreateTeamUserReqSerializer(), responses={ status.HTTP_404_NOT_FOUND: FailSerializer(), }, tags=['openapi-team'], ) # TODO 修改权限控制 def put(self, req, team_id, user_id): if req.user.user_id == user_id: raise serializers.ValidationError("您不能修改自己的权限!", status.HTTP_400_BAD_REQUEST) serializer = CreateTeamUserReqSerializer(data=req.data) serializer.is_valid(raise_exception=True) role_ids = req.data["role_ids"].replace(" ", "").split(",") user = user_repo.get_by_user_id(user_id) user_kind_role_service.update_user_roles(kind="team", kind_id=self.team.tenant_id, user=user, role_ids=role_ids) return Response(None, status.HTTP_200_OK)
def put(self, req, region_id): serializer = UpdateRegionStatusReqSerializer(data=req.data) serializer.is_valid(raise_exception=True) try: region = region_services.update_region_status(region_id, req.data["status"]) serializer = RegionInfoSerializer(region) return Response(serializer.data, status.HTTP_200_OK) except RegionConfig.DoesNotExist: fs = FailSerializer({"msg": "数据中心不存在"}) return Response(fs.data, status.HTTP_404_NOT_FOUND) except RegionUnreachableError as e: fs = FailSerializer({"msg": e.message}) return Response(fs.data, status.HTTP_400_BAD_REQUEST)
def post(self, request, app_id, *args, **kwargs): sos = ServiceGroupOperationsSerializer(data=request.data) sos.is_valid(raise_exception=True) app = group_service.get_app_by_id(self.team, self.region_name, app_id) if not app: raise ErrAppNotFound service_ids = sos.data.get("service_ids", None) if not service_ids or len(service_ids) == 0: service_ids = app_service.get_group_services_by_id(app_id) # TODO: Check the amount of resources used action = sos.data.get("action") if action == "stop": self.has_perms([300006, 400008]) if action == "start": self.has_perms([300005, 400006]) if action == "upgrade": self.has_perms([300007, 400009]) if action == "deploy": self.has_perms([300008, 400010]) code, msg = app_manage_service.batch_operations(self.team, request.user, action, service_ids, None) if code != 200: result = {"msg": "batch operation error"} rst_serializer = FailSerializer(data=result) rst_serializer.is_valid() return Response(rst_serializer.data, status=status.HTTP_400_BAD_REQUEST) else: result = {"msg": msg} rst_serializer = SuccessSerializer(data=result) rst_serializer.is_valid() return Response(rst_serializer.data, status=status.HTTP_200_OK)
def post(self, request, *args, **kwargs): serializer = MarketInstallSerializer(data=request.data) serializer.is_valid(raise_exception=True) data = serializer.data logger.info(data) app = group_service.get_app_by_id(data["app_id"]) if not app: return Response(FailSerializer( {"msg": "install target app not found"}), status=status.HTTP_400_BAD_REQUEST) tenant = team_services.get_team_by_team_id(app.tenant_id) # TODO: get app info by order id token = market_sycn_service.get_enterprise_access_token( tenant.enterprise_id, "market") if token: market_client = get_market_client(token.access_id, token.access_token, token.access_url) app_version = market_client.download_app_by_order( order_id=data["order_id"]) if not app_version: return Response(FailSerializer( {"msg": "download app metadata failure"}), status=status.HTTP_400_BAD_REQUEST) rainbond_app, rainbond_app_version = market_app_service.conversion_cloud_version_to_app( app_version) market_app_service.install_service(tenant, app.region_name, request.user, app.ID, rainbond_app, rainbond_app_version, True, True) services = group_service.get_group_services(data["app_id"]) appInfo = model_to_dict(app) appInfo["enterprise_id"] = tenant.enterprise_id appInfo["service_list"] = ServiceBaseInfoSerializer(services, many=True).data reapp = AppInfoSerializer(data=appInfo) reapp.is_valid() return Response(reapp.data, status=status.HTTP_200_OK) else: return Response(FailSerializer( {"msg": "not support install from market, not bound"}), status=status.HTTP_400_BAD_REQUEST)
class AdminInfoView(BaseOpenAPIView): @swagger_auto_schema( operation_description="删除企业管理员", responses={ status.HTTP_400_BAD_REQUEST: FailSerializer(), status.HTTP_404_NOT_FOUND: FailSerializer(), }, tags=['openapi-user'], ) def delete(self, req, user_id, *args, **kwargs): if str(req.user.user_id) == user_id: raise serializers.ValidationError({"msg": "不能删除自己"}, status.HTTP_400_BAD_REQUEST) try: user_services.delete_admin_user(user_id) return Response(None, status.HTTP_200_OK) except ErrAdminUserDoesNotExist as e: raise exceptions.NotFound(detail="用户'{}'不是企业管理员".format(user_id)) except ErrCannotDelLastAdminUser as e: raise serializers.ValidationError({"msg": e.message}, status.HTTP_400_BAD_REQUEST)
class ListRegionInfo(BaseOpenAPIView): view_perms = ["regions"] @swagger_auto_schema( responses={200: RegionInfoRespSerializer(many=True)}, tags=['openapi-region'], operation_description="获取全部数据中心列表") def get(self, req): regions = region_services.get_enterprise_regions(self.enterprise.enterprise_id, level="") serializer = RegionInfoRespSerializer(data=regions, many=True) serializer.is_valid(raise_exception=True) return Response(serializer.data) @swagger_auto_schema( operation_description="添加数据中心", request_body=openapi.Schema( title="AddRegionRequest", type=openapi.TYPE_OBJECT, required=['region_name', 'region_alias', 'url', 'wsurl', 'httpdomain', 'tcpdomain'], properties={ 'region_name': openapi.Schema(type=openapi.TYPE_STRING), 'region_alias': openapi.Schema(type=openapi.TYPE_STRING), 'url': openapi.Schema(type=openapi.TYPE_STRING), 'wsurl': openapi.Schema(type=openapi.TYPE_STRING), 'httpdomain': openapi.Schema(type=openapi.TYPE_STRING), 'tcpdomain': openapi.Schema(type=openapi.TYPE_STRING), 'scope': openapi.Schema(type=openapi.TYPE_STRING), 'ssl_ca_cert': openapi.Schema(type=openapi.TYPE_STRING), 'cert_file': openapi.Schema(type=openapi.TYPE_STRING), 'key_file': openapi.Schema(type=openapi.TYPE_STRING), 'status': openapi.Schema(type=openapi.TYPE_INTEGER), 'desc': openapi.Schema(type=openapi.TYPE_STRING), }, ), responses={ status.HTTP_201_CREATED: RegionInfoSerializer(), status.HTTP_500_INTERNAL_SERVER_ERROR: None, status.HTTP_400_BAD_REQUEST: FailSerializer(), }, tags=['openapi-region'], ) def post(self, request): try: serializer = RegionInfoSerializer(data=request.data) serializer.is_valid(raise_exception=True) region_data = serializer.data region_data["region_id"] = make_uuid() region = region_services.add_region(region_data) serializer = RegionInfoSerializer(region) if region: return Response(serializer.data, status=status.HTTP_201_CREATED) else: return Response(None, status=status.HTTP_500_INTERNAL_SERVER_ERROR) except RegionExistException as e: logger.exception(e) return Response({"msg": e.message}, status=status.HTTP_400_BAD_REQUEST)
def post(self, request, *args, **kwargs): serializer = AppPostInfoSerializer(data=request.data) serializer.is_valid(raise_exception=True) data = serializer.data logger.info(data["team_alias"]) tenant = team_services.get_tenant_by_tenant_name(data["team_alias"]) if not tenant: raise serializers.ValidationError("指定租户不存在") if not region_services.verify_team_region( team_name=data["team_alias"], region_name=data["region_name"]): raise serializers.ValidationError("指定数据中心租户未开通") code, msg, group_info = group_service.add_group( tenant, data["region_name"], data["app_name"]) if not group_info: return Response(FailSerializer({"msg": msg}).data, status=code) re = AppBaseInfoSerializer(group_info) return Response(re.data, status=status.HTTP_201_CREATED)
class AppStoreInfoView(BaseOpenAPIView): @swagger_auto_schema( operation_description="修改应用市场信息", request_body=UpdAppStoreInfoReqSerializer(), responses={ status.HTTP_200_OK: AppStoreInfoSerializer(), status.HTTP_404_NOT_FOUND: FailSerializer(), }, tags=['openapi-appstore'], ) def put(self, req, eid): serializer = UpdAppStoreInfoReqSerializer(data=req.data) serializer.is_valid(raise_exception=True) if enterprise_services.get_enterprise_by_id(eid) is None: raise exceptions.NotFound({"msg": "企业'{}'不存在".format(eid)}) try: res = enterprise_services.update_appstore_info(eid, req.data) except TenantEnterpriseToken: raise exceptions.NotFound({"msg": "应用市场信息不存在 {}".format(eid)}) serializer = AppStoreInfoSerializer(res) return Response(serializer.data, status=status.HTTP_200_OK)
class ListRegionInfo(ListAPIView): view_perms = ["regions"] @swagger_auto_schema( manual_parameters=[ openapi.Parameter("query", openapi.IN_QUERY, description="根据数据中心名称搜索", type=openapi.TYPE_STRING), openapi.Parameter("current", openapi.IN_QUERY, description="页码", type=openapi.TYPE_STRING), openapi.Parameter("pageSize", openapi.IN_QUERY, description="每页数量", type=openapi.TYPE_STRING), ], responses={200: ListRegionsRespSerializer()}, tags=['openapi-region'], operation_description="获取全部数据中心列表") def get(self, req): query = req.GET.get("query", "") try: page = int(req.GET.get("current", 1)) except ValueError: page = 1 try: page_size = int(req.GET.get("pageSize", 99)) except ValueError: page_size = 99 regions, total = region_services.get_regions_with_resource(query, page, page_size) serializer = ListRegionsRespSerializer(data={"data": regions, "total": total}) serializer.is_valid(raise_exception=True) return Response(serializer.data) @swagger_auto_schema( operation_description="添加数据中心", request_body=openapi.Schema( title="AddRegionRequest", type=openapi.TYPE_OBJECT, required=['region_name', 'region_alias', 'url', 'wsurl', 'httpdomain', 'tcpdomain'], properties={ 'region_name': openapi.Schema(type=openapi.TYPE_STRING), 'region_alias': openapi.Schema(type=openapi.TYPE_STRING), 'url': openapi.Schema(type=openapi.TYPE_STRING), 'wsurl': openapi.Schema(type=openapi.TYPE_STRING), 'httpdomain': openapi.Schema(type=openapi.TYPE_STRING), 'tcpdomain': openapi.Schema(type=openapi.TYPE_STRING), 'scope': openapi.Schema(type=openapi.TYPE_STRING), 'ssl_ca_cert': openapi.Schema(type=openapi.TYPE_STRING), 'cert_file': openapi.Schema(type=openapi.TYPE_STRING), 'key_file': openapi.Schema(type=openapi.TYPE_STRING), 'status': openapi.Schema(type=openapi.TYPE_INTEGER), 'desc': openapi.Schema(type=openapi.TYPE_STRING), }, ), responses={ status.HTTP_201_CREATED: RegionInfoSerializer(), status.HTTP_500_INTERNAL_SERVER_ERROR: None, status.HTTP_400_BAD_REQUEST: FailSerializer(), }, tags=['openapi-region'], ) def post(self, request): try: serializer = RegionInfoSerializer(data=request.data) serializer.is_valid(raise_exception=True) region_data = serializer.data region_data["region_id"] = make_uuid() region = region_services.add_region(region_data) serializer = RegionInfoSerializer(region) if region: return Response(serializer.data, status=status.HTTP_201_CREATED) else: return Response(None, status=status.HTTP_500_INTERNAL_SERVER_ERROR) except RegionExistException as e: logger.exception(e) return Response({"msg": e.message}, status=status.HTTP_400_BAD_REQUEST)
class TeamUserInfoView(BaseOpenAPIView): @swagger_auto_schema( operation_description="将用户从团队中移除", responses={ status.HTTP_200_OK: None, status.HTTP_404_NOT_FOUND: FailSerializer(), status.HTTP_500_INTERNAL_SERVER_ERROR: None }, tags=['openapi-team'], ) def delete(self, req, team_id, user_id): if req.user.user_id == user_id: raise serializers.ValidationError("不能删除自己", status.HTTP_400_BAD_REQUEST) try: user_services.get_user_by_tenant_id(team_id, user_id) user_services.batch_delete_users(team_id, [user_id]) return Response(None, status.HTTP_200_OK) except UserNotExistError as e: return Response({"msg": e.message}, status.HTTP_404_NOT_FOUND) except Tenants.DoesNotExist: return Response({"msg": "团队不存在"}, status.HTTP_404_NOT_FOUND) @swagger_auto_schema( operation_description="add team user", request_body=CreateTeamUserReqSerializer(), responses={ status.HTTP_201_CREATED: None, status.HTTP_500_INTERNAL_SERVER_ERROR: None, status.HTTP_400_BAD_REQUEST: None, }, tags=['openapi-team'], ) def post(self, req, team_id, user_id): serializer = CreateTeamUserReqSerializer(data=req.data) serializer.is_valid(raise_exception=True) try: team = team_services.get_team_by_team_id(team_id) except Tenants.DoesNotExist: raise exceptions.NotFound() role_ids = req.data["role_ids"].replace(" ", "").split(",") roleids = team_services.get_all_team_role_id(tenant_name=team_id, allow_owner=True) for role_id in role_ids: if int(role_id) not in roleids: raise serializers.ValidationError("角色{}不存在".format(role_id), status.HTTP_404_NOT_FOUND) flag = team_services.user_is_exist_in_team(user_list=[user_id], tenant_name=team_id) if flag: user_obj = user_services.get_user_by_user_id(user_id=user_id) raise serializers.ValidationError("用户{}已经存在".format(user_obj.nick_name), status.HTTP_400_BAD_REQUEST) team_services.add_user_role_to_team(tenant=team, user_ids=[user_id], role_ids=role_ids) return Response(None, status.HTTP_201_CREATED) @swagger_auto_schema( operation_description="update team user", request_body=CreateTeamUserReqSerializer(), responses={ status.HTTP_200_OK: None, status.HTTP_500_INTERNAL_SERVER_ERROR: None, status.HTTP_400_BAD_REQUEST: None, status.HTTP_404_NOT_FOUND: FailSerializer(), }, tags=['openapi-team'], ) def put(self, req, team_id, user_id): if req.user.user_id == user_id: raise serializers.ValidationError("您不能修改自己的权限!", status=status.HTTP_400_BAD_REQUEST) serializer = CreateTeamUserReqSerializer(data=req.data) serializer.is_valid(raise_exception=True) role_ids = req.data["role_ids"].replace(" ", "").split(",") roleids = team_services.get_all_team_role_id(tenant_name=team_id, allow_owner=True) for role_id in role_ids: if int(role_id) not in roleids: raise serializers.ValidationError("角色{}不存在".format(role_id), status.HTTP_404_NOT_FOUND) try: user_services.get_user_by_tenant_id(team_id, user_id) except UserNotExistError as e: return Response({"msg": e.message}, status.HTTP_404_NOT_FOUND) team_services.change_tenant_role(user_id=user_id, tenant_name=team_id, role_id_list=role_ids) return Response(None, status.HTTP_200_OK)
def post(self, request, app_id, *args, **kwargs): try: serializers = ServiceGroupOperationsSerializer(data=request.data) serializers.is_valid(raise_exception=True) except ValidationError as e: logger.debug(e) result = {"msg": "请求参数错误"} rst_serializer = FailSerializer(data=result) rst_serializer.is_valid() return Response(rst_serializer.data, status=status.HTTP_400_BAD_REQUEST) tenant, service_ids = app_service.get_group_services_by_id(app_id) if tenant: code, msg = app_service.group_services_operation( tenant, serializers.data.get("action"), service_ids) if code != 200: result = {"msg": "batch manage error"} rst_serializer = FailSerializer(data=result) rst_serializer.is_valid() return Response(rst_serializer.data, status=status.HTTP_400_BAD_REQUEST) else: result = {"msg": "操作成功"} rst_serializer = SuccessSerializer(data=result) rst_serializer.is_valid() return Response(rst_serializer.data, status=status.HTTP_200_OK) else: result = {"msg": "该应用所属团队已被删除"} rst_serializer = FailSerializer(data=result) rst_serializer.is_valid() return Response(rst_serializer.data, status=status.HTTP_404_NOT_FOUND)