Beispiel #1
0
    def post(self, request):
        """添加/编辑AppServer信息
        """
        form = ServerForm(request.POST)
        if not form.is_valid():
            message = first_error_message(form)
            raise BadRequestException(message)

        server_id = form.cleaned_data["server_id"]
        server_ip = form.cleaned_data["server_ip"]
        server_port = form.cleaned_data["server_port"]
        app_port = form.cleaned_data["app_port"]
        server_cate = form.cleaned_data["server_cate"]

        # 验证 ip & port 是否重复
        if BkServer.objects.is_server_exists(server_id, server_ip,
                                             server_port):
            message = "IP为[{ip}], 端口为 [{port}] 的服务器已经存在".format(
                ip=server_ip, port=server_port)
            return FailJsonResponse(message)

        # 编辑信息
        try:
            data = BkServer.objects.update_or_create_server(
                server_id, server_ip, server_port, app_port, server_cate)
            return OKJsonResponse("保存成功", data=data)
        except Exception as e:
            logger.exception("保存应用服务器信息异常:%s", e)
            return FailJsonResponse("保存出错", data={})
Beispiel #2
0
    def _update_base_info(self, request, app_code):
        app = App.objects.get(code=app_code)

        form = BaseInfoForm(request.POST)
        if not form.is_valid():
            message = first_error_message(form)
            raise BadRequestException(message)

        name = form.cleaned_data["name"]
        developer = form.cleaned_data["developer"]
        app_tags = form.cleaned_data["app_tags"]

        old_name = app.name
        is_valid, message = validate_app_name(name, old_name)
        if not is_valid:
            raise BadRequestException(message)
        developer_list = developer.split(';') if developer else []
        # 保存用户基本信息
        with transaction.atomic():
            app.name = name
            app.tags = app_tags
            app.save()

            # 保存开发负责人信息
            if developer_list:
                app.developer.clear()
                user_model = get_user_model()
                for dev in developer_list:
                    d_user = user_model.objects.get(username=dev)
                    app.developer.add(d_user)
Beispiel #3
0
    def post(self, request):
        """添加/编辑第三方服务信息
        """
        form = ExternalServerForm(request.POST)
        if not form.is_valid():
            message = first_error_message(form)
            raise BadRequestException(message)

        server_id = form.cleaned_data["server_id"]
        server_ip = form.cleaned_data["server_ip"]
        server_port = form.cleaned_data["server_port"]
        server_cate = form.cleaned_data["server_cate"]
        username = form.cleaned_data["username"]
        password = form.cleaned_data["password"]

        if ThirdServer.objects.is_server_exists(server_id, server_ip,
                                                server_port):
            message = "IP为[{ip}], 端口为 [{port}] 的服务器已经存在".format(
                ip=server_ip, port=server_port)
            return FailJsonResponse(message)

        try:
            data = ThirdServer.objects.update_or_create_server(
                server_id, server_ip, server_port, username, password,
                server_cate)
            return OKJsonResponse("保存成功", data=data)
        except Exception as e:
            logger.exception("保存服务信息异常:%s", e)
            return FailJsonResponse("保存出错", data={})
Beispiel #4
0
    def get_context_data(self, **kwargs):
        context = super(CheckAppCodeView, self).get_context_data(**kwargs)
        request = self.request

        form = CheckAppCodeForm(request.GET)
        if not form.is_valid():
            message = first_error_message(form)
            context.update({'result': False, 'message': message})
            return context

        context.update({'result': True, 'message': "校验通过"})
        return context
Beispiel #5
0
    def get(self, request):
        username = request.user.username

        form = AppQueryForm(request.GET)
        if not form.is_valid():
            message = first_error_message(form)
            logger.exception("应用列表页面参数异常:%s", message)
            return JsonResponse({
                'data': "请求参数异常",
                'total_num': 0,
                'extend_fun': ''
            })

        keyword = form.cleaned_data["keyword"]
        hide_offline = form.cleaned_data["hide_offline"]
        page = form.cleaned_data["page"]
        page_size = form.cleaned_data["page_size"]

        start = (page - 1) * page_size
        end = page * page_size

        # 超级管理员可以查看所有的应用
        is_superuser = request.user.is_superuser
        has_app, total, app_list = App.objects.query_app_list(is_superuser, username, keyword, hide_offline, start, end)

        # 判断应用状态是否需要刷新
        refresh_app_list = []
        app_refresh_states = [AppStateEnum.IN_TEST.value, AppStateEnum.IN_ONLINE.value, AppStateEnum.IN_OFFLINE.value]
        for _app in app_list:
            if _app.state in app_refresh_states:
                _app_code = _app.code
                try:
                    sync_app_state(_app_code)
                    # 获取更新后的应用信息
                    _app = App.objects.get(code=_app_code)
                except Exception:
                    logger.exception("更新应用[%s]状态失败", _app_code)

            refresh_app_list.append(_app)

        result = {
            'total': total,
            'app_list': refresh_app_list,
            'has_app': has_app,
        }
        template_name = 'app/list_table.part' if has_app else 'app/list_tip.part'
        html_data = render_mako_tostring_context(request, template_name, result)
        return JsonResponse({
            'data': html_data,
            'total_num': total,
            'extend_fun': ''
        })
Beispiel #6
0
    def post(self, request):
        form = PasswordChangeForm(request.POST)
        if not form.is_valid():
            message = first_error_message(form)
            raise BadRequestException(message)

        new_password1 = form.cleaned_data.get("new_password1")
        bk_token = request.COOKIES.get(settings.BK_COOKIE_NAME, None)
        data = {'new_password': new_password1}

        ok, message = change_password(bk_token, data)
        if not ok:
            return FailJsonResponse(message or "密码重置失败")
        return OKJsonResponse("success")
Beispiel #7
0
    def delete(self, request, *args, **kwargs):
        form = LightAppChangeBaseInfoForm(self.request_body_params)
        if not form.is_valid():
            message = first_error_message(form)
            return ApiV2FailJsonResponse(
                message, code=ApiErrorCodeEnumV2.PARAM_NOT_VALID.value)

        light_app = UsefulLinks.objects.get_light_app_or_none(
            form.cleaned_data["bk_light_app_code"])

        # 将app状态标记为下架
        light_app.is_active = False
        light_app.save()
        return ApiV2OKJsonResponse("app 下架成功", data={})
Beispiel #8
0
    def _add_or_update(self, request, app_code, var_id=None):
        if not var_id:
            form = AppEnvForm(request.POST)
        else:
            put = QueryDict(request.body)
            form = AppEnvForm(put)

        if not form.is_valid():
            message = first_error_message(form)
            # print form.errors
            raise BadRequestException(message)

        #  app_code = form.cleaned_data["app_code"]
        name = form.cleaned_data["name"]
        value = form.cleaned_data["value"]
        intro = form.cleaned_data["intro"]
        mode = form.cleaned_data["mode"]

        name = 'BKAPP_%s' % name

        # do add
        if not var_id:
            if AppEnvVar.objects.exists(app_code, mode, name):
                message = "变量名已经存在, 请勿重复添加!"
                return FailJsonResponse(message)

            try:
                env_var = AppEnvVar.objects.create(app_code=app_code,
                                                   mode=mode,
                                                   name=name,
                                                   value=value,
                                                   intro=intro)

                var_id = env_var.id
            except Exception:
                # 保存app环境变量异常
                message = "保存app环境变量失败"
                logger.exception(message)
                return FailJsonResponse(message)
        # do update
        else:
            if AppEnvVar.objects.update_target_exists(app_code, mode, name,
                                                      var_id):
                message = "同名变量已经存在! 无法对当前变量进行更新"
                return FailJsonResponse(message)

            AppEnvVar.objects.update(var_id, name, value, intro, mode)

        return OKJsonResponse("保存变量成功", id=var_id)
Beispiel #9
0
    def _update_vsc_info(self, request, app_code):
        vcs_info_form = VCSInfoForm(request.POST)
        if not vcs_info_form.is_valid():
            message = first_error_message(vcs_info_form)
            raise BadRequestException(message)

        vcs_url = vcs_info_form.cleaned_data["vcs_url"]
        vcs_username = vcs_info_form.cleaned_data["vcs_username"]
        vcs_password = vcs_info_form.cleaned_data["vcs_password"]

        SecureInfo.objects.filter(app_code=app_code).update(
            vcs_url=vcs_url,
            vcs_username=vcs_username,
            vcs_password=vcs_password
        )
Beispiel #10
0
    def _update_db_info(self, request, app_code):
        form = DBInfoForm(request.POST)
        if not form.is_valid():
            message = first_error_message(form)
            raise BadRequestException(message)

        db_host = form.cleaned_data["db_host"]
        db_port = form.cleaned_data["db_port"]
        db_username = form.cleaned_data["db_username"]
        db_password = form.cleaned_data["db_password"]

        SecureInfo.objects.filter(app_code=app_code).update(
            db_host=db_host,
            db_port=db_port,
            db_username=db_username,
            db_password=db_password,
            )
Beispiel #11
0
    def put(self, request, *args, **kwargs):
        form = LightAppEditForm(self.request_body_params)
        if not form.is_valid():
            message = first_error_message(form)
            return ApiV2FailJsonResponse(
                message, code=ApiErrorCodeEnumV2.PARAM_NOT_VALID.value)

        light_app = UsefulLinks.objects.get_light_app_or_none(
            form.cleaned_data["bk_light_app_code"])

        # 保存应用基本信息
        light_app.introduction = form.cleaned_data[
            "introduction"] or light_app.introduction
        light_app.name = form.cleaned_data[
            "bk_light_app_name"] or light_app.name
        light_app.link = form.cleaned_data["app_url"] or light_app.link
        light_app.save()

        return ApiV2OKJsonResponse("app 修改成功", data={})
Beispiel #12
0
    def post(self, request, *args, **kwargs):
        form = LightAppCreateForm(self.request_body_params)
        if not form.is_valid():
            message = first_error_message(form)
            return ApiV2FailJsonResponse(
                message, code=ApiErrorCodeEnumV2.PARAM_NOT_VALID.value)

        parent_app = App.objects.get(code=form.cleaned_data["bk_app_code"])

        # 保存应用信息到数据库
        link = UsefulLinks.objects.create(
            name=form.cleaned_data["bk_light_app_name"],
            link=form.cleaned_data["app_url"],
            link_type=LinkTypeEnum.LIGHT_APP.value,
            introduction=form.cleaned_data["introduction"]
            or parent_app.introduction)
        data = {'bk_light_app_code': link.code}

        return ApiV2OKJsonResponse("创建轻应用成功", data=data)
Beispiel #13
0
    def put_logo(self, request, *args, **kwargs):
        form = LightAppLogoModifyForm(self.request_body_params)
        if not form.is_valid():
            message = first_error_message(form)
            return ApiV2FailJsonResponse(
                message, code=ApiErrorCodeEnumV2.PARAM_NOT_VALID.value)

        light_app = UsefulLinks.objects.get_light_app_or_none(
            form.cleaned_data["bk_light_app_code"])

        try:
            light_app.logo = trans_b64_to_content_file(
                form.cleaned_data["logo"])
            light_app.save()
        except Exception as e:
            # 保存logo时出错
            logger.exception(u"save app logo fail: %s" % e)
            return ApiV2FailJsonResponse(
                "logo 数据格式不合法", code=ApiErrorCodeEnumV2.PARAM_NOT_VALID.value)

        return ApiV2OKJsonResponse("app logo修改成功", data={})
Beispiel #14
0
    def post(self, request, *args, **kwargs):
        app_code = self.kwargs["app_code"]

        form = UploadFileForm(request.POST, request.FILES)
        if not form.is_valid():
            message = first_error_message(form)
            return upload_response_tpl(False, message)

        saas_file = form.cleaned_data["saas_file"]

        md5 = md5_for_file(saas_file.chunks())

        # 2. save to SaaSUploadFile
        # 同名文件覆盖 => 覆盖, 但是这样saas upload file又会存在多个指向同一个文件
        # http://timonweb.com/posts/imagefield-overwrite-file-if-file-with-the-same-name-exists/
        saas_upload_file = SaaSUploadFile.objects.create(
            name=saas_file.name,
            size=saas_file.size,
            md5=md5,
            file=saas_file,
        )

        # 校验大小等参数
        is_valid, message, app_yml_content = validate_and_extract_tar_file(filename=saas_upload_file.name,
                                                                           path=saas_upload_file.file.path)
        if not is_valid:
            logger.info(message)
            return upload_response_tpl(False, message)

        app_config = {}
        try:
            app_config = yaml.load(app_yml_content)
        except Exception:
            message = "无法正确加载{}包中的yml文件".format(saas_upload_file.name)
            logger.exception(message)
            return upload_response_tpl(False, message)

        # basic settings check
        saas_app_code = app_config.get("app_code")

        # 校验app_code
        if app_code == "0":
            app_code = saas_app_code

            # NOTE: 从上传新应用入口进来的, 判定下是否上传的老的包
            if SaaSApp.objects.exists(app_code):
                message = "上传包应用 ID 为: {}. 应用已存在, 非新应用无法从此入口部署. 请从内置应用列表找到该应用, 进入部署页面部署".format(app_code)
                logger.info(message)
                return upload_response_tpl(False, message)
        else:
            if app_code != saas_app_code:
                message = ("当前应用 ID 为: {}, 上传包应用 ID 为: {}. 不是同一个应用, 无法部署. "
                           "请作为新应用上传部署或找到应用{}的部署页面上传部署 ").format(app_code, saas_app_code, saas_app_code)
                logger.info(message)
                return upload_response_tpl(False, message)

        app_name = app_config.get("app_name")
        version = app_config.get("version")
        if not (app_code and app_name and version):
            message = ("upload file: {}, app.yml settings error"
                       "[app_code={}, app_name={}, version={}]").format(saas_file.name,
                                                                        app_code,
                                                                        app_name,
                                                                        version)
            logger.info(message)
            return upload_response_tpl(False, message)

        try:
            saas_app_version_id = save_saas_app_info(app_config, saas_upload_file)
        except Exception:
            message = "保存SaaS包信息失败"
            logger.exception(message)
            return upload_response_tpl(False, message)

        # 解压包文件中的logo到 media/logo/ 目录下
        extract_logo_file(filename=saas_upload_file.name, path=saas_upload_file.file.path, saas_app_code=saas_app_code)

        # for: 部署时展示线上版本/当前版本信息给用户
        file_version_display = "{} (V{})".format(saas_file.name, version)

        data = {"saas_app_version_id": saas_app_version_id, 'file_version_display': file_version_display}
        return upload_response_tpl(True, "上传成功", data)
Beispiel #15
0
    def post(self, request):
        """新建应用
        """
        creater = request.user.username
        # validate
        error_url = "%sapp/error/?error={error}" % settings.SITE_URL
        form = AppCreateForm(request.POST)
        if not form.is_valid():
            message = first_error_message(form)
            return HttpResponseRedirect(error_url.format(error=message))

        # get params
        code = form.cleaned_data["code"]
        name = form.cleaned_data["name"]
        introduction = form.cleaned_data["introduction"]
        app_tags = form.cleaned_data["app_tags"]
        language = form.cleaned_data["language"]
        if not language:
            language = 'python'
        deploy_token = form.cleaned_data["deploy_token"]

        vcs_type = form.cleaned_data["vcs_type"]
        vcs_url = form.cleaned_data["vcs_url"]
        vcs_username = form.cleaned_data["vcs_username"]
        vcs_password = form.cleaned_data["vcs_password"]

        developer = form.cleaned_data["developer"]
        if not developer:
            developer = creater
        developer_list = developer.split(';') if developer else []

        # 注册应用信息
        ok, message, token = register_app(code, name, language)
        if not ok:
            return HttpResponseRedirect(error_url.format(error=message))

        # 保存应用信息到数据库
        try:
            with transaction.atomic():
                app = App.objects.create(
                    name=name,
                    code=code,
                    introduction=introduction,
                    creater=creater,
                    language=language,
                    auth_token=token,
                    deploy_token=deploy_token,
                    tags=app_tags,
                )
                # 保存开发负责人信息
                if developer_list:
                    user_model = get_user_model()
                    for dev in developer_list:
                        try:
                            d_user = user_model.objects.get(username=dev)
                            app.developer.add(d_user)
                        except Exception as e:
                            logger.exception("获取用户[username:%s]异常:%s", dev, e)
                # 保存源码等需要跟App Engine交互的信息
                SecureInfo.objects.create(
                    app_code=code,
                    vcs_type=vcs_type,
                    vcs_url=vcs_url,
                    vcs_username=vcs_username,
                    vcs_password=vcs_password,
                )
        except Exception as e:
            logger.exception("创建应用时,保存应用基本信息出错:%s", e)
            return HttpResponseRedirect(error_url.format(error="保存应用基本信息出错"))
        url = '{}app/{}/info/'.format(settings.SITE_URL, code)
        return HttpResponseRedirect(url)