Ejemplo n.º 1
0
    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"操作过于频繁,请稍后再试"
Ejemplo n.º 2
0
    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"])
Ejemplo n.º 3
0
    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)
Ejemplo n.º 4
0
 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)
Ejemplo n.º 5
0
 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)
Ejemplo n.º 6
0
    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)
Ejemplo n.º 7
0
    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"])
Ejemplo n.º 8
0
    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"])
Ejemplo n.º 9
0
    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"])
Ejemplo n.º 10
0
    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"])
Ejemplo n.º 11
0
    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"])
Ejemplo n.º 12
0
    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"])
Ejemplo n.º 13
0
    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"])
Ejemplo n.º 14
0
    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"])
Ejemplo n.º 15
0
    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)
Ejemplo n.º 16
0
 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"])
Ejemplo n.º 17
0
 def get(self, request, *args, **kwargs):
     result = general_message(200, u"success", "获取成功", bean={"check_uuid": self.service.check_uuid})
     return Response(result, status=200)
Ejemplo n.º 18
0
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))
Ejemplo n.º 19
0
    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"])
Ejemplo n.º 20
0
    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)
Ejemplo n.º 21
0
 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)
Ejemplo n.º 22
0
    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"])
Ejemplo n.º 23
0
 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"])
Ejemplo n.º 24
0
 def get_response(self):
     if self.response:
         return self.response
     else:
         return Response(general_message(10401, "failed", "无数据返回"),
                         status=500)
Ejemplo n.º 25
0
 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)
Ejemplo n.º 26
0
    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)
Ejemplo n.º 27
0
                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
Ejemplo n.º 28
0
    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)
Ejemplo n.º 29
0
    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"])
Ejemplo n.º 30
0
 def post(self, request, *args, **kwargs):
     bean = {"is_certificate": 1}
     result = general_message(200, "success", "获取成功", bean=bean)
     return Response(result)