def back_up_group_apps(self, tenant, user, region, group_id, mode, note): service_slug = app_store.get_slug_connection_info( "enterprise", tenant.tenant_name) service_image = app_store.get_image_connection_info( "enterprise", tenant.tenant_name) services = group_service.get_group_services(group_id) event_id = make_uuid() group_uuid = self.get_backup_group_uuid(group_id) metadata = self.get_group_app_metadata(group_id, tenant) version = current_time_str("%Y%m%d%H%M%S") data = { "event_id": event_id, "group_id": group_uuid, "metadata": metadata, "service_ids": [s.service_id for s in services], "mode": mode, "version": version, "slug_info": service_slug, "image_info": service_image } body = region_api.backup_group_apps(region, tenant.tenant_name, data) bean = body["bean"] record_data = { "group_id": group_id, "event_id": event_id, "group_uuid": group_uuid, "version": version, "team_id": tenant.tenant_id, "region": region, "status": bean["status"], "note": note, "mode": mode, "backup_id": bean.get("backup_id", ""), "source_dir": bean.get("source_dir", ""), "backup_size": bean.get("backup_size", 0), "user": user.nick_name, "backup_server_info": json.dumps({ "slug_info": service_slug, "image_info": service_image }) } backup_record = backup_record_repo.create_backup_records(**record_data) return backup_record
def delete(self, request, *args, **kwargs): """ 应用数据删除 --- parameters: - name: tenantName description: 团队名称 required: true type: string paramType: path - name: group_id description: 组ID required: true type: string paramType: path - name: new_group_id description: 组ID required: true type: string paramType: query """ try: group_id = int(kwargs.get("group_id", None)) if not group_id: return Response(general_message(400, "group id is null", "请确认需要删除的组"), status=400) new_group_id = request.data.get("new_group_id", None) if not new_group_id: return Response(general_message(400, "new group id is null", "请确认新恢复的组"), status=400) if group_id == new_group_id: return Response(general_message(200, "success", "恢复到当前组无需删除"), status=200) group = group_repo.get_group_by_id(group_id) if not group: return Response(general_message(400, "group is delete", "该备份组已删除"), status=400) if group.is_default: return Response(general_message(400, "default app", "默认应用不允许删除"), status=400) new_group = group_repo.get_group_by_id(new_group_id) if not new_group: return Response( general_message(400, "new group not exist", "组ID {0} 不存在".format(new_group_id)), status=400) services = group_service.get_group_services(group_id) for service in services: try: app_manage_service.truncate_service(self.tenant, service) except Exception as le: logger.exception(le) group.delete() result = general_message(200, "success", "操作成功") except Exception as e: logger.exception(e) result = error_message(e.message) return Response(result, status=result["code"])
def backup_group_apps(self, tenant, user, region, group_id, mode, note, force=False): s3_config = EnterpriseConfigService( tenant.enterprise_id).get_cloud_obj_storage_info() if mode == "full-online" and not s3_config: raise ErrObjectStorageInfoNotFound services = group_service.get_group_services(group_id) event_id = make_uuid() group_uuid = self.get_backup_group_uuid(group_id) total_memory, metadata = self.get_group_app_metadata(group_id, tenant) version = current_time_str("%Y%m%d%H%M%S") data = { "event_id": event_id, "group_id": group_uuid, "metadata": json.dumps(metadata), "service_ids": [s.service_id for s in services], "mode": mode, "version": version, "s3_config": s3_config, "force": force, } # 向数据中心发起备份任务 try: body = region_api.backup_group_apps(region, tenant.tenant_name, data) bean = body["bean"] record_data = { "group_id": group_id, "event_id": event_id, "group_uuid": group_uuid, "version": version, "team_id": tenant.tenant_id, "region": region, "status": bean["status"], "note": note, "mode": mode, "backup_id": bean.get("backup_id", ""), "source_dir": bean.get("source_dir", ""), "source_type": bean.get("source_type", ""), "backup_size": bean.get("backup_size", 0), "user": user.nick_name, "total_memory": total_memory, } return backup_record_repo.create_backup_records(**record_data) except region_api.CallApiError as e: logger.exception(e) if e.status == 401: raise ServiceHandleException(msg="backup failed", msg_show="有状态组件必须停止方可进行备份")
def post(self, request, app_id, *args, **kwargs): is_deploy = request.GET.get("is_deploy", False) if is_deploy == "true": is_deploy = True serializer = InstallSerializer(data=request.data) serializer.is_valid(raise_exception=True) market_url = serializer.data.get("market_url") market_domain = serializer.data.get("market_domain") market_type = serializer.data.get("market_type") market_access_key = serializer.data.get("market_access_key") app_model_id = serializer.data.get("app_model_id") app_model_version = serializer.data.get("app_model_version") market = app_market_service.get_app_market_by_domain_url( self.team.enterprise_id, market_domain, market_url) if not market: market_name = make_uuid() dt = { "name": market_name, "url": market_url, "type": market_type, "enterprise_id": self.team.enterprise_id, "access_key": market_access_key, "domain": market_domain, } app_market_service.create_app_market(dt) dt, market = app_market_service.get_app_market( self.team.enterprise_id, market_name, raise_exception=True) market_name = market.name app, app_version_info = app_market_service.cloud_app_model_to_db_model( market, app_model_id, app_model_version, for_install=True) if not app: raise ServiceHandleException(status_code=404, msg="not found", msg_show="云端应用不存在") if not app_version_info: raise ServiceHandleException(status_code=404, msg="not found", msg_show="云端应用版本不存在") market_app_service.install_service(self.team, self.region_name, self.user, app_id, app, app_version_info, is_deploy, True, market_name=market_name) services = group_service.get_group_services(app_id) app_info = model_to_dict(self.app) app_info["app_name"] = app_info["group_name"] app_info["team_id"] = app_info["tenant_id"] app_info["enterprise_id"] = self.team.enterprise_id app_info["service_list"] = services reapp = MarketInstallSerializer(data=app_info) reapp.is_valid() return Response(reapp.data, status=status.HTTP_200_OK)
def __check_group_service_status(self, region, tenant, group_id): services = group_service.get_group_services(group_id) service_ids = [s.service_id for s in services] if not service_ids: return True body = region_api.service_status(region, tenant.tenant_name, {"service_ids": service_ids, "enterprise_id": tenant.enterprise_id}) status_list = body["list"] for status in status_list: if status["status"] not in ("closed", "undeploy"): return False return True
def check_services(app_id, req_service_ids): services = group_service.get_group_services(app_id) service_ids = [service.service_id for service in services] # Judge whether the requested service ID is correct if req_service_ids is not None: for sid in req_service_ids: if sid not in service_ids: raise AbortRequest( msg= "The serviceID is not in the serviceID of the current application binding", msg_show="请求的组件ID不在当前应用绑定的组件ID中", status_code=404)
def import_group_backup(self, tenant, region, group_id, upload_file): group = group_repo.get_group_by_id(group_id) if not group: return 404, "需要导入的组不存在", None services = group_service.get_group_services(group_id) if services: return 409, "请确保需要导入的组中不存在组件", None content = upload_file.read().strip() data = json.loads(AuthCode.decode(content, KEY)) current_backup = backup_record_repo.get_record_by_group_id_and_backup_id( group_id, data["backup_id"]) if current_backup: return 412, "当前团队已导入过该备份", None event_id = make_uuid() group_uuid = make_uuid() params = { "event_id": event_id, "group_id": group_uuid, "status": data["status"], "version": data["version"], "source_dir": data["source_dir"], "source_type": data["source_type"], "backup_mode": data["mode"], "backup_size": data["backup_size"] } body = region_api.copy_backup_data(region, tenant.tenant_name, params) bean = body["bean"] record_data = { "group_id": group.ID, "event_id": event_id, "group_uuid": group_uuid, "version": data["version"], "team_id": tenant.tenant_id, "region": region, "status": bean["status"], "note": data["note"], "mode": data["mode"], "backup_id": bean["backup_id"], "source_dir": data["source_dir"], "source_type": data["source_type"], "backup_size": data["backup_size"], "user": data["user"], "total_memory": data["total_memory"], "backup_server_info": data["backup_server_info"] } new_backup_record = backup_record_repo.create_backup_records( **record_data) return 200, "success", new_backup_record
def check_backup_app_used_custom_volume(self, group_id): services = group_service.get_group_services(group_id) service_list = dict() for service in services: service_list[service.service_id] = service.service_cname service_ids = [service.service_id for service in services] volumes = volume_repo.get_multi_service_volumes(service_ids) use_custom_svc = [] for volume in volumes: if service_list[volume.service_id] not in use_custom_svc: use_custom_svc.append(service_list[volume.service_id]) return use_custom_svc
def __copy_backup_record(self, restore_mode, origin_backup_record, current_team, current_region, migrate_team, migrate_region, migrate_type): """拷贝备份数据""" services = group_service.get_group_services( origin_backup_record.group_id) if not services and migrate_type == "recover": # restore on the original group new_group = group_repo.get_group_by_id( origin_backup_record.group_id) if not new_group: new_group = self.__create_new_group_by_group_name( migrate_team.tenant_id, migrate_region, origin_backup_record.group_id) else: new_group = self.__create_new_group(migrate_team.tenant_id, migrate_region, origin_backup_record.group_id) if restore_mode != AppMigrateType.CURRENT_REGION_CURRENT_TENANT: # 获取原有数据中心数据 original_data = region_api.get_backup_status_by_backup_id( current_region, current_team.tenant_name, origin_backup_record.backup_id) new_event_id = make_uuid() new_group_uuid = make_uuid() new_data = original_data["bean"] new_data["event_id"] = new_event_id new_data["group_id"] = new_group_uuid # 存入其他数据中心 body = region_api.copy_backup_data(migrate_region, migrate_team.tenant_name, new_data) bean = body["bean"] params = origin_backup_record.to_dict() params.pop("ID") params["team_id"] = migrate_team.tenant_id params["event_id"] = new_event_id params["group_id"] = new_group.ID params["group_uuid"] = new_group_uuid params["region"] = migrate_region params["backup_id"] = bean["backup_id"] # create a new backup record in the new region new_backup_record = backup_record_repo.create_backup_records( **params) return new_group, new_backup_record return new_group, None
def get_app_status(self, app): services = group_service.get_group_services(app.ID) service_ids = [service.service_id for service in services] team = team_services.get_team_by_team_id(app.tenant_id) status_list = base_service.status_multi_service( region=app.region_name, tenant_name=team.tenant_name, service_ids=service_ids, enterprise_id=team.enterprise_id) # As long as there is a service running, the application thinks it is running app_status = "closed" for status in status_list: if status["status"] == "running": app_status = "running" if not service_ids: app_status = "notinstall" return app_status, services
def backup_group_apps(self, tenant, user, region, group_id, mode, note): service_slug = app_store.get_slug_connection_info("enterprise", tenant.tenant_name) service_image = app_store.get_image_connection_info("enterprise", tenant.tenant_name) if mode == "full-online" and not self.is_hub_info_configed(): return 412, "未配置hub仓库信息", None services = group_service.get_group_services(group_id) event_id = make_uuid() group_uuid = self.get_backup_group_uuid(group_id) total_memory, metadata = self.get_group_app_metadata(group_id, tenant) version = current_time_str("%Y%m%d%H%M%S") data = { "event_id": event_id, "group_id": group_uuid, "metadata": metadata, "service_ids": [s.service_id for s in services], "mode": mode, "version": version, "slug_info": service_slug, "image_info": service_image } # 向数据中心发起备份任务 body = region_api.backup_group_apps(region, tenant.tenant_name, data) bean = body["bean"] record_data = { "group_id": group_id, "event_id": event_id, "group_uuid": group_uuid, "version": version, "team_id": tenant.tenant_id, "region": region, "status": bean["status"], "note": note, "mode": mode, "backup_id": bean.get("backup_id", ""), "source_dir": bean.get("source_dir", ""), "source_type": bean.get("source_type", ""), "backup_size": bean.get("backup_size", 0), "user": user.nick_name, "total_memory": total_memory, "backup_server_info": json.dumps({ "slug_info": service_slug, "image_info": service_image }) } backup_record = backup_record_repo.create_backup_records(**record_data) return 200, "success", backup_record
def get_group_services_used_plugins(self, group_id): service_list = group_service.get_group_services(group_id) if not service_list: return [] service_ids = [x.service_id for x in service_list] sprs = app_plugin_relation_repo.get_service_plugin_relations_by_service_ids(service_ids) plugin_list = [] temp_plugin_ids = [] for spr in sprs: if spr.plugin_id in temp_plugin_ids: continue tenant_plugin = plugin_repo.get_plugin_by_plugin_ids([spr.plugin_id])[0] plugin_dict = tenant_plugin.to_dict() plugin_dict["build_version"] = spr.build_version plugin_list.append(plugin_dict) temp_plugin_ids.append(spr.plugin_id) return plugin_list
def check_backup_condition(self, tenant, region, group_id): """ 检测备份条件,有状态应用备份应该 """ services = group_service.get_group_services(group_id) service_ids = [s.service_id for s in services] body = region_api.service_status(region, tenant.tenant_name, {"service_ids": service_ids, "enterprise_id": tenant.enterprise_id}) status_list = body["list"] service_status_map = {status_map["service_id"]: status_map["status"] for status_map in status_list} # 处于运行中的有状态 running_state_services = [] for service in services: if service.extend_method == "state": if service_status_map.get(service.service_id) not in ("closed", "undeploy"): running_state_services.append(service.service_cname) return 200, running_state_services
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)
def get_app_services_and_status(self, app): services = group_service.get_group_services(app.ID) service_ids = [service.service_id for service in services] team = team_services.get_team_by_team_id(app.tenant_id) status_list = base_service.status_multi_service( region=app.region_name, tenant_name=team.tenant_name, service_ids=service_ids, enterprise_id=team.enterprise_id) status_map = {} if status_list: for status in status_list: status_map[status["service_id"]] = status["status"] re_services = [] for service in services: s = model_to_dict(service) s["status"] = status_map.get(service.service_id) re_services.append(s) return re_services
def backup_group_apps(self, tenant, user, region, group_id, mode, note): s3_config = config_service.get_cloud_obj_storage_info() if mode == "full-online" and not s3_config: raise ErrObjectStorageInfoNotFound services = group_service.get_group_services(group_id) event_id = make_uuid() group_uuid = self.get_backup_group_uuid(group_id) total_memory, metadata = self.get_group_app_metadata(group_id, tenant) version = current_time_str("%Y%m%d%H%M%S") data = { "event_id": event_id, "group_id": group_uuid, "metadata": metadata, "service_ids": [s.service_id for s in services], "mode": mode, "version": version, "s3_config": s3_config, } # 向数据中心发起备份任务 body = region_api.backup_group_apps(region, tenant.tenant_name, data) bean = body["bean"] record_data = { "group_id": group_id, "event_id": event_id, "group_uuid": group_uuid, "version": version, "team_id": tenant.tenant_id, "region": region, "status": bean["status"], "note": note, "mode": mode, "backup_id": bean.get("backup_id", ""), "source_dir": bean.get("source_dir", ""), "source_type": bean.get("source_type", ""), "backup_size": bean.get("backup_size", 0), "user": user.nick_name, "total_memory": total_memory, } return backup_record_repo.create_backup_records(**record_data)
def get(self, request, *args, **kwargs): """ 监控信息查询 --- parameters: - name: tenantName description: 租户名 required: true type: string paramType: path - name: group_id description: 组ID required: true type: string paramType: path """ group_id = kwargs.get("group_id", None) result_list = [] try: """ 1. 获取组下所有的服务 2. 查询所有服务对应的pod信息,找出ip信息 3. 根据pod信息和ip信息 查询出 响应时间和吞吐率 4. 查询对外的服务的信息 5. ip信息为public,查询出响应时间和吞吐率 6. 综合查到的信息,组合为返回参数 [{"is_web":True,"source":"服务名称","target":"服务名称","data":{"response_time":0.9,"throughput_rate":10}}] """ if group_id is None: return Response(general_message(400, "group id is none", "请指明要查询的组名称"), status=400) prefix = "?query=" services = group_service.get_group_services(group_id) service_id_list = [] id_service_map = {} id_name_map = {} for s in services: service_id_list.append(s.service_id) id_service_map[s.service_id] = s id_name_map[s.service_id] = s.service_cname pods_info = region_api.get_services_pods(self.response_region, self.tenant.tenant_name, service_id_list, self.tenant.enterprise_id) pod_info_list = pods_info["list"] ip_service_map = {} all_ips = [] for pod_info in pod_info_list: pod_ip = pod_info["PodIP"] service_id = pod_info["ServiceID"] service = id_service_map.get(service_id, None) no_dot_ip = pod_ip.replace(".", "") if service: ip_service_map[no_dot_ip] = service all_ips.append(no_dot_ip) response_time, throughput_rate = self.get_query_statements(service_id_list, all_ips) try: res, response_body = region_api.get_query_data(self.response_region, self.tenant.tenant_name, prefix + response_time) res, throughput_body = region_api.get_query_data(self.response_region, self.tenant.tenant_name, prefix + throughput_rate) response_data = response_body["data"]["result"] throughput_data = throughput_body["data"]["result"] for r in response_data: res_union_key = r["metric"]["client"] + "+" + r["metric"]["service_id"] for t in throughput_data: thr_union_key = t["metric"]["client"] + "+" + t["metric"]["service_id"] if res_union_key == thr_union_key: result_bean = {"is_web": False} source = res_union_key.split("+")[0] target = res_union_key.split("+")[1] source_service = ip_service_map.get(source, None) target_service = id_service_map.get(target, None) if source_service and target_service: result_bean["target"] = target_service.service_cname result_bean["source"] = source_service.service_cname elif target_service and not source_service: if source == "public": result_bean["is_web"] = True result_bean["target"] = target_service.service_cname result_bean["source"] = None else: continue result_bean["data"] = {"response_time": float(r["value"][1]), "throughput_rate": float(t["value"][1])} result_list.append(result_bean) except region_api.CallApiError as e: logger.exception(e) result = general_message(200, "success", "成功", list=result_list) except Exception as e: logger.exception(e) result = general_message(400, e.message, "查询失败") return Response(result, status=result["code"])
def get_tcp_rules_by_app_id(self, app_id): services = group_service.get_group_services(app_id) service_ids = [s.service_id for s in services] return tcp_domain.get_services_tcpdomains(service_ids)
def get_tcp_rules_by_app_id(self, region_name, app_id): services = group_service.get_group_services(app_id) service_ids = [s.service_id for s in services] return self.get_tcp_rules_by_service_ids(region_name, service_ids)
def get_http_rules_by_app_id(self, app_id): services = group_service.get_group_services(app_id) service_ids = [s.service_id for s in services] return domain_repo.get_domains_by_service_ids(service_ids)