def update_user_roles(self, kind, kind_id, user, role_ids): update_role_list = [] if not user: raise ServiceHandleException(msg="no found user", msg_show="用户不存在", status_code=404) roles = RoleInfo.objects.filter(kind=kind, kind_id=kind_id) has_role_ids = roles.values_list("ID", flat=True) update_role_ids = list(set(has_role_ids) & set(role_ids)) if not update_role_ids and len(role_ids): raise ServiceHandleException(msg="no found can update params", msg_show="传入角色不可被分配,请检查参数", status_code=404) for role_id in update_role_ids: update_role_list.append(UserRole(user_id=user.user_id, role_id=role_id)) UserRole.objects.bulk_create(update_role_list)
def check_app_name(tenant, region_name, group_name, app: ServiceGroup = None): if not group_name: raise ServiceHandleException(msg="app name required", msg_show="应用名不能为空") if len(group_name) > 128: raise ServiceHandleException(msg="app_name illegal", msg_show="应用名称最多支持128个字符") r = re.compile('^[a-zA-Z0-9_\\.\\-\\u4e00-\\u9fa5]+$') if not r.match(group_name): raise ServiceHandleException(msg="app_name illegal", msg_show="应用名称只支持中英文, 数字, 下划线, 中划线和点") exist_app = group_repo.get_group_by_unique_key(tenant.tenant_id, region_name, group_name) if not exist_app: return if not app or exist_app.app_id != app.app_id: raise ServiceHandleException(msg="app name exist", msg_show="应用名称已存在")
def check_volume_path(self, service, volume_path, local_path=[]): for path in local_path: if volume_path.startswith(path + "/"): raise ServiceHandleException(msg="path error", msg_show="持久化路径不能再挂载共享路径下") volume = volume_repo.get_service_volume_by_path(service.service_id, volume_path) if volume: raise ServiceHandleException( msg="path already exists", msg_show="持久化路径[{0}]已存在".format(volume_path), status_code=412) if service.service_source == AppConstants.SOURCE_CODE: if volume_path == "/app": raise ServiceHandleException(msg="path error", msg_show="源码组件不能挂载/app目录", status_code=409) if not runner_util.is_runner(service.image): volume_path_win = False if re.match('[a-zA-Z]', volume_path[0]) and volume_path[1] == ':': volume_path_win = True if not volume_path.startswith("/") and not volume_path_win: raise ServiceHandleException(msg="path error", msg_show="路径仅支持linux和windows") if volume_path in self.SYSDIRS: raise ServiceHandleException(msg="path error", msg_show="路径{0}为系统路径".format(volume_path), status_code=412) if volume_path_win and len(volume_path) == 3: raise ServiceHandleException(msg="path error", msg_show="路径不能为系统路径", status_code=412) else: if not is_path_legal(volume_path): raise ServiceHandleException(msg="path error", msg_show="请输入符合规范的路径(如:/tmp/volumes)", status_code=412) all_volumes = volume_repo.get_service_volumes(service.service_id).values("volume_path") for path in list(all_volumes): # volume_path不能重复 if path["volume_path"].startswith(volume_path + "/") or volume_path.startswith(path["volume_path"] + "/"): raise ServiceHandleException( msg="path error", msg_show="已存在以{0}开头的路径".format(path["volume_path"]), status_code=412)
def get_perms_metadata(): from console.exception.main import ServiceHandleException perms = [] team_perms = get_perms(copy.deepcopy(TEAM), "team", "team") enterprise_perms = get_perms(copy.deepcopy(ENTERPRISE), "enterprise", "enterprise") perms.extend(team_perms) perms.extend(enterprise_perms) name = map(lambda z: z[0], filter(lambda y: y[-1] > 1, Counter(map(lambda x: x[0], perms)).items())) code = map(lambda z: z[0], filter(lambda y: y[-1] > 1, Counter(map(lambda x: x[2], perms)).items())) if name: raise ServiceHandleException(msg="init perms error", msg_show="初始化权限列表失败,权限列表存在重复名称: {}".format(','.join(name))) if code: raise ServiceHandleException(msg="init perms error", msg_show="初始化权限列表失败,权限列表存在重复编码: {}".format(','.join(code))) return perms
def get_image_connection_info(self, scope, team_name): """ :param scope: enterprise(企业) team(团队) goodrain(好雨云市) :param team_name: 租户名称 :return: image_info hub.goodrain.com/goodrain/xxx:lasted """ try: team = team_repo.get_team_by_team_name(team_name) if not team: return {} if scope.startswith("goodrain"): info = market_api.get_share_hub_info(team.tenant_id, "image") return info["image_repo"] else: image_config = ConsoleSysConfig.objects.filter( key='APPSTORE_IMAGE_HUB') if not image_config: return {"hub_url": 'goodrain.me', "namespace": team_name} image_config_dict = json_load(image_config[0].value) hub_url = image_config_dict.get("hub_url", None) hub_user = image_config_dict.get("hub_user", None) hub_password = image_config_dict.get("hub_password", None) namespace = image_config_dict.get("namespace", team_name) is_trust = hub_url == 'hub.goodrain.com' image_info = { "hub_url": hub_url, "hub_user": hub_user, "hub_password": hub_password, "namespace": namespace, "is_trust": is_trust } return image_info except HttpClient.CallApiError as e: logger.exception(e) if e.status == 403: raise ServiceHandleException("no cloud permission", msg_show="云市授权不通过", status_code=403, error_code=10407) else: raise ServiceHandleException("call cloud api failure", msg_show="云市请求错误", status_code=500, error_code=500) except Exception as e: logger.exception(e) return {}
def delete(self, req, app_id, *args, **kwargs): msg_list = [] try: force = int(req.GET.get("force", 0)) except ValueError: raise ServiceHandleException(msg='force value error', msg_show="参数错误") service_ids = app_service.get_group_services_by_id(self.app.ID) services = service_repo.get_services_by_service_ids(service_ids) if services: status_list = base_service.status_multi_service( region=self.app.region_name, tenant_name=self.team.tenant_name, service_ids=service_ids, enterprise_id=self.team.enterprise_id) status_list = [ x for x in [x["status"] for x in status_list] if x not in ["closed", "undeploy"] ] if len(status_list) > 0: raise ServiceHandleException( msg= "There are running components under the current application", msg_show="当前应用下有运行态的组件,不可删除") else: code_status = 200 for service in services: code, msg = app_manage_service.batch_delete(self.user, self.team, service, is_force=True) msg_dict = dict() msg_dict['status'] = code msg_dict['msg'] = msg msg_dict['service_id'] = service.service_id msg_dict['service_cname'] = service.service_cname msg_list.append(msg_dict) if code != 200: code_status = code if force: code_status = 200 app_manage_service.delete_again(self.user, self.team, service, is_force=True) if code_status != 200: raise ServiceHandleException(msg=msg_list, msg_show="请求错误") group_service.delete_app(self.team, self.region_name, self.app) return Response(None, status=200)
def update_role(self, kind, kind_id, id, name): if not name: raise ServiceHandleException(msg="role name exit", msg_show="角色名称不能为空") exit_role = self.get_role_by_name(kind, kind_id, name, with_default=True) if exit_role: if int(exit_role.ID) != int(id): raise ServiceHandleException(msg="role name exit", msg_show="角色名称已存在") else: return exit_role role = self.get_role_by_id(kind, kind_id, id) if not role: raise ServiceHandleException(msg="role no found", msg_show="角色不存在或为默认角色", status_code=404) role.name = name role.save() return role
def initial(self, request, *args, **kwargs): super(TeamAppServiceAPIView, self).initial(request, *args, **kwargs) service_id = kwargs.get("service_id") self.service = TenantServiceInfo.objects.filter( tenant_id=self.team.tenant_id, service_region=self.region_name, service_id=service_id).first() if not self.service: self.service = TenantServiceInfo.objects.filter( tenant_id=self.team.tenant_id, service_region=self.region_name, service_alias=service_id).first() if not self.service: raise ServiceHandleException(msg_show="组件不存在", msg="no found component", status_code=404) gsr = group_service_relation_repo.get_services_by_group(self.app.ID) if gsr: service_ids = gsr.values_list("service_id", flat=True) if self.service.service_id not in service_ids: raise ServiceHandleException(msg_show="组件不属于指定应用", msg="component not belong to this app", status_code=404)
def post(self, request, *args, **kwargs): note = request.data.get("note") age = request.data.get("age") if not note: raise ServiceHandleException(msg="note can't be null", msg_show="注释不能为空") try: access_key = user_access_services.create_user_access_key(note, request.user.user_id, age) result = general_message(200, None, None, bean=access_key.to_dict()) return Response(result, status=200) except ValueError as e: logger.debug(e.message) raise ServiceHandleException(msg="params error", msg_show="创建失败,请检查参数是否合法") except IntegrityError as e: logger.debug(e.message) raise ServiceHandleException(msg="note duplicate", msg_show="创建失败,注释内容不能重复")
def check_volume_name(self, service, volume_name): r = re.compile('(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$') if not r.match(volume_name): if service.service_source != AppConstants.MARKET: raise ServiceHandleException(msg="volume name illegal", msg_show="持久化名称只支持数字字母下划线") volume_name = service.service_alias + "-" + make_uuid()[-3:] volume = volume_repo.get_service_volume_by_name( service.service_id, volume_name) if volume: raise ServiceHandleException( msg="volume name already exists", msg_show="持久化名称[{0}]已存在".format(volume_name)) return volume_name
def get_slug_connection_info(self, scope, team_name): """ :param scope: enterprise(企业) team(团队) goodrain(好雨云市) :return: slug_info /grdata/build/tenant/ """ try: team = team_repo.get_team_by_team_name(team_name) if not team: return {} if scope == "goodrain": info = market_api.get_share_hub_info(team.tenant_id, "slug") return info["slug_repo"] else: slug_config = ConsoleSysConfig.objects.filter( key='APPSTORE_SLUG_PATH') if not slug_config: return {"namespace": team_name} slug_config_dict = json_load(slug_config[0].value) ftp_host = slug_config_dict.get("ftp_host", None) ftp_port = slug_config_dict.get("ftp_port", None) ftp_namespace = slug_config_dict.get("namespace", None) ftp_username = slug_config_dict.get("ftp_username", None) ftp_password = slug_config_dict.get("ftp_password", None) slug_info = { "ftp_host": ftp_host, "ftp_port": ftp_port, "namespace": ftp_namespace + "/" + team_name, "ftp_username": ftp_username, "ftp_password": ftp_password } return slug_info except HttpClient.CallApiError as e: logger.exception(e) if e.status == 403: raise ServiceHandleException("no cloud permission", msg_show="云市授权不通过", status_code=403, error_code=10407) else: raise ServiceHandleException("call cloud api failure", msg_show="云市请求错误", status_code=500, error_code=500) except Exception as e: logger.exception(e) return {}
def close_thirdpart_outer(self, tenant, service, deal_port): try: self.__close_outer(tenant, service, deal_port) except region_api.CallApiError as e: logger.exception(e) raise ServiceHandleException(msg="close outer port failed", msg_show="关闭对外服务失败")
def get(self, req, eid): data = { "enterprise_id": eid, "used_cpu": 0, "used_memory": 0, "used_disk": 0 } if not req.user.is_administrator: raise ServiceHandleException(status_code=401, error_code=401, msg="Permission denied") ent = enterprise_services.get_enterprise_by_id(eid) if ent is None: return Response({"msg": "企业不存在"}, status=status.HTTP_404_NOT_FOUND) regions = region_services.get_regions_by_enterprise_id(eid) for region in regions: try: res, body = region_api.get_region_resources( eid, region.region_name) rst = body.get("bean") if res.get("status") == 200 and rst: data["used_cpu"] += rst.get("req_cpu", 0) data["used_memory"] += rst.get("req_mem", 0) data["used_disk"] += rst.get("req_disk", 0) except ServiceHandleException: continue serializer = EnterpriseSourceSerializer(data=data) serializer.is_valid(raise_exception=True) return Response(serializer.data, status=status.HTTP_200_OK)
def recover_adaptor_data(self, file_name): files = {'file': open(file_name, 'rb')} remoteurl = "http://{0}:{1}/{2}".format( os.getenv("ADAPTOR_HOST", "127.0.0.1"), os.getenv("ADAPTOR_PORT", "8080"), "enterprise-server/api/v1/recover") r = requests.post(remoteurl, files=files) if r.status_code != 200: raise ServiceHandleException(msg="export adaptor data failed", msg_show="恢复adaptor数据失败")
def get(self, request, *args, **kwargs): group_id = request.GET.get("group_id", None) region_name = request.GET.get("region_name", None) if not group_id or not region_name: result = general_message(400, "not group_id", "参数缺失") return Response(result) services = group_service_relation_repo.get_services_obj_by_group( group_id) if not services: result = general_message(400, "not service", "当前组内无组件,无法操作") return Response(result) service_id_list = [x.service_id for x in services] try: service_status_list = region_api.service_status( self.response_region, self.tenant_name, { "service_ids": service_id_list, "enterprise_id": self.user.enterprise_id }) result = general_message(200, "success", "查询成功", list=service_status_list) return Response(result) except (region_api.CallApiError, ServiceHandleException) as e: logger.debug(e) raise ServiceHandleException(msg="region error", msg_show="访问数据中心失败")
def update_group(self, tenant, region_name, app_id, app_name, note="", username=None): # check app id if not app_id or app_id < 0: raise ServiceHandleException(msg="app id illegal", msg_show="应用ID不合法") # check username if username: user_repo.get_user_by_username(username) # check app name self.check_app_name(tenant, region_name, app_name) data = { "note": note, } if username: data["username"] = username if app_name: data["group_name"] = app_name group_repo.update(app_id, **data)
def delete_role(self, kind, kind_id, id): role = self.get_role_by_id(kind, kind_id, id) if not role: raise ServiceHandleException(msg="role no found or is default", msg_show="角色不存在或为默认角色") role_perm_relation_repo.delete_role_perm_relation(role.ID) user_kind_role_repo.delete_users_role(kind, kind_id, role.ID) role.delete()
def get_team_by_team_name_and_eid(self, eid, team_name): try: return Tenants.objects.get(tenant_name=team_name, enterprise_id=eid) except Tenants.DoesNotExist: raise ServiceHandleException(msg_show="团队不存在", msg="team not found")
def get_or_create_upgrade_record(self, tenant_id, group_id, group_key, upgrade_group_id, is_from_cloud, market_name): """获取或创建升级记录""" recode_kwargs = { "tenant_id": tenant_id, "group_id": group_id, "group_key": group_key, "create_time": datetime.now(), "is_from_cloud": is_from_cloud, "market_name": market_name, "upgrade_group_id": upgrade_group_id, } try: return upgrade_repo.get_app_not_upgrade_record(status__lt=UpgradeStatus.UPGRADED.value, **recode_kwargs) except AppUpgradeRecord.DoesNotExist: from console.services.group_service import group_service tenant = Tenants.objects.get(tenant_id=tenant_id) service_group_keys = group_service.get_group_service_sources(group_id).values_list('group_key', flat=True) if group_key in set(service_group_keys or []): if not is_from_cloud: app = rainbond_app_repo.get_rainbond_app_qs_by_key(tenant.enterprise_id, group_key) if not app: raise ServiceHandleException( msg="the rainbond app is not in the group", msg_show="该应用中没有这个云市组件", status_code=404) app_name = app.app_name else: market = app_market_service.get_app_market_by_name(tenant.enterprise_id, market_name, raise_exception=True) app = app_market_service.get_market_app_model(market, group_key) app_name = app.app_name app_record = upgrade_repo.create_app_upgrade_record(group_name=app_name, **recode_kwargs) return app_record else: raise AbortRequest(msg="the app model is not in the group", msg_show="该应用中没有这个应用模型", status_code=404)
def get_user_roles(self, kind, kind_id, user): if not user: raise ServiceHandleException(msg="no found user", msg_show="用户不存在", status_code=404) user_roles_list = [] roles = RoleInfo.objects.filter(kind=kind, kind_id=kind_id) if roles: role_id_name_kv = {} for role in roles: role_id_name_kv.update({str(role.ID): role.name}) role_ids = roles.values_list("ID", flat=True) user_roles = UserRole.objects.filter(role_id__in=role_ids, user_id=user.user_id) if user_roles: for user_role in user_roles: user_roles_list.append({ "role_id": user_role.role_id, "role_name": role_id_name_kv[str(user_role.role_id)] }) data = { "nick_name": user.nick_name, "user_id": user.user_id, "roles": user_roles_list } return data
def update_service_check_info(self, tenant, service, data): if data["check_status"] != "success": return sid = None try: sid = transaction.savepoint() # 删除原有build类型env,保存新检测build类型env self.upgrade_service_env_info(tenant, service, data) # 重新检测后对端口做加法 try: self.add_service_check_port(tenant, service, data) except ErrComponentPortExists: logger.error( 'upgrade component port by code check failure due to component port exists' ) lang = data["service_info"][0]["language"] if lang == "dockerfile": service.cmd = "" elif service.service_source == AppConstants.SOURCE_CODE: service.cmd = "start web" service.language = lang service.save() transaction.savepoint_commit(sid) except Exception as e: logger.exception(e) if sid: transaction.savepoint_rollback(sid) raise ServiceHandleException( status_code=400, msg="handle check service code info failure", msg_show="处理检测结果失败")
def update_http_rule_config(self, team, region_name, rule_id, configs): self.check_set_header(configs["set_headers"]) service_domain = get_object_or_404(ServiceDomain, msg="no domain", msg_show="策略不存在", http_rule_id=rule_id) service = get_object_or_404(TenantServiceInfo, msg="no service", msg_show="组件不存在", service_id=service_domain.service_id) cf = configuration_repo.get_configuration_by_rule_id(rule_id) gcc_dict = dict() gcc_dict["body"] = configs gcc_dict["rule_id"] = rule_id try: res, data = region_api.upgrade_configuration( region_name, team.tenant_name, service.service_alias, gcc_dict) if res.status == 200: if cf: cf.value = json.dumps(configs) cf.save() else: cf_dict = dict() cf_dict["rule_id"] = rule_id cf_dict["value"] = json.dumps(configs) configuration_repo.add_configuration(**cf_dict) except region_api.CallApiFrequentError as e: logger.exception(e) raise ServiceHandleException( msg="update http rule configuration failure", msg_show="更新HTTP策略的参数发生异常", status_code=500, error_code=500)
def post(self, request, app_id, *args, **kwargs): ctcs = CreateThirdComponentSerializer(data=request.data) ctcs.is_valid(raise_exception=True) req_date = ctcs.data validate_endpoints_info(req_date["endpoints"]) new_component = console_app_service.create_third_party_app(self.region_name, self.team, self.user, req_date["component_name"], req_date["endpoints"], req_date["endpoints_type"]) # add component to app code, msg_show = group_service.add_service_to_group(self.team, self.region_name, app_id, new_component.service_id) if code != 200: raise ServiceHandleException( msg="add component to app failure", msg_show=msg_show, status_code=code, error_code=code) endpoints_type = req_date["endpoints_type"] bean = new_component.to_dict() if endpoints_type == "api": # 生成秘钥 deploy = deploy_repo.get_deploy_relation_by_service_id(service_id=new_component.service_id) api_secret_key = pickle.loads(base64.b64decode(deploy)).get("secret_key") # 从环境变量中获取域名,没有在从请求中获取 host = os.environ.get('DEFAULT_DOMAIN', "http://" + request.get_host()) api_url = host + "/console/" + "third_party/{0}".format(new_component.service_id) bean["api_service_key"] = api_secret_key bean["url"] = api_url console_app_service.create_third_party_service(self.team, new_component, self.user.nick_name) return Response(bean, status=status.HTTP_200_OK)
def delete(self, req, app_id, service_id, *args, **kwargs): try: force = int(req.GET.get("force", 0)) except ValueError: raise ServiceHandleException(msg='force value error', msg_show="参数错误") code, msg = app_manage_service.delete(self.user, self.team, self.service, True) if code != 200 and force: app_manage_service.delete_again(self.user, self.team, self.service, is_force=True) msg_dict = dict() msg_dict['status'] = code msg_dict['msg'] = msg msg_dict['service_id'] = self.service.service_id msg_dict['service_cname'] = self.service.service_cname if code != 200: raise ServiceHandleException(msg="delete error", msg_show=msg, status_code=code) return Response(None, status=status.HTTP_200_OK)
def post(self, request, enterprise_id, market_name, *args, **kwargs): logo = request.data.get("logo") base64_logo = "" if logo: if logo.startswith(settings.MEDIA_URL): logo = logo.replace(settings.MEDIA_URL, settings.MEDIA_ROOT + "/") try: with open(logo, "rb") as f: base64_logo = "data:image/{};base64,".format(logo.split(".")[-1]) + base64.b64encode(f.read()).decode() except Exception as e: logger.exception(e) base64_logo = "" name = request.data.get("name", "") if not validate_name(name): raise ServiceHandleException(msg="error params", msg_show="应用名称只支持中文、字母、数字和-_组合,并且必须以中文、字母、数字开始和结束") dt = { "desc": request.data.get("desc"), "logo": base64_logo, "name": name, "publish_type": request.data.get("publish_type"), "tags": request.data.get("tags"), "introduction": request.data.get("introduction"), "org_id": request.data.get("org_id") } market = app_market_service.get_app_market_by_name(enterprise_id, market_name, raise_exception=True) rst = app_market_service.create_market_app_model(market, body=dt) result = general_message(200, msg="success", msg_show=None, bean=(rst.to_dict() if rst else None)) return Response(result, status=200)
def create_service_plugin_relation(self, tenant_id, service_id, plugin_id, build_version, service_meta_type="", plugin_status=True): sprs = app_plugin_relation_repo.get_relation_by_service_and_plugin( service_id, plugin_id) if sprs: raise ServiceHandleException(msg="plugin has installed", status_code=409, msg_show="组件已安装该插件") plugin_version_info = plugin_version_repo.get_by_id_and_version( tenant_id, plugin_id, build_version) min_memory = plugin_version_info.min_memory min_cpu = plugin_version_info.min_cpu params = { "service_id": service_id, "build_version": build_version, "service_meta_type": service_meta_type, "plugin_id": plugin_id, "plugin_status": plugin_status, "min_memory": min_memory, "min_cpu": min_cpu, } return app_plugin_relation_repo.create_service_plugin_relation( **params)
def delete(self, request, enterprise_id, region_id, *args, **kwargs): try: region_repo.del_by_enterprise_region_id(enterprise_id, region_id) except RegionConfig.DoesNotExist: raise ServiceHandleException(status_code=404, msg="集群已不存在") result = general_message(200, "success", "删除成功") return Response(result, status=result.get("code", 200))
def add_region(self, region_data): region = region_repo.get_region_by_region_name( region_data["region_name"]) if region: raise ServiceHandleException(status_code=400, msg="", msg_show="集群ID{0}已存在".format( region_data["region_name"])) try: region_api.test_region_api(region_data) except ServiceHandleException: raise ServiceHandleException(status_code=400, msg="test link region field", msg_show="连接集群测试失败,请确认网络和集群状态") region = region_repo.create_region(region_data) return region
def delete_service_volume_by_id(self, tenant, service, volume_id, user_name=''): volume = volume_repo.get_service_volume_by_pk(volume_id) if not volume: return 404, "需要删除的路径不存在", None # if volume.volume_type == volume.SHARE: # 判断当前共享目录是否被使用 mnt = mnt_repo.get_mnt_by_dep_id_and_mntname(service.service_id, volume.volume_name) if mnt: return 403, "当前路径被共享,无法删除", None if service.create_status == "complete": data = dict() data["operator"] = user_name try: res, body = region_api.delete_service_volumes( service.service_region, tenant.tenant_name, service.service_alias, volume.volume_name, tenant.enterprise_id, data) logger.debug( "service {0} delete volume {1}, result {2}".format( service.service_cname, volume.volume_name, body)) except region_api.CallApiError as e: if e.status != 404: raise ServiceHandleException( msg="delete volume from region failure", msg_show="从集群删除存储发生错误", status_code=500) volume_repo.delete_volume_by_id(volume_id) volume_repo.delete_file_by_volume(volume) return 200, "success", volume
def get_role_by_id(self, kind, kind_id, id, with_default=False): role = role_kind_repo.get_role_by_id(kind, kind_id, id, with_default) if not role: raise ServiceHandleException(msg="role no found", msg_show=u"角色不存在", status_code=404) return role