def put(self, request, service_id, *args, **kwargs): secret_key = request.data.get("secret_key") # 加密 deploy_key = deploy_repo.get_secret_key_by_service_id( service_id=service_id) deploy_key_decode = pickle.loads( base64.b64decode(deploy_key)).get("secret_key") if secret_key != deploy_key_decode: result = general_message(400, "failed", "密钥错误") return Response(result, status=400) address = request.data.get("ip", None) # is_online true为上线,false为下线 is_online = request.data.get("is_online", True) if type(is_online) != bool: return Response(general_message(400, "is_online type error", "参数类型错误"), status=400) if not address: return Response(general_message(400, "end_point is null", "end_point未指明"), status=400) try: service_obj = TenantServiceInfo.objects.get(service_id=service_id) tenant_obj = Tenants.objects.get(tenant_id=service_obj.tenant_id) endpoint_dict = dict() endpoint_dict["address"] = address endpoint_dict["is_online"] = is_online # 根据ip从数据中心查询, 有就put,没有就post res, body = region_api.get_third_party_service_pods( service_obj.service_region, tenant_obj.tenant_name, service_obj.service_alias) if res.status != 200: return Response(general_message(412, "region error", "数据中心查询失败"), status=412) endpoint_list = body["list"] # 添加 if not endpoint_list: res, body = region_api.post_third_party_service_endpoints( service_obj.service_region, tenant_obj.tenant_name, service_obj.service_alias, endpoint_dict) if res.status != 200: return Response(general_message(412, "region error", "数据中心添加失败"), status=412) return Response(general_message(200, "success", "修改成功")) addresses = [] for endpoint in endpoint_list: addresses.append(endpoint["address"]) addr_list = [addr for addr in addresses] addr_list.append(address) errs, _ = check_endpoints(addr_list) if len(errs) > 0: return Response(general_message( 400, "do not allow multi domain endpoints", "不允许添加多个域名组件实例地址"), status=400) if address not in addresses: # 添加 res, body = region_api.post_third_party_service_endpoints( service_obj.service_region, tenant_obj.tenant_name, service_obj.service_alias, endpoint_dict) if res.status != 200: return Response(general_message(412, "region error", "数据中心添加失败"), status=412) return Response(general_message(200, "success", "修改成功")) # 修改 for endpoint in endpoint_list: if endpoint["address"] == address: bean = dict() bean["ep_id"] = endpoint["ep_id"] bean["is_online"] = is_online res, body = region_api.put_third_party_service_endpoints( service_obj.service_region, tenant_obj.tenant_name, service_obj.service_alias, bean) if res.status != 200: return Response(general_message( 412, "region error", "数据中心修改失败"), status=412) result = general_message(200, "success", "修改成功") return Response(result, status=200) except region_api.CallApiFrequentError as e: logger.exception(e) return 409, u"操作过于频繁,请稍后再试"
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) logger.debug('---------group_id---------->{0}'.format(group_id)) 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 = [] if pod_info_list: for pod_info in pod_info_list: pod_ip = pod_info["pod_ip"] service_id = pod_info["service_id"] 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 post(self, request, plugin_id, *args, **kwargs): """ 应用安装插件 --- parameters: - name: tenantName description: 租户名 required: true type: string paramType: path - name: serviceAlias description: 服务别名 required: true type: string paramType: path - name: plugin_id description: 插件ID required: true type: string paramType: path - name: build_version description: 插件版本 required: true type: string paramType: form """ result = {} build_version = request.data.get("build_version", None) try: if not plugin_id: return Response(general_message(400, "params error","参数错误"),status=400) if not build_version: plugin_version = plugin_version_service.get_newest_usable_plugin_version(plugin_id) build_version = plugin_version.build_version # 1. 建立关联关系 # 2. 生成默认的配置发送给前端 # 3. 生成默认配置存储至console数据库 # 4. 生成默认配置发送给region # >> 进行关联 body_relation = {} body_relation["plugin_id"] = plugin_id body_relation["switch"] = True body_relation["version_id"] = build_version # 1)发送关联请求 try: res, resultBody = region_api.pluginServiceRelation( self.response_region, self.tenant.tenant_name, self.service.service_alias, body_relation) if res.status == 200: plugin_svc.add_service_plugin_relation( service_id=self.service.service_id, plugin_id=plugin_id, build_version=build_version) except region_api.CallApiError as e: if e.status == 400: result = general_message(400, "plugin already related", u"该类型插件已关联,请先卸载同类插件") return Response(result, status=400) else: result = general_message(int(e.status), "region install error", "安装插件失败") return Response(result, status=result["code"]) # 2)发送配置请求 result["config_group"] = self.useDefaultAttr(plugin_id, build_version, "post") complex, normal = plugin_svc.createAttrsJsonForRegion(self.service.service_id, self.service.service_alias, plugin_id) config_envs = {} config_envs["normal_envs"] = normal config_envs["complex_envs"] = complex body = {} body["tenant_id"] = self.tenant.tenant_id body["service_id"] = self.service.service_id body["config_envs"] = config_envs res, resultBody = region_api.postPluginAttr(self.response_region, self.tenant.tenant_name, self.service.service_alias, plugin_id, body) if res.status == 200: result = general_message(200, "success", "操作成功", bean=result["config_group"]) return Response(result, result["code"]) else: result = general_message(int(res.status), "add plugin attr error", "操作失败") return Response(result, status=200) except HasNoDownStreamService as e: try: plugin_svc.del_service_plugin_relation_and_attrs(self.service.service_id, plugin_id) region_api.delPluginServiceRelation( self.response_region, self.tenant.tenant_name, plugin_id, self.service.service_alias) except Exception, e: pass result = general_message(400, "havs no downstream services", u'缺少关联应用,不能使用该类型插件') logger.exception(e) return Response(result, status=400)
def post(self, request): """ 用户登录接口 --- parameters: - name: nick_name description: 用户名 required: true type: string paramType: form - name: password description: 密码 required: true type: string paramType: form """ user_name = request.POST.get("nick_name", None) raw_passwd = request.POST.get("password", None) try: if not user_name or not raw_passwd: code = 405 result = general_message(code, "username is missing", "请填写用户名") return Response(result, status=code) elif not raw_passwd: code = 405 result = general_message(code, "password is missing", "请填写密码") return Response(result, status=code) user, msg, code = user_svc.is_exist(user_name, raw_passwd) if not user: code = 400 result = general_message(code, "authorization fail ", msg) return Response(result, status=code) else: u = authenticate(username=user_name, password=raw_passwd) http_client = HttpClient() url = "http://" + request.get_host( ) + '/console/api-token-auth' default_headers = { 'Connection': 'keep-alive', 'Content-Type': 'application/json' } data = {"nick_name": user_name, "password": raw_passwd} res, body = http_client._post(url, default_headers, json.dumps(data)) if res.get("status", 400) != 200: code = 400 result = general_message(code, "login failed", "登录失败") return Response(result, status=code) logger.debug("res {0} body {1}".format(res, body)) token = body.get("token", "") data = {'token': token} login(request, u) code = 200 result = general_message(code, "login success", "登录成功", bean=data) except Exception as e: logger.exception(e) code = 500 result = error_message(e.message) return Response(result, status=code)
def get(self, request, app_id, *args, **kwargs): res = group_service.list_kubernetes_services(self.tenant.tenant_id, self.region_name, app_id) result = general_message(200, "success", "查询成功", list=res) return Response(result)
def put(self, request, plugin_id, *args, **kwargs): """ 启停用应用插件 --- parameters: - name: tenantName description: 租户名 required: true type: string paramType: path - name: serviceAlias description: 服务别名 required: true type: string paramType: path - name: plugin_id description: 插件ID required: true type: string paramType: path - name: is_switch description: 插件启停状态 required: false type: boolean paramType: form - name: min_memory description: 插件内存 required: false type: boolean paramType: form """ try: if not plugin_id: return Response(general_message(400, "params error", "参数异常"), status=400) is_active = request.data.get("is_switch", True) service_plugin_relation = app_plugin_service.get_service_plugin_relation( self.service.service_id, plugin_id) if not service_plugin_relation: return Response(general_message(404, "params error", "未找到关联插件的构建版本"), status=404) else: build_version = service_plugin_relation.build_version pbv = plugin_version_service.get_by_id_and_version( plugin_id, build_version) # 更新内存和cpu min_memory = request.data.get("min_memory", pbv.min_memory) min_cpu = common_services.calculate_cpu( self.service.service_region, min_memory) data = dict() data["plugin_id"] = plugin_id data["switch"] = is_active data["version_id"] = build_version data["plugin_memory"] = min_memory data["plugin_cpu"] = min_cpu # 更新数据中心数据参数 region_api.update_plugin_service_relation( self.response_region, self.tenant.tenant_name, self.service.service_alias, data) # 更新本地数据 app_plugin_service.start_stop_service_plugin( self.service.service_id, plugin_id, is_active) pbv.min_memory = min_memory pbv.min_cpu = min_cpu pbv.save() result = general_message(200, "success", "操作成功") except Exception, e: logger.exception(e) result = error_message(e.message)
def post(self, request, plugin_id, *args, **kwargs): """ 应用安装插件 --- parameters: - name: tenantName description: 租户名 required: true type: string paramType: path - name: serviceAlias description: 服务别名 required: true type: string paramType: path - name: plugin_id description: 插件ID required: true type: string paramType: path - name: build_version description: 插件版本 required: true type: string paramType: form """ result = {} build_version = request.data.get("build_version", None) try: if not plugin_id: return Response(general_message(400, "params error", "参数错误"), status=400) if not build_version: plugin_version = plugin_version_service.get_newest_usable_plugin_version( plugin_id) build_version = plugin_version.build_version logger.debug( "start install plugin ! plugin_id {0} build_version {1}". format(plugin_id, build_version)) # 1.生成console数据,存储 code, msg = app_plugin_service.save_default_plugin_config( self.tenant, self.service, plugin_id, build_version) if code != 200: return Response(general_message(code, "install plugin fail", msg), status=code) # 2.从console数据库取数据生成region数据 region_config = app_plugin_service.get_region_config_from_db( self.service, plugin_id, build_version) data = dict() data["plugin_id"] = plugin_id data["switch"] = True data["version_id"] = build_version data.update(region_config) code, msg, relation = app_plugin_service.create_service_plugin_relation( self.service.service_id, plugin_id, build_version, "", True) if code != 200: return Response(general_message(code, "install plugin fail", msg), status=code) region_api.install_service_plugin(self.response_region, self.tenant.tenant_name, self.service.service_alias, data) result = general_message(200, "success", "安装成功") except Exception as e: logger.exception(e) app_plugin_service.delete_service_plugin_config( self.service, plugin_id) app_plugin_service.delete_service_plugin_relation( self.service, plugin_id) result = general_message(500, e.message, "插件安装失败") return Response(result, status=result["code"])
def post(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: region description: 需要备份的数据中心 required: true type: string paramType: form - name: team description: 需要迁移到的团队 required: true type: string paramType: form - name: backup_id description: 备份ID required: true type: string paramType: form - name: migrate_type description: 操作类型 required: true type: string paramType: form """ try: migrate_region = request.data.get("region", None) team = request.data.get("team", None) backup_id = request.data.get("backup_id", None) migrate_type = request.data.get("migrate_type", "migrate") if not team: return Response(general_message(400, "team is null", "请指明要迁移的团队"), status=400) migrate_team = team_services.get_tenant_by_tenant_name(team) if not migrate_team: return Response(general_message(404, "team is not found", "需要迁移的团队{0}不存在".format(team)), status=404) regions = region_services.get_team_usable_regions(migrate_team) if migrate_region not in [r.region_name for r in regions]: return Response(general_message(412, "region is not usable", "无法迁移至数据中心{0},请确保该数据中心可用且团队{1}已开通该数据中心权限".format(migrate_region, migrate_team.tenant_name)), status=412) code, msg, migrate_record = migrate_service.start_migrate(self.user, self.tenant, self.response_region, migrate_team, migrate_region, backup_id, migrate_type) if code != 200: return Response(general_message(code, "migrate failed", msg), status=code) result = general_message(200, "success", "操作成功,开始迁移应用", bean=migrate_record.to_dict()) except Exception as e: logger.exception(e) result = error_message(e.message) return Response(result, status=result["code"])
def get(self, request, tenantName, *args, **kwargs): """ 下载应用包 --- parameters: - name: tenantName description: 团队名称 required: true type: string paramType: path - name: format description: 导出类型 rainbond-app | docker-compose required: true type: string paramType: form - name: app_id description: rainbond app id required: true type: string paramType: query """ try: app_id = request.GET.get("app_id", None) export_format = request.GET.get("format", None) if not app_id: return Response(general_message(400, "app id is null", "请指明需要下载的应用"), status=400) if not export_format or export_format not in ("rainbond-app", "docker-compose"): return Response(general_message(400, "export format is illegal", "请指明下载的格式"), status=400) code, app = market_app_service.get_rain_bond_app_by_pk(app_id) if not app: return Response(general_message(404, "not found", "云市应用不存在"), status=404) export_record = export_service.get_export_record( export_format, app) if not export_record: return Response(general_message(400, "no export records", "该应用无导出记录,无法下载"), status=400) if export_record.status != "success": if export_record.status == "failed": return Response(general_message(400, "export failed", "应用导出失败,请重试"), status=400) if export_record.status == "exporting": return Response(general_message(400, "exporting", "应用正在导出中,请稍后重试"), status=400) req, file_name = export_service.get_file_down_req( export_format, tenantName, app) response = StreamingHttpResponse(self.file_iterator(req)) response['Content-Type'] = 'application/octet-stream' response[ 'Content-Disposition'] = 'attachment;filename="{0}"'.format( file_name) return response except Exception as e: logger.exception(e) result = error_message(e.message) return Response(result, status=result["code"])
def put(self, request, *args, **kwargs): """ 修改组件的某个端口(打开|关闭|修改协议|修改环境变量) --- parameters: - name: tenantName description: 租户名 required: true type: string paramType: path - name: serviceAlias description: 组件别名 required: true type: string paramType: path - name: port description: 端口号 required: true type: string paramType: path - name: action description: 操作类型(open_outer|close_outer|open_inner|close_inner|change_protocol|change_port_alias) required: true type: string paramType: form - name: port_alias description: 端口别名(修改端口别名时必须) required: false type: string paramType: - name: protocol description: 端口协议(修改端口协议时必须) required: false type: string paramType: path """ container_port = kwargs.get("port", None) action = request.data.get("action", None) port_alias = request.data.get("port_alias", None) protocol = request.data.get("protocol", None) if not container_port: return Response(general_message(400, "container_port not specify", u"端口变量名未指定"), status=400) if self.service.service_source == "third_party" and ("outer" in action): msg, msg_show, code = port_service.check_domain_thirdpart( self.tenant, self.service) if code != 200: logger.exception(msg, msg_show) return Response(general_message(code, msg, msg_show), status=code) code, msg, data = port_service.manage_port(self.tenant, self.service, self.response_region, int(container_port), action, protocol, port_alias) if code != 200: return Response(general_message(code, "change port fail", msg), status=code) result = general_message(200, "success", "操作成功", bean=model_to_dict(data)) return Response(result, status=result["code"])
def put(self, request, *args, **kwargs): """ 组件拓扑图打开(关闭)对外端口 :param request: :param args: :param kwargs: :return: """ try: open_outer = request.data.get("open_outer", False) close_outer = request.data.get("close_outer", False) container_port = request.data.get("container_port", None) # 开启对外端口 if open_outer: tenant_service_port = port_service.get_service_port_by_port( self.service, int(container_port)) if self.service.service_source == "third_party": msg, msg_show, code = port_service.check_domain_thirdpart( self.tenant, self.service) if code != 200: logger.exception(msg, msg_show) return Response(general_message(code, msg, msg_show), status=code) code, msg, data = port_service.manage_port( self.tenant, self.service, self.response_region, int(container_port), "open_outer", tenant_service_port.protocol, tenant_service_port.port_alias) if code != 200: return Response(general_message(412, "open outer fail", u"打开对外端口失败"), status=412) return Response(general_message(200, "open outer success", u"开启成功"), status=200) # 关闭该组件所有对外端口 if close_outer: tenant_service_ports = port_service.get_service_ports( self.service) for tenant_service_port in tenant_service_ports: code, msg, data = port_service.manage_port( self.tenant, self.service, self.response_region, tenant_service_port.container_port, "close_outer", tenant_service_port.protocol, tenant_service_port.port_alias) if code != 200: return Response(general_message( 412, "open outer fail", u"关闭对外端口失败"), status=412) return Response(general_message(200, "close outer success", u"关闭对外端口成功"), status=200) # 校验要依赖的组件是否开启了对外端口 open_outer_services = port_repo.get_service_ports( self.tenant.tenant_id, self.service.service_id).filter(is_outer_service=True) if not open_outer_services: if self.service.service_source == "third_party": msg, msg_show, code = port_service.check_domain_thirdpart( self.tenant, self.service) if code != 200: logger.exception(msg, msg_show) return Response(general_message(code, msg, msg_show), status=code) service_ports = port_repo.get_service_ports( self.tenant.tenant_id, self.service.service_id) port_list = [ service_port.container_port for service_port in service_ports ] if len(port_list) == 1: # 一个端口直接开启 tenant_service_port = port_service.get_service_port_by_port( self.service, int(port_list[0])) code, msg, data = port_service.manage_port( self.tenant, self.service, self.response_region, int(port_list[0]), "open_outer", tenant_service_port.protocol, tenant_service_port.port_alias) if code != 200: return Response(general_message( 412, "open outer fail", u"打开对外端口失败"), status=412) return Response(general_message(200, "open outer success", u"开启成功"), status=200) else: # 多个端口需要用户选择后开启 return Response(general_message( 201, "the service does not open an external port", u"该组件未开启对外端口", list=port_list), status=201) else: return Response(general_message( 202, "the service has an external port open", u"该组件已开启对外端口"), status=200) except Exception as e: logger.exception(e) result = error_message(e.message) return Response(result, status=result["code"])
def get(self, request, *args, **kwargs): """ 获取组件的端口信息 --- parameters: - name: tenantName description: 租户名 required: true type: string paramType: path - name: serviceAlias description: 组件别名 required: true type: string paramType: path """ try: tenant_service_ports = port_service.get_service_ports(self.service) port_list = [] for port in tenant_service_ports: port_info = port.to_dict() variables = port_service.get_port_variables( self.tenant, self.service, port) port_info["environment"] = variables["environment"] outer_url = "" inner_url = "" if port_info["environment"]: if port.is_inner_service: try: inner_host, inner_port = None, None for pf in port_info["environment"]: if pf.get("name"): if pf.get("name").endswith("HOST"): inner_host = pf.get("value") elif pf.get("name").endswith("PORT"): inner_port = pf.get("value") inner_url = "{0}:{1}".format( inner_host, inner_port) except Exception as se: logger.exception(se) port_info["inner_url"] = inner_url outer_service = variables.get("outer_service", None) if outer_service: outer_url = "{0}:{1}".format( variables["outer_service"]["domain"], variables["outer_service"]["port"]) port_info["outer_url"] = outer_url port_info["bind_domains"] = [] bind_domains = domain_service.get_port_bind_domains( self.service, port.container_port) if bind_domains: for bind_domain in bind_domains: if not bind_domain.domain_path: bind_domain.domain_path = '/' bind_domain.save() port_info["bind_domains"] = [ domain.to_dict() for domain in bind_domains ] bind_tcp_domains = domain_service.get_tcp_port_bind_domains( self.service, port.container_port) if bind_tcp_domains: port_info["bind_tcp_domains"] = [ domain.to_dict() for domain in bind_tcp_domains ] else: port_info["bind_tcp_domains"] = [] port_list.append(port_info) result = general_message(200, "success", "查询成功", list=port_list) except Exception as e: logger.exception(e) result = error_message(e.message) return Response(result, status=result["code"])
def post(self, request, *args, **kwargs): """ 为组件添加端口 --- parameters: - name: tenantName description: 租户名 required: true type: string paramType: path - name: serviceAlias description: 组件别名 required: true type: string paramType: path - name: port description: 端口 required: true type: integer paramType: form - name: protocol description: 端口协议 required: true type: string paramType: form - name: port_alias description: 端口别名 required: true type: string paramType: form - name: is_inner_service description: 是否打开对内组件 required: true type: boolean paramType: form - name: is_outer_service description: 是否打开对外组件 required: true type: boolean paramType: form """ port = request.data.get("port", None) protocol = request.data.get("protocol", None) port_alias = request.data.get("port_alias", None) is_inner_service = request.data.get('is_inner_service', False) is_outer_service = request.data.get('is_outer_service', False) try: if not port: return Response(general_message(400, "params error", u"缺少端口参数"), status=400) if not protocol: return Response(general_message(400, "params error", u"缺少协议参数"), status=400) if not port_alias: port_alias = self.service.service_alias.upper().replace( "-", "_") + str(port) code, msg, port_info = port_service.add_service_port( self.tenant, self.service, port, protocol, port_alias, is_inner_service, is_outer_service) if code != 200: return Response(general_message(code, "add port error", msg), status=code) result = general_message(200, "success", "端口添加成功", bean=model_to_dict(port_info)) except Exception as e: logger.exception(e) result = error_message(e.message) return Response(result, status=result["code"])
def post(self, request, *args, **kwargs): """ 创建第三方组件 """ group_id = request.data.get("group_id", -1) service_cname = request.data.get("service_cname", None) endpoints = request.data.get("endpoints", None) endpoints_type = request.data.get("endpoints_type", None) if not service_cname: return Response(general_message(400, "service_cname is null", "组件名未指明"), status=400) if not endpoints and endpoints_type != "api": return Response(general_message(400, "end_point is null", "end_point未指明"), status=400) validate_endpoints_info(endpoints) code, msg_show, new_service = app_service.create_third_party_app( self.response_region, self.tenant, self.user, service_cname, endpoints, endpoints_type) if code != 200: return Response(general_message(code, "service create fail", msg_show), status=code) # 添加组件所在组 code, msg_show = group_service.add_service_to_group( self.tenant, self.response_region, group_id, new_service.service_id) if code != 200: logger.debug("service.create", msg_show) if endpoints_type == "discovery": # 添加username,password信息 if "username" in endpoints and "password" in endpoints: if endpoints["username"] or endpoints["password"]: app_service.create_service_source_info( self.tenant, new_service, endpoints["username"], endpoints["password"]) bean = new_service.to_dict() if endpoints_type == "api": # 生成秘钥 deploy = deploy_repo.get_deploy_relation_by_service_id( service_id=new_service.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_service.service_id) bean["api_service_key"] = api_secret_key bean["url"] = api_url result = general_message(200, "success", "创建成功", bean=bean) return Response(result, status=result["code"])
def post(self, request, service_id, *args, **kwargs): try: service_obj = TenantServiceInfo.objects.get(service_id=service_id) if not service_obj: result = general_message(400, "failed", "服务不存在") return Response(result, status=400) tenant_obj = Tenants.objects.get(tenant_id=service_obj.tenant_id) service_webhook = service_webhooks_repo.get_service_webhooks_by_service_id_and_type( service_obj.service_id, "image_webhooks") if not service_webhook.state: result = general_message(400, "failed", "服务关闭了自动构建") return Response(result, status=400) # 校验 repository = request.data.get("repository") if not repository: logger.debug("缺少repository信息") result = general_message(400, "failed", "缺少repository信息") return Response(result, status=400) push_data = request.data.get("push_data") pusher = push_data.get("pusher") tag = push_data.get("tag") repo_name = repository.get("repo_name") if not repo_name: repository_namespace = repository.get("namespace") repository_name = repository.get("name") if repository_namespace and repository_name: # maybe aliyun repo add fake host repo_name = "fake.repo.aliyun.com/" + repository_namespace + "/" + repository_name else: repo_name = repository.get("repo_full_name") if not repo_name: result = general_message(400, "failed", "缺少repository名称信息") return Response(result, status=400) repo_ref = reference.Reference.parse(repo_name) _, repo_name = repo_ref.split_hostname() ref = reference.Reference.parse(service_obj.image) hostname, name = ref.split_hostname() if repo_name != name: result = general_message(400, "failed", "镜像名称与服务构建源不符") return Response(result, status=400) # 标签匹配 if service_webhook.trigger: # 如果有正则表达式根据正则触发 if not re.match(service_webhook.trigger, tag): result = general_message(400, "failed", "镜像tag与正则表达式不匹配") return Response(result, status=400) service_repo.change_service_image_tag(service_obj, tag) else: # 如果没有根据标签触发 if tag != ref['tag']: result = general_message(400, "failed", "镜像tag与服务构建源不符") return Response(result, status=400) # 获取应用状态 status_map = app_service.get_service_status(tenant_obj, service_obj) status = status_map.get("status", None) user_obj = Users.objects.get(user_id=service_obj.creater) committer_name = pusher if status != "undeploy" and status != "closed" \ and status != "closed": return user_services.deploy_service( tenant_obj=tenant_obj, service_obj=service_obj, user=user_obj, committer_name=committer_name) else: result = general_message(400, "failed", "应用状态处于关闭中,不支持自动构建") return Response(result, status=400) except Exception as e: logger.exception(e) result = error_message(e.message) return Response(result, status=500)
def get(self, request, *args, **kwargs): """ 获取作用对象的event事件 --- parameters: - name: tenantName description: 租户名 required: true type: string paramType: path - name: target description: 作用对象 required: true type: string paramType: path - name: targetAlias description: 作用对象别名 required: true type: string paramType: path - name: page description: 页号 required: false type: integer paramType: query - name: page_size description: 每页大小 required: false type: integer paramType: query """ page = request.GET.get("page", 1) page_size = request.GET.get("page_size", 6) target = request.GET.get("target", "") targetAlias = request.GET.get("targetAlias", "") if targetAlias == "": target = "tenant" targetAlias = self.tenant.tenant_name if target == "service": services = TenantServiceInfo.objects.filter( service_alias=targetAlias, tenant_id=self.tenant.tenant_id) if len(services) > 0: self.service = services[0] target_id = self.service.service_id events, total, has_next = event_service.get_target_events( target, target_id, self.tenant, self.service.service_region, int(page), int(page_size)) result = general_message(200, "success", "查询成功", list=events, total=total, has_next=has_next) else: result = general_message(200, "success", "查询成功", list=[], total=0, has_next=False) elif target == "tenant": target_id = self.tenant.tenant_id events, total, has_next = event_service.get_target_events( target, target_id, self.tenant, self.tenant.region, int(page), int(page_size)) result = general_message(200, "success", "查询成功", list=events, total=total, has_next=has_next) return Response(result, status=result["code"])
def get(self, request, *args, **kwargs): result = general_message(200, u"success", "获取成功", bean={"check_uuid": self.service.check_uuid}) return Response(result, status=200)
def check_perm(perm, user, tenantName=None, serviceAlias=None): if isinstance(user, AnonymousUser): raise PermissionDenied('this resource need login status', redirect_url='/login') if tenantName is None: raise UrlParseError(500, 'tenantName is None') if not hasattr(user, 'actions'): user.actions = UserActions() p = PermActions() try: tenant = Tenants.objects.get(tenant_name=tenantName) identitys = team_services.get_user_perm_identitys_in_permtenant( user_id=user.pk, tenant_name=tenant.tenant_name) role_id_list = team_services.get_user_perm_role_id_in_permtenant( user_id=user.pk, tenant_name=tenant.tenant_name) if not identitys and not role_id_list: raise PermRelTenant.DoesNotExist tenant_actions_tuple = () if identitys: tenant_identity = get_highest_identity(identitys) tenant_actions = p.keys( 'tenant_{0}_actions'.format(tenant_identity)) tenant_actions_tuple += tenant_actions if role_id_list: for role_id in role_id_list: perm_tuple = role_perm_repo.get_perm_by_role_id( role_id=role_id) tenant_actions_tuple += perm_tuple user.actions.set_actions('tenant', tuple(set(tenant_actions_tuple))) if serviceAlias is not None: service = TenantServiceInfo.objects.get( tenant_id=tenant.tenant_id, service_alias=serviceAlias) user_service_perms_id_list = ServiceRelPerms.objects.filter( user_id=user.pk, service_id=service.pk).values_list("perm_id", flat=True) perm_codename_list = role_perm_repo.get_perm_list_by_perm_id_list( perm_id_list=user_service_perms_id_list) user.actions.set_actions('service', perm_codename_list) except Tenants.DoesNotExist: raise UrlParseError( 404, 'no matching tenantName for {0}'.format(tenantName)) except TenantServiceInfo.DoesNotExist: raise UrlParseError( 404, 'no matching serviceAlias for {0}'.format(serviceAlias)) except PermRelTenant.DoesNotExist: tenant = Tenants.objects.filter(tenant_name=tenantName)[0] if not user.is_sys_admin and tenantName != "grdemo": raise UrlParseError( 403, 'no permissions for user {0} on tenant {1}'.format( user.nick_name, tenant.tenant_name)) user.actions.set_actions('tenant', p.keys('tenant_viewer_actions')) except PermRelService.DoesNotExist: pass # if user.is_sys_admin: # return True if perm in user.actions: return True raise BusinessException( Response(general_message(403, "you don't have enough permissions", "您无权限执行此操作"), status=403))
def put(self, request, plugin_id, *args, **kwargs): """ 应用插件配置更新 --- parameters: - name: tenantName description: 租户名 required: true type: string paramType: path - name: serviceAlias description: 服务别名 required: true type: string paramType: path - name: plugin_id description: 插件ID required: true type: string paramType: path - name: body description: 配置内容 required: true type: string paramType: body """ sid = None try: logger.debug("update service plugin config ") config = json.loads(request.body) logger.debug("====> {0}".format(config)) if not config: return Response(general_message(400, "params error", "参数配置不可为空"), status=400) pbv = plugin_version_service.get_newest_usable_plugin_version( plugin_id) if not pbv: return Response(general_message(400, "no usable plugin version", "无最新更新的版本信息,无法更新配置"), status=400) sid = transaction.savepoint() # 删除原有配置 app_plugin_service.delete_service_plugin_config( self.service, plugin_id) # 全量插入新配置 app_plugin_service.update_service_plugin_config( self.service, plugin_id, pbv.build_version, config) # 更新数据中心配置 region_config = app_plugin_service.get_region_config_from_db( self.service, plugin_id, pbv.build_version) region_api.update_service_plugin_config(self.response_region, self.tenant.tenant_name, self.service.service_alias, plugin_id, region_config) # 提交操作 transaction.savepoint_commit(sid) result = general_message(200, "success", "配置更新成功") except Exception as e: logger.exception(e) if sid: transaction.savepoint_rollback(sid) result = error_message(e.message) return Response(result, result["code"])
def get(self, request, *args, **kwargs): """ 登录页面获取云帮Logo、标题、github、gitlab配置信息(不要Authorization头) --- """ try: # 判断是否已经初始化权限默认数据,没有则初始化 status = role_perm_repo.initialize_permission_settings() code = 200 data = dict() logo = config_service.get_image() host_name = request.get_host() build_absolute_uri = request.build_absolute_uri() scheme = "http" if build_absolute_uri.startswith("https"): scheme = "https" data["logo"] = "{0}".format(str(logo)) # 判断是否为公有云 if settings.MODULES.get('SSO_LOGIN'): data["url"] = os.getenv("SSO_BASE_URL", "https://sso.goodrain.com") + "/#/login/" data["is_public"] = True else: data["url"] = "{0}://{1}/index#/user/login".format(scheme, request.get_host()) data["is_public"] = False title = config_service.get_config_by_key("TITLE") if not title: config = config_service.add_config("TITLE", "好雨云帮", "string", "云帮title") title = config.value data["title"] = title if settings.MODULES.get('SSO_LOGIN'): data["is_user_register"] = True else: users = user_repo.get_all_users() if users: data["is_user_register"] = True else: data["is_user_register"] = False is_regist = config_service.get_config_by_key("REGISTER_STATUS") if not is_regist: is_regist = config_service.add_config( key="REGISTER_STATUS", default_value="yes", type="string", desc="开启/关闭注册" ).value if is_regist == "yes": data["is_regist"] = True else: data["is_regist"] = False # if register_config[0].value != "yes": # data["is_regist"] = False # else: # data["is_regist"] = True github_config = config_service.get_github_config() data["github_config"] = github_config gitlab_config = config_service.get_gitlab_config() data["gitlab_config"] = gitlab_config data["eid"] = None enterprise = enterprise_repo.get_enterprise_first() if enterprise: data["eid"] = enterprise.enterprise_id data["version"] = os.getenv("RELEASE_DESC","public-cloud") result = general_message(code, "query success", "Logo获取成功", bean=data, initialize_info=status) return Response(result, status=code) except Exception as e: logger.exception(e) result = error_message(e.message) return Response(result)
def post(self, request, team_name, user_name, *args, **kwargs): """ 修改成员权限 --- parameters: - name: team_name description: 团队名 required: true type: string paramType: path - name: user_name description: 被修改权限的团队成员 required: true type: string paramType: path - name: identitys description: 权限 格式 {"identitys": "viewer,access"} required: true type: string paramType: body """ try: perm_list = team_services.get_user_perm_identitys_in_permtenant( user_id=request.user.user_id, tenant_name=team_name) perm_tuple = team_services.get_user_perm_in_tenant( user_id=request.user.user_id, tenant_name=team_name) no_auth = ("owner" not in perm_list) and ("admin" not in perm_list) if no_auth: code = 400 result = general_message(code, "no identity", "您不是管理员,没有权限做此操作") else: code = 200 new_identitys = request.data.get("identitys", None) if new_identitys: new_identitys = new_identitys.split( ',') if new_identitys else [] other_user = user_services.get_user_by_username( user_name=user_name) if other_user.user_id == request.user.user_id: result = general_message(400, "failed", "您不能修改自己的权限!") return Response(result, status=400) team_services.change_tenant_identity( user_id=other_user.user_id, tenant_name=team_name, new_identitys=new_identitys) result = general_message(code, "identity modify success", "{}权限修改成功".format(user_name)) else: result = general_message(400, "identity failed", "修改权限时,权限不能为空") except SameIdentityError as e: logger.exception(e) code = 400 result = general_message(code, "identity exist", "该用户已拥有此权限") except UserNotExistError as e: logger.exception(e) code = 400 result = general_message(code, "users not exist", "该用户不存在") except Exception as e: logger.exception(e) code = 500 result = error_message(e.message) return Response(result, status=code)
def post(self, request, *args, **kwargs): """ 插件创建 --- parameters: - name: tenantName description: 团队名 required: true type: string paramType: path - name: plugin_alias description: 插件名称 required: true type: string paramType: form - name: build_source description: 构建来源 dockerfile | image required: true type: string paramType: form - name: min_memory description: 最小内存 required: true type: integer paramType: form - name: category description: 插件类别 net-plugin:down|net-plugin:up|analyst-plugin:perf|init-plugin|general-plugin required: false type: string paramType: form - name: build_cmd description: 构建命令 required: false type: string paramType: form - name: code_repo description: dockerfile构建代码仓库地址,选择dockerfile时必须 required: false type: string paramType: form - name: code_version description: 代码版本,默认master required: false type: string paramType: form - name: image description: 镜像构建时镜像名称 required: false type: string paramType: form - name: desc description: 镜像说明 required: true type: string paramType: form """ # 必要参数 plugin_alias = request.data.get("plugin_alias", None) build_source = request.data.get("build_source", None) min_memory = request.data.get("min_memory", None) category = request.data.get("category", None) desc = request.data.get("desc", None) # 非必要参数 build_cmd = request.data.get("build_cmd", None) code_repo = request.data.get("code_repo", None) code_version = request.data.get("code_version", None) image = request.data.get("image", None) tenant_plugin = None plugin_build_version = None try: if not plugin_alias: return Response(general_message(400, "plugin alias is null", "插件名称未指明"), status=400) if not build_source: return Response(general_message(400, "build source is null", "构建来源未指明"), status=400) if not min_memory: return Response(general_message(400, "plugin min_memroy is null", "插件内存大小未指明"), status=400) if not category: return Response(general_message(400, "plugin category is null", "插件类别未指明"), status=400) else: if category not in ( PluginCategoryConstants.OUTPUT_NET, PluginCategoryConstants.INPUT_NET, PluginCategoryConstants.PERFORMANCE_ANALYSIS, PluginCategoryConstants.INIT_TYPE, PluginCategoryConstants.COMMON_TYPE): return Response(general_message( 400, "plugin category is wrong", "插件类别参数错误,详情请参数API说明"), status=400) if not desc: return Response(general_message(400, "plugin desc is null", "请填写插件描述"), status=400) image_tag = "" if image: image_and_tag = image.split(":") if len(image_and_tag) > 1: image = image_and_tag[0] image_tag = image_and_tag[1] else: image = image_and_tag[0] image_tag = "latest" # 创建基本信息 code, msg, tenant_plugin = plugin_service.create_tenant_plugin( self.tenant, self.user.user_id, self.response_region, desc, plugin_alias, category, build_source, image, code_repo) if code != 200: return Response(general_message(code, "create plugin error", msg), status=code) # 创建插件版本信息 plugin_build_version = plugin_version_service.create_build_version( self.response_region, tenant_plugin.plugin_id, self.tenant.tenant_id, self.user.user_id, "", "unbuild", min_memory, build_cmd, image_tag, code_version) #数据中心创建插件 code, msg = plugin_service.create_region_plugin( self.response_region, self.tenant, tenant_plugin) if code != 200: plugin_service.delete_tenant_plugin(tenant_plugin.plugin_id) plugin_version_service.delete_build_version_by_id_and_version( tenant_plugin.plugin_id, plugin_build_version.build_version, True) return Response(general_message(code, "create plugin error", msg), status=code) bean = tenant_plugin.to_dict() bean["build_version"] = plugin_build_version.build_version bean["code_version"] = plugin_build_version.code_version bean["build_status"] = plugin_build_version.build_status bean["update_info"] = plugin_build_version.update_info bean["image_tag"] = plugin_build_version.image_tag result = general_message(200, "success", "创建成功", bean=bean) except Exception as e: logger.exception(e) result = error_message(e.message) if tenant_plugin: plugin_service.delete_tenant_plugin(tenant_plugin.plugin_id) if plugin_build_version: plugin_version_service.delete_build_version_by_id_and_version( tenant_plugin.plugin_id, plugin_build_version.build_version, True) return Response(result, status=result["code"])
def get(self, request, *args, **kwargs): """ 获取服务指定模式的探针 --- parameters: - name: tenantName description: 租户名 required: true type: string paramType: path - name: serviceAlias description: 服务别名 required: true type: string paramType: path - name: mode description: 不健康处理方式(readiness|liveness|ignore) required: true type: string paramType: query """ try: if self.service.service_source == "third_party": code, msg, probe = probe_service.get_service_probe( self.service) if code != 200: return Response( general_message(code, "get probe error", msg)) result = general_message(200, "success", "查询成功", bean=probe.to_dict()) else: mode = request.GET.get("mode", None) if not mode: code, msg, probe = probe_service.get_service_probe( self.service) if code != 200: return Response( general_message(code, "get probe error", msg)) result = general_message(200, "success", "查询成功", bean=probe.to_dict()) else: code, msg, probe = probe_service.get_service_probe_by_mode( self.service, mode) if code != 200: return Response( general_message(code, "get probe error", msg)) if not mode: result = general_message(200, "success", "查询成功", list=probe) else: result = general_message(200, "success", "查询成功", bean=probe.to_dict()) return Response(result, status=result["code"]) except Exception as e: logger.exception(e) result = error_message(e.message) return Response(result, status=result["code"])
def get_response(self): if self.response: return self.response else: return Response(general_message(10401, "failed", "无数据返回"), status=500)
def get(self, request, app_id, *args, **kwargs): status = group_service.get_app_status(self.tenant, self.region_name, app_id) result = general_message(200, "success", "查询成功", list=status) return Response(result)
def post(self, request, service_id, *args, **kwargs): """ github,gitlab 回调接口 触发自动部署 """ try: service_obj = TenantServiceInfo.objects.get(service_id=service_id) tenant_obj = Tenants.objects.get(tenant_id=service_obj.tenant_id) service_webhook = service_webhooks_repo.get_service_webhooks_by_service_id_and_type( service_obj.service_id, "code_webhooks") if not service_webhook.state: logger.debug("没开启webhooks自动部署") result = general_message(400, "failed", "没有开启此功能") return Response(result, status=400) # github github_event = request.META.get("HTTP_X_GITHUB_EVENT", None) user_agent = request.META.get("HTTP_USER_AGENT", None) if user_agent: user_agent = user_agent.split("/")[0] if github_event and user_agent == "GitHub-Hookshot": if github_event == "ping": logger.debug("支持此事件类型") result = general_message(200, "success", "支持测试连接") return Response(result, status=200) if github_event != "push" and github_event != "ping": logger.debug("不支持此事件类型") result = general_message(400, "failed", "不支持此事件类型") return Response(result, status=400) commits_info = request.data.get("head_commit") if not commits_info: logger.debug("提交信息获取失败") result = general_message(400, "failed", "提交信息获取失败") return Response(result, status=400) message = commits_info.get("message") keyword = "@" + service_webhook.deploy_keyword if keyword not in message: logger.debug("提交信息无效") result = general_message(200, "failed", "提交信息无效") return Response(result, status=200) # signature = request.META.get("HTTP_X_HUB_SIGNATURE", None) ref = request.data.get("ref") if not ref: logger.debug("获取分支信息失败") result = general_message(200, "failed", "获取分支信息失败") return Response(result, status=200) ref = ref.split("/")[2] if not service_obj.code_version == ref: logger.debug("当前分支与部署分支不同") result = general_message(200, "failed", "提交分支与部署分支不同") return Response(result, status=200) repository = request.data.get("repository") if not repository: logger.debug("却少repository信息") result = general_message(200, "failed", "却少repository信息") return Response(result, status=200) clone_url = repository.get("clone_url") ssh_url = repository.get("ssh_url") code, msg, msg_show = self._check_warehouse(service_obj.git_url, clone_url, ssh_url) if code != 200: return Response(general_message(200, msg, msg_show), status=200) # 获取应用状态 status_map = app_service.get_service_status(tenant_obj, service_obj) status = status_map.get("status", None) logger.debug(status) user_obj = Users.objects.get(user_id=service_obj.creater) committer_name = commits_info.get("author").get("username") if status == "running" or status == "abnormal": return user_services.deploy_service( tenant_obj=tenant_obj, service_obj=service_obj, user=user_obj, committer_name=committer_name) else: logger.debug("应用状态异常") result = general_message(400, "failed", "应用状态不支持") return Response(result, status=400) # gitlab elif request.META.get("HTTP_X_GITLAB_EVENT", None): logger.debug(request.data) commits_info = request.data.get("commits") if not commits_info: logger.debug("提交信息获取失败") result = general_message(400, "failed", "提交信息获取失败") return Response(result, status=400) message = commits_info[-1].get("message") keyword = "@" + service_webhook.deploy_keyword if keyword not in message: logger.debug("提交信息无效") result = general_message(200, "failed", "提交信息无效") return Response(result, status=200) event_name = request.data.get("object_kind", None) logger.debug("kind", event_name) if event_name == "ping": logger.debug("支持此事件类型") result = general_message(200, "success", "支持测试连接") return Response(result, status=200) if event_name != "push" and event_name != "ping": logger.debug("不支持此事件类型") result = general_message(200, "failed", "不支持此事件类型") return Response(result, status=200) ref = request.data.get("ref") if not ref: logger.debug("获取分支信息失败") result = general_message(200, "failed", "获取分支信息失败") return Response(result, status=200) ref = ref.split("/")[2] if not service_obj.code_version == ref: logger.debug("当前分支与部署分支不同") result = general_message(200, "failed", "提交分支与部署分支不同") return Response(result, status=200) repository = request.data.get("repository") if not repository: logger.debug("却少repository信息") result = general_message(200, "failed", "却少repository信息") return Response(result, status=200) git_http_url = repository.get("git_http_url") gitlab_ssh_url = repository.get("git_ssh_url") code, msg, msg_show = self._check_warehouse(service_obj.git_url, git_http_url, gitlab_ssh_url) if code != 200: return Response(general_message(200, msg, msg_show), status=200) # 获取应用状态 status_map = app_service.get_service_status(tenant_obj, service_obj) status = status_map.get("status", None) user = Users.objects.get(user_id=service_obj.creater) committer_name = commits_info[-1].get("author").get("name") logger.debug("status", status_map) if status == "running" or status == "abnormal": return user_services.deploy_service( tenant_obj=tenant_obj, service_obj=service_obj, user=user, committer_name=committer_name) else: logger.debug("应用状态异常") result = general_message(200, "failed", "应用状态不支持") return Response(result, status=200) # gitee elif request.META.get("HTTP_X_GITEE_EVENT", None) or \ request.META.get("HTTP_X_GIT_OSCHINA_EVENT", None): logger.debug(request.data) commits_info = request.data.get("head_commit") if not commits_info: logger.debug("提交信息获取失败") result = general_message(400, "failed", "提交信息获取失败") return Response(result, status=400) message = commits_info.get("message") keyword = "@" + service_webhook.deploy_keyword if keyword not in message: logger.debug("提交信息无效") result = general_message(200, "failed", "提交信息无效") return Response(result, status=200) ref = request.data.get("ref") if not ref: logger.debug("获取分支信息失败") result = general_message(200, "failed", "获取分支信息失败") return Response(result, status=200) ref = ref.split("/")[2] if not service_obj.code_version == ref: logger.debug("当前分支与部署分支不同") result = general_message(200, "failed", "提交分支与部署分支不同") return Response(result, status=200) repository = request.data.get("repository") if not repository: logger.debug("却少repository信息") result = general_message(200, "failed", "却少repository信息") return Response(result, status=200) clone_url = repository.get("clone_url") ssh_url = repository.get("ssh_url") code, msg, msg_show = self._check_warehouse(service_obj.git_url, clone_url, ssh_url) if code != 200: return Response(general_message(200, msg, msg_show), status=200) # 获取应用状态 status_map = app_service.get_service_status(tenant_obj, service_obj) status = status_map.get("status", None) logger.debug(status) user_obj = Users.objects.get(user_id=service_obj.creater) committer_name = commits_info.get("author").get("username") if status == "running" or status == "abnormal": return user_services.deploy_service( tenant_obj=tenant_obj, service_obj=service_obj, user=user_obj, committer_name=committer_name) else: logger.debug("应用状态异常") result = general_message(200, "failed", "应用状态不支持") return Response(result, status=200) # gogs elif request.META.get("HTTP_X_GOGS_EVENT", None): logger.debug(request.data) commits_info = request.data.get("commits") if not commits_info: logger.debug("提交信息获取失败") result = general_message(400, "failed", "提交信息获取失败") return Response(result, status=400) message = commits_info[0].get("message") keyword = "@" + service_webhook.deploy_keyword if keyword not in message: logger.debug("提交信息无效") result = general_message(200, "failed", "提交信息无效") return Response(result, status=200) ref = request.data.get("ref") if not ref: logger.debug("获取分支信息失败") result = general_message(200, "failed", "获取分支信息失败") return Response(result, status=200) ref = ref.split("/")[2] if not service_obj.code_version == ref: logger.debug("当前分支与部署分支不同") result = general_message(200, "failed", "提交分支与部署分支不同") return Response(result, status=200) repository = request.data.get("repository") if not repository: logger.debug("却少repository信息") result = general_message(200, "failed", "却少repository信息") return Response(result, status=200) clone_url = repository.get("clone_url") ssh_url = repository.get("ssh_url") code, msg, msg_show = self._check_warehouse(service_obj.git_url, clone_url, ssh_url) if code != 200: return Response(general_message(200, msg, msg_show), status=200) # 获取应用状态 status_map = app_service.get_service_status(tenant_obj, service_obj) status = status_map.get("status", None) logger.debug(status) user_obj = Users.objects.get(user_id=service_obj.creater) committer_name = commits_info[0].get("author").get("username") if status == "running" or status == "abnormal": return user_services.deploy_service( tenant_obj=tenant_obj, service_obj=service_obj, user=user_obj, committer_name=committer_name) else: logger.debug("应用状态异常") result = general_message(200, "failed", "应用状态不支持") return Response(result, status=200) # coding elif request.META.get("HTTP_X_CODING_EVENT", None): coding_event = request.META.get("HTTP_X_CODING_EVENT", None) if coding_event == "ping": logger.debug("支持此事件类型") result = general_message(200, "success", "支持测试连接") return Response(result, status=200) if coding_event != "push" and coding_event != "ping": logger.debug("不支持此事件类型") result = general_message(400, "failed", "不支持此事件类型") return Response(result, status=400) commits_info = request.data.get("head_commit") if not commits_info: logger.debug("提交信息获取失败") result = general_message(400, "failed", "提交信息获取失败") return Response(result, status=400) message = commits_info.get("message") keyword = "@" + service_webhook.deploy_keyword if keyword not in message: logger.debug("提交信息无效") result = general_message(200, "failed", "提交信息无效") return Response(result, status=200) ref = request.data.get("ref") if not ref: logger.debug("获取分支信息失败") result = general_message(200, "failed", "获取分支信息失败") return Response(result, status=200) ref = ref.split("/")[2] if not service_obj.code_version == ref: logger.debug("当前分支与部署分支不同") result = general_message(200, "failed", "提交分支与部署分支不同") return Response(result, status=200) repository = request.data.get("repository") if not repository: logger.debug("却少repository信息") result = general_message(200, "failed", "却少repository信息") return Response(result, status=200) clone_url = repository.get("clone_url") ssh_url = repository.get("ssh_url") code, msg, msg_show = self._check_warehouse(service_obj.git_url, clone_url, ssh_url) if code != 200: return Response(general_message(200, msg, msg_show), status=200) # 获取应用状态 status_map = app_service.get_service_status(tenant_obj, service_obj) status = status_map.get("status", None) logger.debug(status) user_obj = Users.objects.get(user_id=service_obj.creater) committer_name = commits_info.get("author").get("username") if status == "running" or status == "abnormal": return user_services.deploy_service( tenant_obj=tenant_obj, service_obj=service_obj, user=user_obj, committer_name=committer_name) else: logger.debug("应用状态异常") result = general_message(400, "failed", "应用状态不支持") return Response(result, status=400) else: logger.debug("暂时仅支持github与gitlab") result = general_message(400, "failed", "暂时仅支持github与gitlab哦~") return Response(result, status=400) except Tenants.DoesNotExist as e: logger.exception(e) logger.error(e) return Response(e.message, status=400) except TenantServiceInfo.DoesNotExist as e: logger.exception(e) logger.error(e) return Response(e.message, status=400) except Exception as e: logger.exception(e) logger.error(e) return Response(e.message, status=500)
region_api.delPluginServiceRelation( self.response_region, self.tenant.tenant_name, plugin_id, self.service.service_alias) except Exception, e: pass result = general_message(400, "havs no downstream services", u'缺少关联应用,不能使用该类型插件') logger.exception(e) return Response(result, status=400) except Exception, e: try: plugin_svc.del_service_plugin_relation_and_attrs(self.service.service_id, plugin_id) region_api.delPluginServiceRelation( self.response_region, self.tenant.tenant_name, plugin_id, self.service.service_alias) except Exception, e: logger.exception(e) pass result = general_message(500, "service relate plugin error", u'关联插件失败') logger.exception(e) return Response(result, status=500) @perm_required('manage_service') def delete(self, request, plugin_id, *args, **kwargs): """ 应用卸载插件 --- parameters: - name: tenantName description: 租户名 required: true type: string paramType: path - name: serviceAlias
def get(self, request, *args, **kwargs): """ 判断该应用是否有webhooks自动部署功能,有则返回URL """ try: deployment_way = request.GET.get("deployment_way", None) if not deployment_way: result = general_message(400, "Parameter cannot be empty", "缺少参数") return Response(result, status=400) tenant_id = self.tenant.tenant_id service_alias = self.service.service_alias service_obj = TenantServiceInfo.objects.filter(tenant_id=tenant_id, service_alias=service_alias)[0] if service_obj.service_source == AppConstants.MARKET: result = general_message(200, "failed", "该应用不符合要求", bean={"display": False}) return Response(result, status=200) if service_obj.service_source == AppConstants.SOURCE_CODE: support_type = 1 else: support_type = 2 service_id = service_obj.service_id # 从环境变量中获取域名,没有在从请求中获取 host = os.environ.get('DEFAULT_DOMAIN', request.get_host()) service_webhook = service_webhooks_repo.get_or_create_service_webhook(self.service.service_id, deployment_way) # api处发自动部署 if deployment_way == "api_webhooks": # 生成秘钥 deploy = deploy_repo.get_deploy_relation_by_service_id(service_id=service_id) secret_key = pickle.loads(base64.b64decode(deploy)).get("secret_key") url = "http://" + host + "/console/" + "custom/deploy/" + service_obj.service_id result = general_message( 200, "success", "获取URl及开启状态成功", bean={ "url": url, "secret_key": secret_key, "status": service_webhook.state, "display": True, "support_type": support_type }) # 镜像处发自动部署 elif deployment_way == "image_webhooks": url = "http://" + host + "/console/" + "image/webhooks/" + service_obj.service_id result = general_message( 200, "success", "获取URl及开启状态成功", bean={ "url": url, "status": service_webhook.state, "display": True, "support_type": support_type, "trigger": service_webhook.trigger, }) # 源码处发自动部署 else: url = "http://" + host + "/console/" + "webhooks/" + service_obj.service_id deploy_keyword = service_webhook.deploy_keyword result = general_message( 200, "success", "获取URl及开启状态成功", bean={ "url": url, "status": service_webhook.state, "display": True, "support_type": support_type, "deploy_keyword": deploy_keyword }) return Response(result, status=200) except Exception as e: logger.exception(e) result = error_message(e.message) return Response(result, status=500)
def get(self, request, *args, **kwargs): """ 应用详情信息 --- parameters: - name: tenantName description: 租户名 required: true type: string paramType: path - name: serviceAlias description: 服务别名 required: true type: string paramType: path """ bean = dict() try: # status_map = app_service.get_service_status(self.tenant, self.service) # used_resource = app_service.get_service_resource_with_plugin(self.tenant, self.service, # status_map["status"]) # service_abled_plugins = app_plugin_service.get_service_abled_plugin(self.service) # plugin_list = [p.to_dict() for p in service_abled_plugins] # bean.update(status_map) # bean.update(used_resource) # bean.update({"plugin_list": plugin_list}) service_model = self.service.to_dict() group_map = group_service.get_services_group_name([self.service.service_id]) group_name = group_map.get(self.service.service_id)["group_name"] group_id = group_map.get(self.service.service_id)["group_id"] service_model["group_name"] = group_name service_model["group_id"] = group_id bean.update({"service": service_model}) tenant_actions = self.user.actions.tenant_actions bean.update({"tenant_actions": tenant_actions}) service_actions = self.user.actions.service_actions bean.update({"service_actions": service_actions}) event_websocket_url = ws_service.get_event_log_ws(self.request, self.service.service_region) bean.update({"event_websocket_url": event_websocket_url}) if self.service.service_source == "market": service_source = service_source_repo.get_service_source(self.tenant.tenant_id, self.service.service_id) if not service_source: result = general_message(200, "success", "查询成功", bean=bean) return Response(result, status=result["code"]) rain_app = rainbond_app_repo.get_rainbond_app_by_key_and_version(service_source.group_key, service_source.version) if not rain_app: result = general_message(200, "success", "当前云市应用已删除", bean=bean) return Response(result, status=result["code"]) else: bean.update({"rain_app_name": rain_app.group_name}) apps_template = json.loads(rain_app.app_template) apps_list = apps_template.get("apps") for app in apps_list: if app["service_key"] == self.service.service_key: if self.service.deploy_version and int( app["deploy_version"]) > int( self.service.deploy_version): self.service.is_upgrate = True self.service.save() bean.update({"service": service_model}) try: apps_template = json.loads(rain_app.app_template) apps_list = apps_template.get("apps") service_source = service_source_repo.get_service_source( self.service.tenant_id, self.service.service_id) if service_source and service_source.extend_info: extend_info = json.loads(service_source.extend_info) if extend_info: for app in apps_list: if "service_share_uuid" in app: if app["service_share_uuid"] == extend_info["source_service_share_uuid"]: new_version = int(app["deploy_version"]) old_version = int(extend_info["source_deploy_version"]) if new_version > old_version: self.service.is_upgrate = True self.service.save() service_model["is_upgrade"] = True bean.update({"service": service_model}) elif "service_share_uuid" not in app and "service_key" in app: if app["service_key"] == extend_info["source_service_share_uuid"]: new_version = int(app["deploy_version"]) old_version = int(extend_info["source_deploy_version"]) if new_version > old_version: self.service.is_upgrate = True self.service.save() service_model["is_upgrade"] = True bean.update({"service": service_model}) except Exception as e: logger.exception(e) if self.service.service_source == AppConstants.DOCKER_COMPOSE: if self.service.create_status != "complete": compose_service_relation = compose_service.get_service_compose_id(self.service) if compose_service_relation: service_model["compose_id"] = compose_service_relation.compose_id bean.update({"service": service_model}) bean["is_third"] = False if self.service.service_source == "third_party": bean["is_third"] = True service_endpoints = service_endpoints_repo.get_service_endpoints_by_service_id(self.service.service_id) if service_endpoints: bean["register_way"] = service_endpoints.endpoints_type if service_endpoints.endpoints_type == "api": # 从环境变量中获取域名,没有在从请求中获取 host = os.environ.get('DEFAULT_DOMAIN', request.get_host()) bean["api_url"] = "http://" + host + "/console/" + \ "third_party/{0}".format(self.service.service_id) key_repo = deploy_repo.get_service_key_by_service_id(service_id=self.service.service_id) if key_repo: bean["api_service_key"] = pickle.loads( base64.b64decode(key_repo.secret_key)).get("secret_key") if service_endpoints.endpoints_type == "discovery": # 返回类型和key endpoints_info_dict = json.loads(service_endpoints.endpoints_info) bean["discovery_type"] = endpoints_info_dict["type"] bean["discovery_key"] = endpoints_info_dict["key"] result = general_message(200, "success", "查询成功", bean=bean) except Exception as e: logger.exception(e) result = error_message(e.message) return Response(result, status=result["code"])
def post(self, request, *args, **kwargs): bean = {"is_certificate": 1} result = general_message(200, "success", "获取成功", bean=bean) return Response(result)