diff --git a/frontend/build/paas-server.js b/frontend/build/paas-server.js index 3f6cc7ba4..9fe75e094 100644 --- a/frontend/build/paas-server.js +++ b/frontend/build/paas-server.js @@ -70,8 +70,7 @@ const GLOBAL_VAR = { BK_DOCS_URL_PREFIX: process.env.BK_DOCS_URL_PREFIX || '', BK_DOMAIN: process.env.BK_DOMAIN || '', BK_SHARED_RES_URL: process.env.BK_SHARED_RES_URL || '', - BK_APP_CODE: process.env.BK_APP_CODE || '', - VERSION: process.env.VERSION || '' + BK_APP_CODE: process.env.BK_APP_CODE || '' }; // APA 重定向回首页,由首页Route响应处理 diff --git a/frontend/index.html b/frontend/index.html index 85d8cd4b0..eea14bc38 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -6,7 +6,7 @@ - 权限中心 | 腾讯蓝鲸智云 + 权限中心 | 蓝鲸智云
@@ -33,7 +33,6 @@ const BK_COMPONENT_API_URL = '{{ BK_COMPONENT_API_URL }}' || '' const BK_SHARED_RES_URL = '{{ BK_SHARED_RES_URL }}' || '' const BK_APP_CODE = '{{ BK_APP_CODE }}' || '' - const VERSION = '{{ VERSION }}' || '' document.domain = '{{ SESSION_COOKIE_DOMAIN }}' window.LOGIN_SERVICE_URL = LOGIN_SERVICE_URL window.AJAX_URL_PREFIX = AJAX_URL_PREFIX @@ -57,7 +56,6 @@ window.BK_COMPONENT_API_URL = BK_COMPONENT_API_URL window.BK_SHARED_RES_URL = BK_SHARED_RES_URL window.BK_APP_CODE = BK_APP_CODE - window.VERSION = VERSION })() function getLanguage () { @@ -77,9 +75,9 @@ CUR_LANGUAGE = 'zh-cn' } if (CUR_LANGUAGE === 'en') { - document.title = 'BKIAM | Tencent Blueking' + document.title = 'lAM | Tencent BlueKing' } else { - document.title = '权限中心 | 腾讯蓝鲸智云' + document.title = '权限中心 | 蓝鲸智云' } return CUR_LANGUAGE diff --git a/frontend/package.json b/frontend/package.json index a48fff5ae..0c5855a7b 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -90,7 +90,7 @@ "@blueking/functional-dependency": "0.0.1-beta.12", "@blueking/login-modal": "^1.0.0", "@blueking/notice-component-vue2": "^2.0.3", - "@blueking/platform-config": "^1.0.2", + "@blueking/platform-config": "^1.0.5", "@blueking/sub-saas": "0.0.0-beta.7", "@blueking/user-selector": "^1.0.14", "@commitlint/cli": "~13.1.0", @@ -111,7 +111,7 @@ "babel-plugin-syntax-jsx": "^6.18.0", "babel-plugin-transform-vue-jsx": "^4.0.1", "better-npm-run": "~0.1.1", - "bk-magic-vue": "^2.5.9-beta.17", + "bk-magic-vue": "^2.5.9-beta.37", "body-parser": "~1.19.0", "chalk": "~2.4.2", "cheerio": "~1.0.0-rc.3", diff --git a/frontend/src/App.vue b/frontend/src/App.vue index f20803002..d6f4130ea 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -100,7 +100,8 @@ return { reload: this.reload, reloadCurPage: this.reloadCurPage, - showNoticeAlert: this.isShowNoticeAlert + // 基本类型不具备响应式,这里需要根据异步操作动态计算所以这里返回function + showNoticeAlert: () => this.isShowNoticeAlert }; }, components: { diff --git a/frontend/src/IframeEntry.vue b/frontend/src/IframeEntry.vue index b97b93aa1..e73358043 100644 --- a/frontend/src/IframeEntry.vue +++ b/frontend/src/IframeEntry.vue @@ -60,7 +60,7 @@ return { reload: this.reload, reloadCurPage: this.reloadCurPage, - showNoticeAlert: this.isShowNoticeAlert + showNoticeAlert: () => this.isShowNoticeAlert }; }, components: { diff --git a/frontend/src/common/constants.js b/frontend/src/common/constants.js index 881443a63..aee8225fd 100644 --- a/frontend/src/common/constants.js +++ b/frontend/src/common/constants.js @@ -136,6 +136,109 @@ export const NEED_CONFIRM_DIALOG_ROUTER = [ 'secondaryManageSpaceCreate' ]; +// 不同导航栏下的路由模块分类 +export const ALL_ROUTES_LIST = new Map([ + // 权限模板 + [ + ['permTemplate', 'permTemplateDetail', 'permTemplateCreate', 'permTemplateEdit', 'permTemplateDiff'], + 'permTemplateNav' + ], + // 首页 + [['', 'index'], 'indexNav'], + // 用户组 + [ + ['userGroup', 'userGroupDetail', 'createUserGroup', 'cloneUserGroup', 'userGroupPermDetail', 'groupPermRenewal', 'addGroupPerm'], + 'userGroupNav' + ], + // 系统接入 + [ + [ + 'systemAccess', + 'systemAccessCreate', + 'systemAccessAccess', + 'systemAccessRegistry', + 'systemAccessOptimize', + 'systemAccessComplete' + ], + 'systemAccessNav' + ], + // 我的申请 + [['apply'], 'applyNav'], + // 权限申请 'permApply' + [['applyCustomPerm', 'applyJoinUserGroup'], 'permApplyNav'], + // 临时权限申请 'provisionPermApply' + [['applyProvisionPerm'], 'provisionPermApplyNav'], + // 我的权限 + [ + [ + 'myPerm', + 'templatePermDetail', + 'groupPermDetail', + 'permRenewal', + 'groupPermRenewal', + 'permTransfer', + 'permTransferHistory', + 'applyPerm' + ], + 'myPermNav' + ], + // 我的管理空间 + [['myManageSpace', 'myManageSpaceCreate', 'gradingAdminDetail', 'gradingAdminEdit', 'gradingAdminCreate', 'myManageSpaceSubDetail', 'secondaryManageSpaceEdit'], 'myManageSpaceNav'], + // 分级管理员 + [['ratingManager', 'gradingAdminDetail', 'gradingAdminCreate', 'gradingAdminEdit'], 'gradingAdminNav'], + // 二级管理空间 + [['secondaryManageSpace', 'secondaryManageSpaceCreate', 'secondaryManageSpaceDetail'], 'secondaryManageSpaceNav'], + // 授权边界 + [['authorBoundary', 'authorBoundaryEditFirstLevel', 'authorBoundaryEditSecondLevel'], 'authorBoundaryNav'], + // 最大可授权人员边界 + [['addMemberBoundary'], 'addMemberBoundaryNav'], + // 资源权限 + [['resourcePermiss'], 'resourcePermissNav'], + // 管理员 + [['administrator'], 'settingNav'], + // 审批流程 + [['approvalProcess'], 'approvalProcessNav'], + // 用户 + [['user'], 'userNav'], + // 审计 + [['audit'], 'auditNav'], + // 用户组设置 + [['userGroupSetting'], 'userGroupSettingNav'], + // 敏感等级 + [['sensitivityLevel'], 'sensitivityLevelNav'], + // 人员模板 + [['memberTemplate'], 'memberTemplateNav'], + // 管理空间下资源权限管理 + [['resourcePermManage'], 'resourcePermManageNav'], + // 用户/组织 + [['userOrgPerm'], 'userOrgPermNav'], + // 续期通知 + [['renewalNotice'], 'renewalNoticeNav'] +]); + +// 切换管理员身份需要重定向的页面 +export const MANAGE_SPACE_REDIRECT_ROUTES = new Map([ + // 权限模板 + [ + ['permTemplateDetail', 'permTemplateCreate', 'permTemplateEdit', 'permTemplateDiff'], + 'permTemplate' + ], + // 用户组模块 + [ + ['userGroupDetail', 'createUserGroup', 'cloneUserGroup', 'userGroupPermDetail', 'groupPermRenewal', 'addGroupPerm'], + 'userGroup' + ], + // 管理空间 + [ + ['gradingAdminDetail', 'gradingAdminCreate', 'gradingAdminEdit'], + 'ratingManager'], + // 二级管理员 + [ + ['secondaryManageSpaceCreate', 'secondaryManageSpaceDetail', 'secondaryManageSpaceEdit'], + 'secondaryManageSpace' + ] +]); + // 用户组属性枚举 export const USER_GROUP_ATTRIBUTES = [ { @@ -273,3 +376,83 @@ export const SEND_DAYS_LIST = [ value: 'sunday' } ]; + +// 只显示角色名称的审计类型 +export const ONLY_ROLE_TYPE = [ + 'template.create', + 'subject.template.create', + 'subject.template.delete' +]; + +// 没有详情的审计类型 +export const NO_DETAIL_TYPE = [ + 'group.create', + 'group.delete', + // 'template.create', + 'template.update', + 'role.create' +]; + +// 只有描述字段的审计类型 +export const ONLY_DESCRIPTION_TYPE = [ + 'group.update', + 'role.update', + 'role.member.policy.create', + 'role.member.policy.delete', + 'approval.global.update' +]; + +// 只有子对象的审计类型 +export const ONLY_SUB_TYPE = [ + 'action.sensitivity.level.update', + 'group.template.create', + 'group.member.create', + 'group.member.delete', + 'group.member.renew', + 'group.transfer', + 'user.group.delete', + 'department.group.delete', + 'user.role.delete', + 'role.member.create', + 'role.member.delete', + 'role.member.update', + 'role.commonaction.create', + 'role.commonaction.delete', + 'subject.template.group.delete', + 'subject.template.member.create', + 'subject.template.member.delete' +]; + +// 只有附加信息的审计类型 +export const ONLY_EXTRA_INFO_TYPE = [ + 'group.policy.create', + 'group.policy.delete', + 'group.policy.update', + 'user.policy.delete', + 'user.policy.create', + 'user.policy.update', + 'user.temporary.policy.create', + 'user.temporary.policy.delete', + 'user.blacklist.member.create', + 'user.blacklist.member.delete', + 'user.permission.clean', + 'role.group.renew', + 'template.version.sync' +]; + +// 既有 description 又有 extra_info +export const DE_TYPR = ['template.update']; + +// 既有 sub_objects 又有 extra_info +export const SE_TYPE = [ + 'template.member.create', + 'template.member.delete', + 'template.version.update' +]; + +// 既有 description 又有 sub_objects +export const DS_TYPE = [ + 'approval.action.update', + 'approval.group.update', + 'template.preupdate.create' +]; diff --git a/frontend/src/common/router-handle.js b/frontend/src/common/router-handle.js index 2f2700d59..8bb1d1f28 100644 --- a/frontend/src/common/router-handle.js +++ b/frontend/src/common/router-handle.js @@ -36,6 +36,7 @@ export const getRouterDiff = (payload) => { return [ 'userGroup', 'createUserGroup', + 'cloneUserGroup', 'userGroupDetail', 'permTemplate', 'permTemplateCreate', @@ -49,11 +50,17 @@ export const getRouterDiff = (payload) => { 'permTemplateDiff', 'addGroupPerm', 'resourcePermiss', - 'firstManageSpace', 'ratingManager', + 'gradingAdminCreate', + 'gradingAdminDetail', + 'gradingAdminEdit', + 'gradingAdminUpdateTemplate', 'secondaryManageSpace', - 'authorBoundary', 'secondaryManageSpaceCreate', + 'secondaryManageSpaceDetail', + 'authorBoundary', + 'authorBoundaryEditFirstLevel', + 'authorBoundaryEditSecondLevel', 'userGroupSetting', 'sensitivityLevel', 'memberTemplate', @@ -75,6 +82,8 @@ export const getRouterDiff = (payload) => { 'ratingManager', 'gradingAdminCreate', 'gradingAdminDetail', + 'gradingAdminEdit', + 'gradingAdminUpdateTemplate', 'user', 'gradingAdminUpdateTemplate', 'administrator', @@ -88,10 +97,10 @@ export const getRouterDiff = (payload) => { 'systemAccessOptimize', 'systemAccessComplete', 'resourcePermiss', - 'userGroupDetail', - 'firstManageSpace', 'secondaryManageSpace', 'authorBoundary', + 'authorBoundaryEditFirstLevel', + 'authorBoundaryEditSecondLevel', 'myManageSpace', 'myManageSpaceCreate', 'permTransfer', @@ -115,10 +124,12 @@ export const getRouterDiff = (payload) => { 'ratingManager', 'gradingAdminCreate', 'gradingAdminDetail', - 'user', + 'gradingAdminEdit', 'gradingAdminUpdateTemplate', + 'user', 'approval', 'permRenewal', + 'permTransfer', 'audit', 'systemAccess', 'systemAccessCreate', @@ -126,10 +137,14 @@ export const getRouterDiff = (payload) => { 'systemAccessRegistry', 'systemAccessOptimize', 'systemAccessComplete', - 'firstManageSpace', 'secondaryManageSpace', + 'secondaryManageSpaceCreate', + 'secondaryManageSpaceDetail', 'authorBoundary', + 'authorBoundaryEditFirstLevel', + 'authorBoundaryEditSecondLevel', 'myManageSpace', + 'myManageSpaceCreate', 'renewalNotice', 'userOrgPerm' ]; @@ -147,11 +162,13 @@ export const getRouterDiff = (payload) => { 'ratingManager', 'gradingAdminCreate', 'gradingAdminDetail', - 'user', + 'gradingAdminEdit', 'gradingAdminUpdateTemplate', + 'user', 'administrator', 'approval', 'permRenewal', + 'permTransfer', 'audit', 'systemAccess', 'systemAccessCreate', @@ -161,7 +178,6 @@ export const getRouterDiff = (payload) => { 'systemAccessComplete', 'myManageSpace', 'resourcePermiss', - 'firstManageSpace', 'sensitivityLevel', 'resourcePermManage', 'renewalNotice' @@ -180,11 +196,13 @@ export const getRouterDiff = (payload) => { 'ratingManager', 'gradingAdminCreate', 'gradingAdminDetail', - 'user', + 'gradingAdminEdit', 'gradingAdminUpdateTemplate', + 'user', 'administrator', 'approval', 'permRenewal', + 'permTransfer', 'audit', 'systemAccess', 'systemAccessCreate', @@ -196,7 +214,6 @@ export const getRouterDiff = (payload) => { 'secondaryManageSpace', 'secondaryManageSpaceCreate', 'secondaryManageSpaceDetail', - 'firstManageSpace', 'myManageSpace', 'permTemplate', 'userGroupSetting', @@ -221,6 +238,7 @@ export const getRouterDiff = (payload) => { 'orgPermDetail', 'userGroup', 'createUserGroup', + 'cloneUserGroup', 'userGroupDetail', 'userGroupPermDetail', 'permTemplate', @@ -265,6 +283,7 @@ export const getNavRouterDiff = (navIndex, managerPerm = '') => { return [ 'userGroup', 'createUserGroup', + 'cloneUserGroup', 'userGroupDetail', 'permTemplate', 'permTemplateCreate', @@ -278,10 +297,17 @@ export const getNavRouterDiff = (navIndex, managerPerm = '') => { 'permTemplateDiff', 'addGroupPerm', 'resourcePermiss', - 'firstManageSpace', 'ratingManager', + 'gradingAdminCreate', + 'gradingAdminDetail', + 'gradingAdminEdit', + 'gradingAdminUpdateTemplate', 'authorBoundary', + 'authorBoundaryEditFirstLevel', + 'authorBoundaryEditSecondLevel', 'secondaryManageSpace', + 'secondaryManageSpaceCreate', + 'secondaryManageSpaceDetail', 'userGroupSetting', 'sensitivityLevel', 'memberTemplate', @@ -305,6 +331,7 @@ export const getNavRouterDiff = (navIndex, managerPerm = '') => { 'orgPermDetail', 'userGroup', 'createUserGroup', + 'cloneUserGroup', 'userGroupDetail', 'userGroupPermDetail', 'permTemplate', @@ -324,15 +351,18 @@ export const getNavRouterDiff = (navIndex, managerPerm = '') => { 'approvalProcess', 'approval', 'permRenewal', + 'permTransfer', 'groupPermRenewal', 'permTemplateEdit', 'permTemplateDiff', 'addGroupPerm', 'resourcePermiss', - 'firstManageSpace', 'authorBoundary', - 'secondaryManageSpace', + 'authorBoundaryEditFirstLevel', + 'authorBoundaryEditSecondLevel', 'myManageSpace', + 'myManageSpaceCreate', + 'secondaryManageSpace', 'secondaryManageSpaceCreate', 'secondaryManageSpaceDetail', 'userGroupSetting', @@ -356,6 +386,7 @@ export const getNavRouterDiff = (navIndex, managerPerm = '') => { 'orgPermDetail', 'approval', 'permRenewal', + 'permTransfer', 'systemAccess', 'systemAccessCreate', 'systemAccessAccess', @@ -365,17 +396,18 @@ export const getNavRouterDiff = (navIndex, managerPerm = '') => { 'audit', 'userGroup', 'createUserGroup', + 'cloneUserGroup', 'userGroupDetail', 'userGroupPermDetail', 'permTemplate', 'permTemplateDetail', 'permTemplateCreate', - 'authorBoundary', - 'secondaryManageSpace', 'myManageSpace', 'myManageSpaceCreate', + 'secondaryManageSpace', 'secondaryManageSpaceCreate', 'secondaryManageSpaceDetail', + 'authorBoundary', 'authorBoundaryEditFirstLevel', 'authorBoundaryEditSecondLevel', 'permTemplateEdit', diff --git a/frontend/src/common/util.js b/frontend/src/common/util.js index 3750aeb62..873fdf058 100644 --- a/frontend/src/common/util.js +++ b/frontend/src/common/util.js @@ -627,20 +627,58 @@ export function formatI18nKey () { * @param {callback} str 回调名 * */ -export function jsonpRequest (url, params, callbackName) { - return new Promise((resolve, reject) => { - const script = document.createElement('script'); - if (callbackName) { - callbackName = callbackName + Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1); +// export function jsonpRequest (url, params, callbackName) { +// return new Promise((resolve, reject) => { +// const script = document.createElement('script'); +// if (callbackName) { +// callbackName = callbackName + Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1); +// } +// Object.assign(params, callbackName ? { callback: callbackName } : {}); +// const arr = Object.keys(params).map(key => `${key}=${params[key]}`); +// script.src = `${url}?${arr.join('&')}`; +// document.body.appendChild(script); +// if (callbackName) { +// window[callbackName] = (data) => { +// resolve(data); +// }; +// } +// }); +// } +export function jsonpRequest (url, data) { + if (!url) throw new Error('invalid URL'); + const callback = `CALLBACK${Math.random().toString().slice(9, 18)}`; + const JSONP = document.createElement('script'); + JSONP.setAttribute('type', 'text/javascript'); + const headEle = document.getElementsByTagName('head')[0]; + let query = ''; + if (data) { + if (typeof data === 'string') { + query = `&${data}`; + } else if (typeof data === 'object') { + for (const [key, value] of Object.entries(data)) { + query += `&${key}=${encodeURIComponent(value)}`; + } } - Object.assign(params, callbackName ? { callback: callbackName } : {}); - const arr = Object.keys(params).map(key => `${key}=${params[key]}`); - script.src = `${url}?${arr.join('&')}`; - document.body.appendChild(script); - if (callbackName) { - window[callbackName] = (data) => { - resolve(data); + query += `&_time=${Date.now()}`; + } + let promiseRejecter = null; + JSONP.src = `${url}?callback=${callback}${query}`; + JSONP.onerror = function (event) { + if (promiseRejecter) { + promiseRejecter = event; + } + }; + return new Promise((resolve, reject) => { + promiseRejecter = reject; + try { + window[callback] = (result) => { + resolve(result); + headEle.removeChild(JSONP); + delete window[callback]; }; + headEle.appendChild(JSONP); + } catch (err) { + reject(err); } }); } diff --git a/frontend/src/components/choose-ip/sideslider.vue b/frontend/src/components/choose-ip/sideslider.vue index 0d5d0b80a..15be6e509 100644 --- a/frontend/src/components/choose-ip/sideslider.vue +++ b/frontend/src/components/choose-ip/sideslider.vue @@ -725,7 +725,7 @@ } } .bk-sideslider-footer { - background-color: #f5f6fa!important; + background-color: #ffffff !important; border-color: #dcdee5!important; } } diff --git a/frontend/src/components/common-action/index.vue b/frontend/src/components/common-action/index.vue index 37ae87670..75b5bc1a8 100644 --- a/frontend/src/components/common-action/index.vue +++ b/frontend/src/components/common-action/index.vue @@ -41,10 +41,10 @@ @blur="handleBlur" @enter="handleEnter"> -
+
-
+
@@ -206,7 +206,7 @@ }, handleBlur () { - if (this.tagName === '') { + if (this.tagName.trim() === '') { this.isEdit = false; } }, @@ -225,15 +225,15 @@ }, handleEnter () { - this.handeSave(); + this.handleSave(); }, handleDelete (id, $id, index) { this.$emit('on-delete', id, $id, index); }, - handeSave () { - if (this.tagName === '') { + handleSave () { + if (this.tagName.trim() === '') { this.isEdit = false; return; } @@ -241,7 +241,7 @@ this.handleReset(); }, - handeCancel () { + handleCancel () { this.handleReset(); } } diff --git a/frontend/src/components/header-nav/index.vue b/frontend/src/components/header-nav/index.vue index 87939298c..445307f0f 100644 --- a/frontend/src/components/header-nav/index.vue +++ b/frontend/src/components/header-nav/index.vue @@ -125,9 +125,9 @@ import { buildURLParams } from '@/common/url'; import { formatI18nKey, jsonpRequest, getManagerMenuPerm } from '@/common/util'; import { NEED_CONFIRM_DIALOG_ROUTER } from '@/common/constants'; - import SystemLog from '../system-log'; import { getRouterDiff, getNavRouterDiff } from '@/common/router-handle'; - import Cookie from 'js-cookie'; + import SystemLog from '../system-log'; + import Cookies from 'js-cookie'; import magicbox from 'bk-magic-vue'; import logoSvg from '@/images/logo.svg'; @@ -311,15 +311,10 @@ }, appName () { // 如果未获取到配置,使用默认title - if (this.globalConfig) { - const { name, nameEn } = this.globalConfig; - return this.curLanguageIsCn ? name : nameEn; - } - return this.$t('m.nav["蓝鲸权限中心"]'); + return this.globalConfig && this.globalConfig.i18n ? this.globalConfig.i18n.productName : this.$t('m.nav["蓝鲸权限中心"]'); }, appLogo () { // 如果未获取到配置,使用默认logo - console.log(this.globalConfig.appLogo); const src = this.globalConfig.appLogo || logoSvg; return src; } @@ -624,29 +619,47 @@ locale.use(magicBoxLanguageMap[formatI18nKey()]); window.CUR_LANGUAGE = formatI18nKey(); this.$i18n.locale = formatI18nKey(); - window.location.reload(); }, - handleChangeLocale (language) { - Cookie.remove('blueking_language', { path: '' }); - Cookie.set('blueking_language', language, { - domain: window.BK_DOMAIN - }); + async handleChangeLocale (language) { + const curDomain = window.BK_DOMAIN || window.location.hostname.replace(/^.*(\.[^.]+\.[^.]+)$/, '$1'); + Cookies.remove( + 'blueking_language', + { + expires: -1, + domain: curDomain, + path: '' + } + ); + // 增加语言cookie有效期为一年 + const expires = new Date(); + expires.setFullYear(expires.getFullYear() + 1); + Cookies.set( + 'blueking_language', + language, + { + expires: expires, + domain: curDomain + } + ); this.setMagicBoxLocale(language); - jsonpRequest(`${window.BK_COMPONENT_API_URL}/api/c/compapi/v2/usermanage/fe_update_user_language/?language=${language}`, { language }); + if (window.BK_COMPONENT_API_URL) { + const url = `${window.BK_COMPONENT_API_URL}/api/c/compapi/v2/usermanage/fe_update_user_language/`; + try { + await jsonpRequest(url, { language }); + } finally { + window.location.reload(); + } + return; + } + window.location.reload(); }, handleSwitchIdentity () { // this.curHeight = document.getElementsByClassName('user-dropdown')[0].offsetHeight this.isShowGradingWrapper = !this.isShowGradingWrapper; }, - - handleBack () { - this.isShowUserDropdown = false; - this.isShowGradingWrapper = false; - this.handleSwitchRole({ id: 0, type: 'staff', name: this.user.role.name }); - }, - + handleLogout () { window.localStorage.removeItem('iam-header-title-cache'); window.localStorage.removeItem('iam-header-name-cache'); diff --git a/frontend/src/components/iam-member-template-table/index.vue b/frontend/src/components/iam-member-template-table/index.vue index c8ce92ffb..e49dfddcc 100644 --- a/frontend/src/components/iam-member-template-table/index.vue +++ b/frontend/src/components/iam-member-template-table/index.vue @@ -249,9 +249,13 @@ fetchSelectedGroupCount () { this.$nextTick(() => { - const selectionCount = document.getElementsByClassName('bk-page-selection-count'); - if (this.$refs.templateTableRef && selectionCount && selectionCount.length && selectionCount[0].children) { - selectionCount[0].children[0].innerHTML = this.currentSelectList.length; + const tableRef = this.$refs.templateTableRef; + if (tableRef && tableRef.$refs && tableRef.$refs.paginationWrapper) { + const paginationWrapper = tableRef.$refs.paginationWrapper; + const selectCount = paginationWrapper.getElementsByClassName('bk-page-selection-count'); + if (selectCount && selectCount.length && selectCount[0].children) { + selectCount[0].children[0].innerHTML = this.currentSelectList.length; + } } }); }, diff --git a/frontend/src/components/iam-view-resource-popover/index.vue b/frontend/src/components/iam-view-resource-popover/index.vue index 530431f03..620f9129c 100644 --- a/frontend/src/components/iam-view-resource-popover/index.vue +++ b/frontend/src/components/iam-view-resource-popover/index.vue @@ -1,36 +1,39 @@ - diff --git a/saas/.editorconfig b/saas/.editorconfig index e43144c4c..fa6c23c1f 100644 --- a/saas/.editorconfig +++ b/saas/.editorconfig @@ -12,7 +12,7 @@ charset = utf-8 # Docstrings and comments use max_line_length = 79 [*.py] -max_line_length = 88 +max_line_length = 119 # Use 2 spaces for the HTML files [*.html] diff --git a/saas/VERSION b/saas/VERSION index b14865f47..63221cd37 100644 --- a/saas/VERSION +++ b/saas/VERSION @@ -1 +1 @@ -1.10.29 +1.10.30 diff --git a/saas/backend/api/management/constants.py b/saas/backend/api/management/constants.py index 6619925ec..2eb402766 100644 --- a/saas/backend/api/management/constants.py +++ b/saas/backend/api/management/constants.py @@ -55,6 +55,7 @@ class ManagementAPIEnum(BaseAPIEnum): V2_GROUP_MEMBER_ADD = auto() V2_GROUP_MEMBER_DELETE = auto() V2_GROUP_MEMBER_EXPIRED_AT_UPDATE = auto() + V2_GROUP_SUBJECT_TEMPLATE_LIST = auto() # 用户组权限 V2_GROUP_POLICY_GRANT = auto() V2_GROUP_POLICY_REVOKE = auto() @@ -66,6 +67,7 @@ class ManagementAPIEnum(BaseAPIEnum): # 用户组归属 V2_USER_GROUPS_BELONG_CHECK = auto() V2_DEPARTMENT_GROUPS_BELONG_CHECK = auto() + V2_MEMBER_GROUPS_DETAIL_LIST = auto() # 分级管理员 V2_GRADE_MANAGER_CREATE = auto() V2_GRADE_MANAGER_UPDATE = auto() @@ -123,6 +125,7 @@ class ManagementAPIEnum(BaseAPIEnum): (V2_GROUP_MEMBER_ADD, "[V2]添加用户组成员"), (V2_GROUP_MEMBER_DELETE, "[V2]删除用户组成员"), (V2_GROUP_MEMBER_EXPIRED_AT_UPDATE, "[V2]用户组成员续期"), + (V2_GROUP_SUBJECT_TEMPLATE_LIST, "[V2]获取用户组人员模板列表"), # 用户组权限 (V2_GROUP_POLICY_GRANT, "[V2]授权用户组"), (V2_GROUP_POLICY_REVOKE, "[V2]回收用户组权限"), @@ -134,6 +137,7 @@ class ManagementAPIEnum(BaseAPIEnum): # 用户组归属 (V2_USER_GROUPS_BELONG_CHECK, "[V2]判断用户与用户组归属"), (V2_DEPARTMENT_GROUPS_BELONG_CHECK, "[V2]判断部门与用户组归属"), + (V2_MEMBER_GROUPS_DETAIL_LIST, "[V2]用户组成员在组内的详情"), # 分级管理员 (V2_GRADE_MANAGER_DETAIL, "[V2]分级管理员详情"), (V2_GRADE_MANAGER_CREATE, "[V2]新建分级管理员"), diff --git a/saas/backend/api/management/v2/serializers.py b/saas/backend/api/management/v2/serializers.py index c7b93e645..19a222065 100644 --- a/saas/backend/api/management/v2/serializers.py +++ b/saas/backend/api/management/v2/serializers.py @@ -22,6 +22,7 @@ from backend.biz.subject_template import SubjectTemplateBiz from backend.service.constants import GroupMemberType from backend.service.models import Subject +from backend.util.serializer import StringArrayField class ManagementSourceSystemSLZ(serializers.Serializer): @@ -189,6 +190,15 @@ def validate(self, data): return data +class ManagementGroupSubjectTemplateSLZ(serializers.Serializer): + id = serializers.CharField(label="人员模板 ID", source="template_id") + name = serializers.SerializerMethodField(label="人员模板名称") + expired_at = serializers.IntegerField(label="过期时间戳(单位秒)") + + def get_name(self, obj): + return self.context["subject_template_name_map"].get(obj.template_id) or obj.template_id + + class ManagementGradeManagerBasicSLZ(serializers.Serializer): id = serializers.IntegerField(label="分级管理员ID") @@ -252,6 +262,53 @@ class ManagementSubjectGroupBelongSLZ(serializers.Serializer): group_ids = serializers.CharField(label="用户组ID,多个以英文逗号分隔", max_length=255, required=True) +class ManagementMemberGroupDetailInputInPathSLZ(serializers.Serializer): + group_member_type = serializers.ChoiceField(help_text="用户组成员类型", choices=GroupMemberType.get_choices()) + member_id = serializers.CharField(help_text="用户组成员 ID", max_length=128) + + def validate(self, attrs): + # 组织 ID 和 人员模板 ID 都必须是整数 + group_member_type = attrs["group_member_type"] + member_id = attrs["member_id"] + if group_member_type in (GroupMemberType.DEPARTMENT.value, GroupMemberType.TEMPLATE.value): + try: + int(member_id) + except ValueError: + raise serializers.ValidationError( + { + "member_id": [f"当 group_member_type 为 {group_member_type} 时,member_id({member_id}) 必须为整数"], + } + ) + + return attrs + + +class ManagementMemberGroupDetailInputSLZ(serializers.Serializer): + group_ids = StringArrayField(help_text="用户组 ID,多个以英文逗号分隔", min_items=1, max_items=100) + + def validate_group_ids(self, value): + try: + [int(i) for i in value] + except ValueError: + raise serializers.ValidationError({"group_ids": ["用户组 ID 必须为整数"]}) + + return value + + +class ManagementMemberGroupDetailOutputSLZ(serializers.Serializer): + id = serializers.IntegerField(help_text="用户组 ID") + name = serializers.CharField(help_text="用户组名称") + description = serializers.CharField(help_text="用户组描述") + created_at = serializers.SerializerMethodField(help_text="加入用户组时间戳") + expired_at = serializers.SerializerMethodField(help_text="过期时间戳") + + def get_created_at(self, obj): + return self.context["subject_group_map"][obj.id]["created_at"] + + def get_expired_at(self, obj): + return self.context["subject_group_map"][obj.id]["expired_at"] + + class ManagementGradeManagerApplicationResultSLZ(serializers.Serializer): id = serializers.CharField(label="申请单据ID") sn = serializers.CharField(label="ITSM审批单SN") diff --git a/saas/backend/api/management/v2/urls.py b/saas/backend/api/management/v2/urls.py index 0935a36cf..7b40c24e6 100644 --- a/saas/backend/api/management/v2/urls.py +++ b/saas/backend/api/management/v2/urls.py @@ -26,37 +26,43 @@ name="open.management.v2.grade_manager", ), # -------------- 用户组本身 -------------- - # 系统管理员下创建用户组 + # 系统管理员下创建用户组(支持同步创建人员模板) path( "grade_managers/-/groups/", views.ManagementSystemManagerGroupViewSet.as_view({"post": "create"}), name="open.management.v2.system_manager_group", ), - # 分级管理员下创建用户组 + # 分级管理员下创建用户组(支持同步创建用户组对应的人员模板) path( "grade_managers//groups/", views.ManagementGradeManagerGroupViewSet.as_view({"post": "create", "get": "list"}), name="open.management.v2.grade_manager_group", ), - # 用户组基本信息更新 & 删除 + # 用户组基本信息更新 & 删除(自动同步删除用户组人员模板) path( "groups//", views.ManagementGroupViewSet.as_view({"put": "update", "delete": "destroy"}), name="open.management.v2.group", ), # -------------- 用户组成员 -------------- - # 用户组成员 + # 用户组成员(增加和删除支持人员模板,查询列表不支持人员模板) path( "groups//members/", views.ManagementGroupMemberViewSet.as_view({"get": "list", "post": "create", "delete": "destroy"}), name="open.management.v2.group_member", ), - # 用户组成员有效期 + # 用户组成员有效期(不支持人员模板) path( "groups//members/-/expired_at/", views.ManagementGroupMemberExpiredAtViewSet.as_view({"put": "update"}), name="open.management.v2.group_member.expired_at", ), + # 用户组下类型为人员模板的成员 + path( + "groups//subject_templates/", + views.ManagementGroupSubjectTemplateViewSet.as_view({"get": "list"}), + name="open.management.v2.group_subject_template", + ), # -------------- 用户组权限 -------------- # 用户组自定义权限 path( @@ -112,6 +118,12 @@ views.ManagementDepartmentGroupBelongViewSet.as_view({"get": "check"}), name="open.management.v2.department_group_belong", ), + # 批量查询某个成员在一批用户组里的详情(支持人员模板) + path( + "group_member_types//members//groups/-/details/", + views.ManagementMemberGroupDetailViewSet.as_view({"get": "list"}), + name="open.management.v2.member_group_detail", + ), # -------------- Approval -------------- # 审批回调 path( diff --git a/saas/backend/api/management/v2/views/__init__.py b/saas/backend/api/management/v2/views/__init__.py index 6a6fb342b..1871097b8 100644 --- a/saas/backend/api/management/v2/views/__init__.py +++ b/saas/backend/api/management/v2/views/__init__.py @@ -24,10 +24,15 @@ ManagementGroupMemberViewSet, ManagementGroupPolicyActionViewSet, ManagementGroupPolicyViewSet, + ManagementGroupSubjectTemplateViewSet, ManagementGroupViewSet, ManagementSystemManagerGroupViewSet, ) -from .subject import ManagementDepartmentGroupBelongViewSet, ManagementUserGroupBelongViewSet +from .subject import ( + ManagementDepartmentGroupBelongViewSet, + ManagementMemberGroupDetailViewSet, + ManagementUserGroupBelongViewSet, +) from .subject_template import ManagementGradeManagerSubjectTemplateViewSet from .subset_manager import ManagementSubsetManagerCreateListViewSet, ManagementSubsetManagerViewSet @@ -37,6 +42,7 @@ "ManagementGroupViewSet", "ManagementGroupMemberViewSet", "ManagementGroupMemberExpiredAtViewSet", + "ManagementGroupSubjectTemplateViewSet", "ManagementGroupPolicyViewSet", "ManagementGroupApplicationViewSet", "ManagementGroupRenewApplicationViewSet", @@ -52,4 +58,5 @@ "ManagementGradeManagerViewSet", "ManagementSubsetManagerViewSet", "ManagementGradeManagerSubjectTemplateViewSet", + "ManagementMemberGroupDetailViewSet", ] diff --git a/saas/backend/api/management/v2/views/group.py b/saas/backend/api/management/v2/views/group.py index d9964fe4e..2e0801901 100644 --- a/saas/backend/api/management/v2/views/group.py +++ b/saas/backend/api/management/v2/views/group.py @@ -30,6 +30,7 @@ ManagementGroupPolicyDeleteSLZ, ManagementGroupRevokeSLZ, ManagementGroupSLZ, + ManagementGroupSubjectTemplateSLZ, ManagementQueryGroupSLZ, ) from backend.apps.group.audit import ( @@ -49,6 +50,7 @@ from backend.apps.policy.models import Policy from backend.apps.policy.serializers import PolicySLZ from backend.apps.role.models import Role +from backend.apps.subject_template.models import SubjectTemplate, SubjectTemplateGroup from backend.audit.audit import add_audit, audit_context_setter, view_audit_decorator from backend.audit.constants import AuditSourceType from backend.biz.group import ( @@ -481,6 +483,50 @@ def update(self, request, *args, **kwargs): return Response({}) +class ManagementGroupSubjectTemplateViewSet(GenericViewSet): + """用户组类型为人员模板的成员""" + + authentication_classes = [ESBAuthentication] + permission_classes = [ManagementAPIPermission] + + management_api_permission = { + "list": ( + VerifyApiParamLocationEnum.GROUP_IN_PATH.value, + ManagementAPIEnum.V2_GROUP_SUBJECT_TEMPLATE_LIST.value, + ) + } + + lookup_field = "id" + queryset = Group.objects.all() + pagination_class = CompatiblePagination + + @swagger_auto_schema( + operation_description="用户组人员模板成员列表", + responses={status.HTTP_200_OK: ManagementGroupMemberSLZ(label="用户组人员模板成员信息", many=True)}, + tags=["management.role.group.subject_template"], + ) + def list(self, request, *args, **kwargs): + group = self.get_object() + + # 查询用户组拥有的权限模板 + queryset = SubjectTemplateGroup.objects.filter(group_id=group.id) + + # 查询模板名称 + subject_template_ids = list(queryset.values_list("template_id", flat=True)) + subject_template_name_map = dict( + SubjectTemplate.objects.filter(id__in=subject_template_ids).values_list("id", "name") + ) + + # 分页 + page = self.paginate_queryset(queryset) + assert page is not None + + serializer = ManagementGroupSubjectTemplateSLZ( + page, many=True, context={"subject_template_name_map": subject_template_name_map} + ) + return self.get_paginated_response(serializer.data) + + class ManagementGroupPolicyViewSet(GenericViewSet): """用户组权限 - 自定义权限""" diff --git a/saas/backend/api/management/v2/views/subject.py b/saas/backend/api/management/v2/views/subject.py index a58cce572..12cadbb2c 100644 --- a/saas/backend/api/management/v2/views/subject.py +++ b/saas/backend/api/management/v2/views/subject.py @@ -8,6 +8,8 @@ an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. """ +from typing import Dict, List + from drf_yasg.utils import swagger_auto_schema from rest_framework import serializers, status from rest_framework.response import Response @@ -16,10 +18,20 @@ from backend.api.authentication import ESBAuthentication from backend.api.management.constants import ManagementAPIEnum, VerifyApiParamLocationEnum from backend.api.management.v2.permissions import ManagementAPIPermission -from backend.api.management.v2.serializers import ManagementSubjectGroupBelongSLZ +from backend.api.management.v2.serializers import ( + ManagementMemberGroupDetailInputInPathSLZ, + ManagementMemberGroupDetailInputSLZ, + ManagementMemberGroupDetailOutputSLZ, + ManagementSubjectGroupBelongSLZ, +) +from backend.apps.group.models import Group +from backend.apps.subject_template.models import SubjectTemplateGroup from backend.biz.group import GroupBiz from backend.common.error_codes import error_codes +from backend.component.iam import list_subject_groups_detail +from backend.service.constants import GroupMemberType from backend.service.models import Subject +from backend.util.time import utc_string_to_timestamp class ManagementUserGroupBelongViewSet(GenericViewSet): @@ -101,3 +113,77 @@ def check(self, request, *args, **kwargs): ) return Response(group_belongs) + + +class ManagementMemberGroupDetailViewSet(GenericViewSet): + """用户组成员在用户组内的详情""" + + authentication_classes = [ESBAuthentication] + permission_classes = [ManagementAPIPermission] + management_api_permission = { + "list": ( + VerifyApiParamLocationEnum.GROUP_IDS_IN_QUERY.value, + ManagementAPIEnum.V2_MEMBER_GROUPS_DETAIL_LIST.value, + ), + } + + pagination_class = None + + @staticmethod + def _get_subject_group_dict(subject: Subject, group_ids: List[int]) -> Dict[int, Dict[str, int]]: + """ + 从后台查询加入的用户组详情 + """ + # Note: 后台支持 group_ids 过滤查询,但最多 100,数据量过多则需要分多次查询 + groups = list_subject_groups_detail(subject.type, subject.id, group_ids) + return { + int(one["id"]): { + "expired_at": one["expired_at"], + "created_at": utc_string_to_timestamp(one["created_at"]), + } + for one in groups + } + + @swagger_auto_schema( + operation_description="用户组成员在用户组内的详情", + responses={status.HTTP_200_OK: ManagementMemberGroupDetailOutputSLZ(label="加入用户组的详细信息", many=True)}, + tags=["management.role.group_member_detail"], + ) + def list(self, request, *args, **kwargs): + # URL 路径参数 获取用户组成员类型和成员 ID + path_slz = ManagementMemberGroupDetailInputInPathSLZ(data=kwargs) + path_slz.is_valid(raise_exception=True) + path_data = path_slz.validated_data + group_member_type, member_id = path_data["group_member_type"], path_data["member_id"] + + # 请求参数 + slz = ManagementMemberGroupDetailInputSLZ(data=request.query_params) + slz.is_valid(raise_exception=True) + data = slz.validated_data + group_ids = list(map(int, data["group_ids"])) + + # 查询成员在组里的详情:过期时间、加入的时间 + subject_group_map = {} + if group_member_type in (GroupMemberType.DEPARTMENT.value, GroupMemberType.USER.value): + # 用户或组织 + subject = Subject(type=group_member_type, id=member_id) + subject_group_map = self._get_subject_group_dict(subject, group_ids) + elif group_member_type == GroupMemberType.TEMPLATE.value: + # 人员模板 + template_groups = SubjectTemplateGroup.objects.filter(template_id=int(member_id), group_id__in=group_ids) + subject_group_map = { + i.group_id: { + "expired_at": i.expired_at, + "created_at": int(i.created_time.timestamp()), + } + for i in template_groups + } + + # 只返回存在关系的用户组 + groups = Group.objects.filter(id__in=list(subject_group_map.keys())) + + return Response( + ManagementMemberGroupDetailOutputSLZ( + groups, many=True, context={"subject_group_map": subject_group_map} + ).data + ) diff --git a/saas/backend/component/iam.py b/saas/backend/component/iam.py index 6ba901d88..43c496df7 100644 --- a/saas/backend/component/iam.py +++ b/saas/backend/component/iam.py @@ -603,6 +603,19 @@ def unfreeze_subjects(subjects: List[Dict]) -> None: return _call_iam_api(http_delete, url_path, data=subjects) +def list_subject_groups_detail(subject_type: str, subject_id: str, group_ids: List[int]) -> List[Dict]: + """ + 查询Subject与用户组的详情(包括加入时间和过期时间) + """ + url_path = "/api/v1/web/subjects-groups/detail" + data = { + "type": subject_type, + "id": subject_id, + "group_ids": ",".join(map(str, group_ids)), + } + return _call_iam_api(http_get, url_path, data=data) + + def check_subject_groups_belong(subject_type: str, subject_id: str, group_ids: List[int]) -> Dict[str, bool]: """ 校验Subject与用户组是否存在关系 diff --git a/saas/backend/healthz/views.py b/saas/backend/healthz/views.py index 0e3566c83..de3b4a683 100644 --- a/saas/backend/healthz/views.py +++ b/saas/backend/healthz/views.py @@ -30,7 +30,7 @@ def healthz(request): checker = HealthChecker() data = {} - for name in ["mysql", "redis", "celery", "iam", "usermgr"]: + for name in ["mysql", "redis", "celery", "iam"]: ok, message = getattr(checker, name)() if not ok: return HttpResponseServerError(message) diff --git a/saas/backend/util/serializer.py b/saas/backend/util/serializer.py new file mode 100644 index 000000000..d469e2284 --- /dev/null +++ b/saas/backend/util/serializer.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +""" +TencentBlueKing is pleased to support the open source community by making 蓝鲸智云-权限中心(BlueKing-IAM) available. +Copyright (C) 2017-2021 THL A29 Limited, a Tencent company. All rights reserved. +Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License. +You may obtain a copy of the License at http://opensource.org/licenses/MIT +Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on +an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the +specific language governing permissions and limitations under the License. +""" + +from typing import List, Optional + +from django.utils.translation import gettext_lazy as _ +from rest_framework import fields +from rest_framework.fields import empty + + +class StringArrayField(fields.CharField): + """String representation of an array field""" + + default_error_messages = { + "max_items": _("至多包含 {max_items} 个对象."), + "min_items": _("至少包含 {min_items} 个对象."), + } + + def __init__( + self, min_items: Optional[int] = None, max_items: Optional[int] = None, delimiter: str = ",", **kwargs + ): + self.min_items = min_items + self.max_items = max_items + self.delimiter = delimiter + + super().__init__(**kwargs) + + def run_validation(self, data=empty): + data = super().run_validation(data) + + item_cnt = len(data) + if self.min_items is not None and item_cnt < self.min_items: + self.fail("min_items", min_items=self.min_items) + + if self.max_items is not None and item_cnt > self.max_items: + self.fail("max_items", max_items=self.max_items) + + return data + + def to_internal_value(self, data) -> List[str]: + # convert string to list + data = super().to_internal_value(data) + return [x.strip() for x in data.split(self.delimiter) if x] diff --git a/saas/backend/util/time.py b/saas/backend/util/time.py index 509870534..ed53eeba1 100644 --- a/saas/backend/util/time.py +++ b/saas/backend/util/time.py @@ -29,6 +29,14 @@ def utc_string_to_local(str_time): return utc_to_local(t) +def utc_string_to_timestamp(str_time: str) -> int: + """ + 后端UTC时间转换为时间戳 + """ + t = string_to_datetime(str_time, fmt="%Y-%m-%dT%H:%M:%SZ") + return int(t.timestamp()) + + def utc_to_local(utc_time): tz = timezone.get_current_timezone() dt = datetime.datetime.utcnow() diff --git a/saas/config/ce.py b/saas/config/ce.py index 8867eab3e..c0cf4df04 100644 --- a/saas/config/ce.py +++ b/saas/config/ce.py @@ -11,6 +11,8 @@ import os import random import string +from pathlib import Path +from typing import Any, Dict, List, Optional from urllib.parse import urlparse from . import RequestIDFilter @@ -207,160 +209,139 @@ STATIC_URL = env.str("BKPAAS_STATIC_URL", default=SITE_URL + "staticfiles/") AJAX_URL_PREFIX = SITE_URL + "api/v1" -# 只对正式环境日志级别进行配置,可以在这里修改 -LOG_LEVEL = env.str("BKAPP_LOG_LEVEL", default="ERROR") -_LOG_CLASS = "logging.handlers.RotatingFileHandler" -if IS_LOCAL: - LOG_LEVEL = "DEBUG" - _LOG_DIR = os.path.join(os.path.dirname(BASE_DIR), "logs", APP_CODE) - _LOG_NAME_PREFIX = env.str("BKPAAS_LOG_NAME_PREFIX", default=APP_CODE) - _LOGGING_FORMAT = { - "format": ( - "%(levelname)s [%(asctime)s] %(pathname)s " - "%(lineno)d %(funcName)s %(process)d %(thread)d " - "\n \t %(request_id)s\t%(message)s \n" - ), - "datefmt": "%Y-%m-%d %H:%M:%S", - } +# 日志等级,高于或等于该等级的日志才会被记录 +LOG_LEVEL = env.str("BKAPP_LOG_LEVEL", default=None) or env.str("LOG_LEVEL", default="ERROR") +# 用于存放日志文件的目录,默认值为空,表示不使用任何文件,所有日志直接输出到控制台。 +# 可配置为有效目录,支持相对或绝对地址,比如:"logs" 或 "/var/lib/app_logs/"。 +# 配置本选项后,原有的控制台日志输出将关闭。 +LOGGING_DIRECTORY = env.str("BKPAAS_APP_LOG_PATH", default=None) or env.str("LOGGING_DIRECTORY", default=None) +# 日志文件格式,可选值为:json/text +LOGGING_FILE_FORMAT = env.str("LOGGING_FILE_FORMAT", default="json") + +if LOGGING_DIRECTORY is None: + logging_to_console = True + logging_directory = None else: - _LOG_DIR = env.str("BKPAAS_APP_LOG_PATH", default="/") - _RAND_STR = "".join(random.sample(string.ascii_letters + string.digits, 4)) - _LOG_NAME_PREFIX = "%s-%s" % (env.str("BKPAAS_PROCESS_TYPE"), _RAND_STR) - - _LOGGING_FORMAT = { - "()": "pythonjsonlogger.jsonlogger.JsonFormatter", - "fmt": ( - "%(levelname)s %(asctime)s %(pathname)s %(lineno)d " - "%(funcName)s %(process)d %(thread)d %(request_id)s %(message)s" - ), - } -if not os.path.exists(_LOG_DIR): - os.makedirs(_LOG_DIR) -LOGGING = { - "version": 1, - "disable_existing_loggers": False, - "filters": { - "request_id_filter": { - "()": RequestIDFilter, - } - }, - "formatters": { - "verbose": _LOGGING_FORMAT, - "simple": {"format": "%(levelname)s %(message)s"}, - "bk_audit": {"format": "%(message)s"}, - }, - "handlers": { - "null": { - "level": "DEBUG", - "class": "logging.NullHandler", - }, - "console": {"level": "DEBUG", "class": "logging.StreamHandler", "formatter": "simple"}, - "root": { - "class": _LOG_CLASS, - "formatter": "verbose", - "filename": os.path.join(_LOG_DIR, "%s-django.log" % _LOG_NAME_PREFIX), - "maxBytes": 1024 * 1024 * 10, - "backupCount": 5, - "filters": ["request_id_filter"], - }, - "component": { - "class": _LOG_CLASS, - "formatter": "verbose", - "filename": os.path.join(_LOG_DIR, "%s-component.log" % _LOG_NAME_PREFIX), - "maxBytes": 1024 * 1024 * 10, - "backupCount": 5, - "filters": ["request_id_filter"], - }, - "mysql": { - "class": _LOG_CLASS, - "formatter": "verbose", - "filename": os.path.join(_LOG_DIR, "%s-mysql.log" % _LOG_NAME_PREFIX), - "maxBytes": 1024 * 1024 * 10, - "backupCount": 5, + logging_to_console = False + # The dir allows both absolute and relative path, when it's relative, combine + # the value with project's base directory + logging_directory = Path(BASE_DIR) / Path(LOGGING_DIRECTORY) + logging_directory.mkdir(exist_ok=True) + +# 是否总是打印日志到控制台,默认关闭 +LOGGING_ALWAYS_CONSOLE = env.bool("LOGGING_ALWAYS_CONSOLE", default=False) +if LOGGING_ALWAYS_CONSOLE: + logging_to_console = True + + +def build_logging_config(log_level: str, to_console: bool, file_directory: Optional[Path], file_format: str) -> Dict: + """Build the global logging config dict. + + :param log_level: The log level. + :param to_console: If True, output the logs to the console. + :param file_directory: If the value is not None, output the logs to the given directory. + :param file_format: The format of the logging file, "json" or "text". + :return: The logging config dict. + """ + + def _build_file_handler(log_path: Path, filename: str, format: str) -> Dict: + if format not in ("json", "text"): + raise ValueError(f"Invalid file_format: {file_format}") + formatter = "verbose_json" if format == "json" else "verbose" + return { + "class": "concurrent_log_handler.ConcurrentRotatingFileHandler", + "level": log_level, + "formatter": formatter, "filters": ["request_id_filter"], - }, - "celery": { - "class": _LOG_CLASS, - "formatter": "verbose", - "filename": os.path.join(_LOG_DIR, "%s-celery.log" % _LOG_NAME_PREFIX), - "maxBytes": 1024 * 1024 * 10, + "filename": str(log_path / filename), + # Set max file size to 100MB + "maxBytes": 100 * 1024 * 1024, "backupCount": 5, - "filters": ["request_id_filter"], - }, - "organization": { - "class": _LOG_CLASS, + } + + handlers_config: Dict[str, Any] = { + "null": {"level": log_level, "class": "logging.NullHandler"}, + "console": { + "level": log_level, + "class": "logging.StreamHandler", "formatter": "verbose", - "filename": os.path.join(_LOG_DIR, "%s-json.log" % _LOG_NAME_PREFIX), - "maxBytes": 1024 * 1024 * 10, - "backupCount": 5, "filters": ["request_id_filter"], }, - "bk_audit": { - "class": _LOG_CLASS, + } + # 生成指定 Logger 对应的 Handlers + logger_handlers_map: Dict[str, List[str]] = {} + for logger_name in ["root", "component", "celery", "organization"]: + handlers = [] + + if to_console: + handlers.append("console") + + if file_directory: + # 生成 logger 对应日志文件的 Handler + handlers_config[logger_name] = _build_file_handler( + file_directory, f"{logger_name}-{file_format}.log", file_format + ) + handlers.append(logger_name) + + logger_handlers_map[logger_name] = handlers + + # bk_audit 特殊 Handler + handlers_config["bk_audit"] = {"class": "logging.NullHandler"} + if file_directory: + handlers_config["bk_audit"] = { + "class": "concurrent_log_handler.ConcurrentRotatingFileHandler", "formatter": "bk_audit", - "filename": os.path.join(_LOG_DIR, "%s-audit.log" % _LOG_NAME_PREFIX), + "filename": str(file_directory / "audit.log"), "maxBytes": 1024 * 1024 * 10, "backupCount": 5, + } + + return { + "version": 1, + "disable_existing_loggers": False, + "filters": { + "request_id_filter": {"()": RequestIDFilter}, }, - }, - "loggers": { - "django": { - "handlers": ["null"], - "level": "INFO", - "propagate": True, - }, - "django.server": { - "handlers": ["console"], - "level": LOG_LEVEL, - "propagate": True, - }, - "django.request": { - "handlers": ["root"], - "level": "ERROR", - "propagate": True, - }, - "django.db.backends": { - "handlers": ["mysql"], - "level": LOG_LEVEL, - "propagate": True, - }, - # the root logger ,用于整个project的logger - "root": { - "handlers": ["root"], - "level": LOG_LEVEL, - "propagate": True, - }, - # 组件调用日志 - "component": { - "handlers": ["component"], - "level": LOG_LEVEL, - "propagate": True, - }, - "celery": { - "handlers": ["celery"], - "level": LOG_LEVEL, - "propagate": True, - }, - # 普通app日志 - "app": { - "handlers": ["root"], - "level": LOG_LEVEL, - "propagate": True, - }, - # 组织架构同步日志 - "organization": { - "handlers": ["root" if IS_LOCAL else "organization"], - "level": LOG_LEVEL, - "propagate": True, + "formatters": { + "verbose": { + "format": ( + "%(name)s %(levelname)s [%(asctime)s] %(pathname)s %(lineno)d %(funcName)s %(process)d %(thread)d " + "\n \t%(request_id)s\t%(message)s \n" + ), + "datefmt": "%Y-%m-%d %H:%M:%S", + }, + "verbose_json": { + "()": "pythonjsonlogger.jsonlogger.JsonFormatter", + "fmt": ( + "%(name)s %(levelname)s %(asctime)s %(pathname)s %(lineno)d " + "%(funcName)s %(process)d %(thread)d %(request_id)s %(message)s" + ), + }, + "simple": {"format": "%(name)s %(levelname)s %(message)s"}, + "bk_audit": {"format": "%(message)s"}, }, - # 审计日志文件 - "bk_audit": { - "handlers": ["bk_audit"], - "level": "INFO", - "propagate": True, + "handlers": handlers_config, + # the root logger, 用于整个项目的默认 logger + "root": {"handlers": logger_handlers_map["root"], "level": log_level, "propagate": False}, + "loggers": { + "django": {"handlers": ["null"], "level": "INFO", "propagate": True}, + "django.server": {"handlers": ["console"], "level": log_level, "propagate": False}, + "django.request": {"handlers": logger_handlers_map["root"], "level": log_level, "propagate": False}, + # 除 root 外的其他指定 Logger + **{ + logger_name: {"handlers": handlers, "level": log_level, "propagate": False} + for logger_name, handlers in logger_handlers_map.items() + if logger_name != "root" + }, + # 普通app日志 + "app": {"handlers": logger_handlers_map["root"], "level": LOG_LEVEL, "propagate": True}, + # 审计日志文件 + "bk_audit": {"handlers": ["bk_audit"], "level": "INFO", "propagate": True}, }, - }, -} + } + + +LOGGING = build_logging_config(LOG_LEVEL, logging_to_console, logging_directory, LOGGING_FILE_FORMAT) APP_API_URL = APP_URL # 前后端分离架构下, APP_URL 与 APP_API_URL 不一样 diff --git a/saas/poetry.lock b/saas/poetry.lock index a294a2c9f..8f666132a 100644 --- a/saas/poetry.lock +++ b/saas/poetry.lock @@ -416,6 +416,17 @@ category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +[[package]] +name = "concurrent-log-handler" +version = "0.9.25" +description = "RotatingFileHandler replacement with concurrency, gzip and Windows support" +category = "main" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +portalocker = ">=1.6.0" + [[package]] name = "contextvars" version = "2.4" @@ -1451,6 +1462,22 @@ importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} [package.extras] dev = ["pre-commit", "tox"] +[[package]] +name = "portalocker" +version = "2.7.0" +description = "Wraps the portalocker recipe for easy usage" +category = "main" +optional = false +python-versions = ">=3.5" + +[package.dependencies] +pywin32 = {version = ">=226", markers = "platform_system == \"Windows\""} + +[package.extras] +docs = ["sphinx (>=1.7.1)"] +redis = ["redis"] +tests = ["pytest (>=5.4.1)", "pytest-cov (>=2.8.1)", "pytest-mypy (>=0.8.0)", "pytest-timeout (>=2.1.0)", "redis", "sphinx (>=6.0.0)"] + [[package]] name = "prometheus-client" version = "0.13.0" @@ -1691,6 +1718,14 @@ category = "main" optional = false python-versions = "*" +[[package]] +name = "pywin32" +version = "306" +description = "Python for Window Extensions" +category = "main" +optional = false +python-versions = "*" + [[package]] name = "pyyaml" version = "5.4.1" @@ -2059,7 +2094,7 @@ testing = ["coverage (>=5.0.3)", "zope.event", "zope.testing"] [metadata] lock-version = "1.1" python-versions = "3.6.6" -content-hash = "c8a8f658bf82bde36e847d3f5ca4876471b7f5ca2bc752d94d2a1e6110a0512c" +content-hash = "c9800affbfce17977e6848f1613834fcd7b3fc4cb2feb60fa7114c263b3c4aee" [metadata.files] aenum = [ @@ -2225,6 +2260,10 @@ colorama = [ {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, ] +concurrent-log-handler = [ + {file = "concurrent_log_handler-0.9.25-py3-none-any.whl", hash = "sha256:157bee12914aa2a72246d1d0641ce07c1aa7a55faa3322bed02f21e60395eb82"}, + {file = "concurrent_log_handler-0.9.25.tar.gz", hash = "sha256:1e2c6f021414e214d3dac66107894827a3e78db63018304a4f29e55ba549ac22"}, +] contextvars = [ {file = "contextvars-2.4.tar.gz", hash = "sha256:f38c908aaa59c14335eeea12abea5f443646216c4e29380d7bf34d2018e2c39e"}, ] @@ -2869,6 +2908,10 @@ pluggy = [ {file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"}, {file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"}, ] +portalocker = [ + {file = "portalocker-2.7.0-py2.py3-none-any.whl", hash = "sha256:a07c5b4f3985c3cf4798369631fb7011adb498e2a46d8440efc75a8f29a0f983"}, + {file = "portalocker-2.7.0.tar.gz", hash = "sha256:032e81d534a88ec1736d03f780ba073f047a06c478b06e2937486f334e955c51"}, +] prometheus-client = [ {file = "prometheus_client-0.13.0-py3-none-any.whl", hash = "sha256:70782d19ea1a3aeb8523aa07780dbee6a595e566198ab4ed7fdc32b53b5fa1d1"}, {file = "prometheus_client-0.13.0.tar.gz", hash = "sha256:3fdc6fc5b03a9eaee44d015e2913b496864b9ad6557013f23e28f926d7b62913"}, @@ -3091,6 +3134,22 @@ pytz = [ {file = "pytz-2022.6-py2.py3-none-any.whl", hash = "sha256:222439474e9c98fced559f1709d89e6c9cbf8d79c794ff3eb9f8800064291427"}, {file = "pytz-2022.6.tar.gz", hash = "sha256:e89512406b793ca39f5971bc999cc538ce125c0e51c27941bef4568b460095e2"}, ] +pywin32 = [ + {file = "pywin32-306-cp310-cp310-win32.whl", hash = "sha256:06d3420a5155ba65f0b72f2699b5bacf3109f36acbe8923765c22938a69dfc8d"}, + {file = "pywin32-306-cp310-cp310-win_amd64.whl", hash = "sha256:84f4471dbca1887ea3803d8848a1616429ac94a4a8d05f4bc9c5dcfd42ca99c8"}, + {file = "pywin32-306-cp311-cp311-win32.whl", hash = "sha256:e65028133d15b64d2ed8f06dd9fbc268352478d4f9289e69c190ecd6818b6407"}, + {file = "pywin32-306-cp311-cp311-win_amd64.whl", hash = "sha256:a7639f51c184c0272e93f244eb24dafca9b1855707d94c192d4a0b4c01e1100e"}, + {file = "pywin32-306-cp311-cp311-win_arm64.whl", hash = "sha256:70dba0c913d19f942a2db25217d9a1b726c278f483a919f1abfed79c9cf64d3a"}, + {file = "pywin32-306-cp312-cp312-win32.whl", hash = "sha256:383229d515657f4e3ed1343da8be101000562bf514591ff383ae940cad65458b"}, + {file = "pywin32-306-cp312-cp312-win_amd64.whl", hash = "sha256:37257794c1ad39ee9be652da0462dc2e394c8159dfd913a8a4e8eb6fd346da0e"}, + {file = "pywin32-306-cp312-cp312-win_arm64.whl", hash = "sha256:5821ec52f6d321aa59e2db7e0a35b997de60c201943557d108af9d4ae1ec7040"}, + {file = "pywin32-306-cp37-cp37m-win32.whl", hash = "sha256:1c73ea9a0d2283d889001998059f5eaaba3b6238f767c9cf2833b13e6a685f65"}, + {file = "pywin32-306-cp37-cp37m-win_amd64.whl", hash = "sha256:72c5f621542d7bdd4fdb716227be0dd3f8565c11b280be6315b06ace35487d36"}, + {file = "pywin32-306-cp38-cp38-win32.whl", hash = "sha256:e4c092e2589b5cf0d365849e73e02c391c1349958c5ac3e9d5ccb9a28e017b3a"}, + {file = "pywin32-306-cp38-cp38-win_amd64.whl", hash = "sha256:e8ac1ae3601bee6ca9f7cb4b5363bf1c0badb935ef243c4733ff9a393b1690c0"}, + {file = "pywin32-306-cp39-cp39-win32.whl", hash = "sha256:e25fd5b485b55ac9c057f67d94bc203f3f6595078d1fb3b458c9c28b7153a802"}, + {file = "pywin32-306-cp39-cp39-win_amd64.whl", hash = "sha256:39b61c15272833b5c329a2989999dcae836b1eed650252ab1b7bfbe1d59f30f4"}, +] pyyaml = [ {file = "PyYAML-5.4.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:3b2b1824fe7112845700f815ff6a489360226a5609b96ec2190a45e62a9fc922"}, {file = "PyYAML-5.4.1-cp27-cp27m-win32.whl", hash = "sha256:129def1b7c1bf22faffd67b8f3724645203b79d8f4cc81f674654d9902cb4393"}, diff --git a/saas/pyproject.toml b/saas/pyproject.toml index 7b6768b4a..0f47673ea 100644 --- a/saas/pyproject.toml +++ b/saas/pyproject.toml @@ -142,6 +142,7 @@ opentelemetry-semantic-conventions = "0.27b0" sqlparse = "0.4.4" urllib3 = "1.26.18" future = "0.18.3" +concurrent-log-handler = "0.9.25" [tool.poetry.dev-dependencies] # For flake8 support pyproject.toml diff --git a/saas/requirements.txt b/saas/requirements.txt index cdca4959d..7aa8e32e7 100644 --- a/saas/requirements.txt +++ b/saas/requirements.txt @@ -23,6 +23,7 @@ click-didyoumean==0.3.0; python_full_version >= "3.6.2" and python_full_version click-plugins==1.1.1; python_version >= "3.6" click-repl==0.2.0; python_version >= "3.6" click==7.1.2; python_full_version >= "3.6.2" and python_version >= "3.6" and python_version < "3.11" and python_full_version < "4.0.0" and (python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6") +concurrent-log-handler==0.9.25; python_version >= "3.6" contextvars==2.4; python_version < "3.7" and python_version >= "3.6" coreapi==2.3.3; python_version >= "3.6" coreschema==0.0.4; python_version >= "3.6" @@ -85,6 +86,7 @@ opentelemetry-sdk==1.8.0; python_version >= "3.6" opentelemetry-semantic-conventions==0.27b0; python_version >= "3.6" opentelemetry-util-http==0.27b0; python_version >= "3.6" packaging==21.0; python_full_version >= "3.6.1" and python_full_version < "4.0.0" and python_version >= "3.6" +portalocker==2.7.0; python_version >= "3.6" prometheus-client==0.13.0; python_version >= "3.6" prompt-toolkit==3.0.36; python_full_version >= "3.6.2" and python_version >= "3.6" protobuf==3.19.5; python_version >= "3.5" @@ -100,6 +102,7 @@ python-dateutil==2.8.2; python_version >= "2.7" and python_full_version < "3.0.0 python-editor==1.0.4; python_full_version >= "3.6.2" and python_version < "3.11" python-json-logger==0.1.7 pytz==2022.6 +pywin32==306; platform_system == "Windows" and python_version >= "3.6" pyyaml==5.4.1; python_full_version >= "3.6.1" and python_full_version < "4.0.0" redis==4.3.6; python_version >= "3.6" requests==2.27.1; (python_version >= "2.7" and python_full_version < "3.0.0") or (python_full_version >= "3.6.0") diff --git a/saas/requirements_dev.txt b/saas/requirements_dev.txt index c68066f91..ac5e39fae 100644 --- a/saas/requirements_dev.txt +++ b/saas/requirements_dev.txt @@ -29,6 +29,7 @@ click-plugins==1.1.1; python_version >= "3.6" click-repl==0.2.0; python_version >= "3.6" click==7.1.2; python_full_version >= "3.6.2" and python_version >= "3.6" and python_version < "3.11" and (python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.5.0" and python_version >= "3.6") and python_full_version < "4.0.0" colorama==0.4.4; python_version >= "3.6" and python_full_version < "3.0.0" and sys_platform == "win32" and platform_system == "Windows" or sys_platform == "win32" and python_version >= "3.6" and python_full_version >= "3.5.0" and platform_system == "Windows" +concurrent-log-handler==0.9.25; python_version >= "3.6" contextvars==2.4; python_version < "3.7" and python_version >= "3.6" converge==0.9.8 coreapi==2.3.3; python_version >= "3.6" @@ -109,6 +110,7 @@ packaging==21.0; python_full_version >= "3.6.1" and python_full_version < "4.0.0 pathspec==0.9.0; python_full_version >= "3.6.2" pbr==5.11.0; python_version >= "3.6" pluggy==0.13.1; python_version >= "3.6" and python_full_version < "3.0.0" or python_full_version >= "3.4.0" and python_version >= "3.6" +portalocker==2.7.0; python_version >= "3.6" prometheus-client==0.13.0; python_version >= "3.6" prompt-toolkit==3.0.36; python_full_version >= "3.6.2" and python_version >= "3.6" protobuf==3.19.5; python_version >= "3.5" @@ -131,6 +133,7 @@ python-dateutil==2.8.2; python_version >= "2.7" and python_full_version < "3.0.0 python-editor==1.0.4; python_full_version >= "3.6.2" and python_version < "3.11" python-json-logger==0.1.7 pytz==2022.6 +pywin32==306; platform_system == "Windows" and python_version >= "3.6" pyyaml==5.4.1; python_full_version >= "3.6.1" and python_full_version < "4.0.0" and (python_version >= "3.5" and python_full_version < "3.0.0" or python_full_version >= "3.6.0" and python_version >= "3.5") redis==4.3.6; python_version >= "3.6" regex==2021.8.3; python_full_version >= "3.6.2" diff --git a/saas/resources/apigateway/bk_apigw_resources_bk-iam.yaml b/saas/resources/apigateway/bk_apigw_resources_bk-iam.yaml index 35e04ed12..103fb6d82 100644 --- a/saas/resources/apigateway/bk_apigw_resources_bk-iam.yaml +++ b/saas/resources/apigateway/bk_apigw_resources_bk-iam.yaml @@ -5,14 +5,14 @@ info: title: API Gateway Resources description: '' schemes: -- http + - http paths: /api/v1/engine/batch-search: post: operationId: engine_batch_search description: 批量检索 tags: - - engine + - engine responses: default: description: '' @@ -29,20 +29,20 @@ paths: upstreams: loadbalance: roundrobin hosts: - - host: http://{env.engine} - weight: 100 - transformHeaders: {} + - host: http://{env.engine} + weight: 100 + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v1/engine/healthz: get: operationId: engine_healthz description: 检查engine服务是否健康 tags: - - engine + - engine responses: default: description: '' @@ -59,21 +59,21 @@ paths: upstreams: loadbalance: roundrobin hosts: - - host: http://{env.engine} - weight: 100 - transformHeaders: {} + - host: http://{env.engine} + weight: 100 + transformHeaders: { } authConfig: userVerifiedRequired: false appVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v1/engine/ping: get: operationId: engine_ping description: 检查engine连通性 tags: - - engine + - engine responses: default: description: '' @@ -90,21 +90,21 @@ paths: upstreams: loadbalance: roundrobin hosts: - - host: http://{env.engine} - weight: 100 - transformHeaders: {} + - host: http://{env.engine} + weight: 100 + transformHeaders: { } authConfig: userVerifiedRequired: false appVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v1/engine/search: post: operationId: engine_search description: 检索 tags: - - engine + - engine responses: default: description: '' @@ -121,20 +121,20 @@ paths: upstreams: loadbalance: roundrobin hosts: - - host: http://{env.engine} - weight: 100 - transformHeaders: {} + - host: http://{env.engine} + weight: 100 + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v1/engine/version: get: operationId: engine_version description: 检查engine程序版本 tags: - - engine + - engine responses: default: description: '' @@ -151,20 +151,20 @@ paths: upstreams: loadbalance: roundrobin hosts: - - host: http://{env.engine} - weight: 100 - transformHeaders: {} + - host: http://{env.engine} + weight: 100 + transformHeaders: { } authConfig: userVerifiedRequired: false appVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] /api/v1/model/systems: post: operationId: system_create description: 新增 system tags: - - model + - model responses: default: description: '' @@ -181,20 +181,20 @@ paths: upstreams: loadbalance: roundrobin hosts: - - host: http://{env.backend} - weight: 100 - transformHeaders: {} + - host: http://{env.backend} + weight: 100 + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v1/model/systems/{system_id}: get: operationId: system_get description: 查询 system tags: - - model + - model responses: default: description: '' @@ -211,19 +211,19 @@ paths: upstreams: loadbalance: roundrobin hosts: - - host: http://{env.backend} - weight: 100 - transformHeaders: {} + - host: http://{env.backend} + weight: 100 + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: put: operationId: system_update description: 更新 system tags: - - model + - model responses: default: description: '' @@ -240,20 +240,20 @@ paths: upstreams: loadbalance: roundrobin hosts: - - host: http://{env.backend} - weight: 100 - transformHeaders: {} + - host: http://{env.backend} + weight: 100 + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v1/model/systems/{system_id}/actions: delete: operationId: system_batch_delete_actions description: 批量删除actions tags: - - model + - model responses: default: description: '' @@ -270,19 +270,19 @@ paths: upstreams: loadbalance: roundrobin hosts: - - host: http://{env.backend} - weight: 100 - transformHeaders: {} + - host: http://{env.backend} + weight: 100 + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: post: operationId: system_add_actions description: 新增actions tags: - - model + - model responses: default: description: '' @@ -299,20 +299,20 @@ paths: upstreams: loadbalance: roundrobin hosts: - - host: http://{env.backend} - weight: 100 - transformHeaders: {} + - host: http://{env.backend} + weight: 100 + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v1/model/systems/{system_id}/actions/{action_id}: delete: operationId: system_delete_action description: 删除action tags: - - model + - model responses: default: description: '' @@ -329,19 +329,19 @@ paths: upstreams: loadbalance: roundrobin hosts: - - host: http://{env.backend} - weight: 100 - transformHeaders: {} + - host: http://{env.backend} + weight: 100 + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: put: operationId: system_update_action description: 更新action tags: - - model + - model responses: default: description: '' @@ -358,20 +358,20 @@ paths: upstreams: loadbalance: roundrobin hosts: - - host: http://{env.backend} - weight: 100 - transformHeaders: {} + - host: http://{env.backend} + weight: 100 + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v1/model/systems/{system_id}/actions/{action_id}/policies: delete: operationId: system_delete_action_policies description: 删除action的policies tags: - - model + - model responses: default: description: '' @@ -388,20 +388,20 @@ paths: upstreams: loadbalance: roundrobin hosts: - - host: http://{env.backend} - weight: 100 - transformHeaders: {} + - host: http://{env.backend} + weight: 100 + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v1/model/systems/{system_id}/clients: get: operationId: system_get_clients description: 查询 system clients tags: - - model + - model responses: default: description: '' @@ -418,20 +418,20 @@ paths: upstreams: loadbalance: roundrobin hosts: - - host: http://{env.backend} - weight: 100 - transformHeaders: {} + - host: http://{env.backend} + weight: 100 + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v1/model/systems/{system_id}/configs/{name}: post: operationId: system_add_configs description: 配置新增name=common_actions/feature_shield_rules/resource_creator_actions tags: - - model + - model responses: default: description: '' @@ -448,19 +448,19 @@ paths: upstreams: loadbalance: roundrobin hosts: - - host: http://{env.backend} - weight: 100 - transformHeaders: {} + - host: http://{env.backend} + weight: 100 + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: put: operationId: system_update_configs description: 配置更新name=common_actions/feature_shield_rules/resource_creator_actions tags: - - model + - model responses: default: description: '' @@ -477,20 +477,20 @@ paths: upstreams: loadbalance: roundrobin hosts: - - host: http://{env.backend} - weight: 100 - transformHeaders: {} + - host: http://{env.backend} + weight: 100 + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v1/model/systems/{system_id}/instance-selections: delete: operationId: system_batch_delete_instance_selections description: 批量删除 instance-selections tags: - - model + - model responses: default: description: '' @@ -507,19 +507,19 @@ paths: upstreams: loadbalance: roundrobin hosts: - - host: http://{env.backend} - weight: 100 - transformHeaders: {} + - host: http://{env.backend} + weight: 100 + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: post: operationId: system_add_instance_selections description: 新增instance_selections tags: - - model + - model responses: default: description: '' @@ -536,20 +536,20 @@ paths: upstreams: loadbalance: roundrobin hosts: - - host: http://{env.backend} - weight: 100 - transformHeaders: {} + - host: http://{env.backend} + weight: 100 + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v1/model/systems/{system_id}/instance-selections/{instance_selection_id}: delete: operationId: system_delete_instance_selection description: 删除 instance_selection tags: - - model + - model responses: default: description: '' @@ -566,19 +566,19 @@ paths: upstreams: loadbalance: roundrobin hosts: - - host: http://{env.backend} - weight: 100 - transformHeaders: {} + - host: http://{env.backend} + weight: 100 + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: put: operationId: system_update_instance_selection description: 更新 instance_selection tags: - - model + - model responses: default: description: '' @@ -595,20 +595,20 @@ paths: upstreams: loadbalance: roundrobin hosts: - - host: http://{env.backend} - weight: 100 - transformHeaders: {} + - host: http://{env.backend} + weight: 100 + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v1/model/systems/{system_id}/query: get: operationId: system_query description: 查询 system 通用信息 tags: - - model + - model responses: default: description: '' @@ -625,20 +625,20 @@ paths: upstreams: loadbalance: roundrobin hosts: - - host: http://{env.backend} - weight: 100 - transformHeaders: {} + - host: http://{env.backend} + weight: 100 + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v1/model/systems/{system_id}/resource-types: delete: operationId: system_batch_delete_resource_types description: 批量删除 resource_type tags: - - model + - model responses: default: description: '' @@ -655,19 +655,19 @@ paths: upstreams: loadbalance: roundrobin hosts: - - host: http://{env.backend} - weight: 100 - transformHeaders: {} + - host: http://{env.backend} + weight: 100 + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: post: operationId: system_add_resource_types description: 新增resource_type tags: - - model + - model responses: default: description: '' @@ -684,20 +684,20 @@ paths: upstreams: loadbalance: roundrobin hosts: - - host: http://{env.backend} - weight: 100 - transformHeaders: {} + - host: http://{env.backend} + weight: 100 + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v1/model/systems/{system_id}/resource-types/{resource_type_id}: delete: operationId: system_delete_resource_types description: 删除 resource_type tags: - - model + - model responses: default: description: '' @@ -714,19 +714,19 @@ paths: upstreams: loadbalance: roundrobin hosts: - - host: http://{env.backend} - weight: 100 - transformHeaders: {} + - host: http://{env.backend} + weight: 100 + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: put: operationId: system_update_resource_types description: 更新 resource_type tags: - - model + - model responses: default: description: '' @@ -743,20 +743,20 @@ paths: upstreams: loadbalance: roundrobin hosts: - - host: http://{env.backend} - weight: 100 - transformHeaders: {} + - host: http://{env.backend} + weight: 100 + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v1/model/systems/{system_id}/token: get: operationId: system_get_token description: 查询 system token tags: - - model + - model responses: default: description: '' @@ -773,19 +773,19 @@ paths: upstreams: loadbalance: roundrobin hosts: - - host: http://{env.backend} - weight: 100 - transformHeaders: {} + - host: http://{env.backend} + weight: 100 + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] /api/v1/open/application/: post: operationId: application description: 接入系统权限申请 tags: - - open + - open responses: default: description: '' @@ -799,19 +799,19 @@ paths: path: /api/v1/open/application/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v1/open/application/approval_bot/role/: post: operationId: approval_bot_callback_role description: 审批机器人角色回调 tags: - - open + - open responses: default: description: '' @@ -825,19 +825,19 @@ paths: path: /api/v1/open/application/approval_bot/role/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v1/open/application/approval_bot/user/: post: operationId: approval_bot_callback_user description: 审批机器人用户续期回调 tags: - - open + - open responses: default: description: '' @@ -851,19 +851,19 @@ paths: path: /api/v1/open/application/approval_bot/user/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v1/open/application/policies/: post: operationId: application_grant_policy description: 创建自定义权限申请单 tags: - - open + - open responses: default: description: '' @@ -877,19 +877,19 @@ paths: path: /api/v1/open/application/policies/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v1/open/application/{sn}/: get: operationId: application_detail description: 申请单详情 tags: - - open + - open responses: default: description: '' @@ -903,19 +903,19 @@ paths: path: /api/v1/open/application/{sn}/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v1/open/authorization/batch_instance/: post: operationId: authorization_batch_instance description: 批量操作批量资源授权回收, deprecated tags: - - open + - open responses: default: description: '' @@ -929,19 +929,19 @@ paths: path: /api/v1/open/authorization/batch_instance/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v1/open/authorization/batch_path/: post: operationId: authorization_batch_path description: 批量操作批量拓扑层级授权/回收 tags: - - open + - open responses: default: description: '' @@ -955,19 +955,19 @@ paths: path: /api/v1/open/authorization/batch_path/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v1/open/authorization/batch_resource_creator_action/: post: operationId: authorization_batch_resource_creator_action description: 新建关联授权 tags: - - open + - open responses: default: description: '' @@ -981,19 +981,19 @@ paths: path: /api/v1/open/authorization/batch_resource_creator_action/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v1/open/authorization/instance/: post: operationId: authorization_instance description: 单个资源授权回收, deprecated tags: - - open + - open responses: default: description: '' @@ -1007,19 +1007,19 @@ paths: path: /api/v1/open/authorization/instance/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v1/open/authorization/path/: post: operationId: authorization_path description: 单个拓扑层级授权/回收 tags: - - open + - open responses: default: description: '' @@ -1033,19 +1033,19 @@ paths: path: /api/v1/open/authorization/path/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v1/open/authorization/resource_creator_action/: post: operationId: authorization_resource_creator_action description: 新建关联授权 tags: - - open + - open responses: default: description: '' @@ -1059,19 +1059,19 @@ paths: path: /api/v1/open/authorization/resource_creator_action/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v1/open/authorization/resource_creator_action_attribute/: post: operationId: authorization_resource_creator_action_attribute description: 新建关联授权-属性授权 tags: - - open + - open responses: default: description: '' @@ -1085,19 +1085,19 @@ paths: path: /api/v1/open/authorization/resource_creator_action_attribute/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v1/open/departments/{department_id}/groups: get: operationId: open_departments_groups description: 查询部门加入的组列表(注意部门-组关系存在有限期, 只会返回未过期的组列表) tags: - - open + - open responses: default: description: '' @@ -1114,20 +1114,20 @@ paths: upstreams: loadbalance: roundrobin hosts: - - host: http://{env.backend} - weight: 100 - transformHeaders: {} + - host: http://{env.backend} + weight: 100 + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v1/open/management/grade_managers/: get: operationId: management_grade_managers_list description: 查询分级管理员列表 tags: - - open + - open responses: default: description: '' @@ -1141,18 +1141,18 @@ paths: path: /api/v1/open/management/grade_managers/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: post: operationId: management_grade_managers description: 创建分级管理员 tags: - - open + - open responses: default: description: '' @@ -1166,19 +1166,19 @@ paths: path: /api/v1/open/management/grade_managers/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v1/open/management/grade_managers/{id}/: put: operationId: management_grade_managers_update description: 修改分级管理员 tags: - - open + - open responses: default: description: '' @@ -1192,19 +1192,19 @@ paths: path: /api/v1/open/management/grade_managers/{id}/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v1/open/management/grade_managers/{id}/groups/: get: operationId: management_grade_manager_groups description: 分级管理员的用户组列表 tags: - - open + - open responses: default: description: '' @@ -1218,18 +1218,18 @@ paths: path: /api/v1/open/management/grade_managers/{id}/groups/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: post: operationId: management_grade_manager_create_groups description: 分级管理员批量创建用户组 tags: - - open + - open responses: default: description: '' @@ -1243,19 +1243,19 @@ paths: path: /api/v1/open/management/grade_managers/{id}/groups/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v1/open/management/grade_managers/{id}/members/: delete: operationId: management_delete_grade_manager_members description: 批量删除分级管理员成员 tags: - - open + - open responses: default: description: '' @@ -1269,18 +1269,18 @@ paths: path: /api/v1/open/management/grade_managers/{id}/members/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: get: operationId: management_grade_manager_members description: 分级管理员成员列表 tags: - - open + - open responses: default: description: '' @@ -1294,18 +1294,18 @@ paths: path: /api/v1/open/management/grade_managers/{id}/members/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: post: operationId: management_add_grade_manager_members description: 批量添加分级管理员成员 tags: - - open + - open responses: default: description: '' @@ -1319,19 +1319,19 @@ paths: path: /api/v1/open/management/grade_managers/{id}/members/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v1/open/management/groups/applications/: post: operationId: management_groups_applications description: 创建用户组申请单 tags: - - open + - open responses: default: description: '' @@ -1345,19 +1345,19 @@ paths: path: /api/v1/open/management/groups/applications/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v1/open/management/groups/{id}/: delete: operationId: management_grade_manager_delete_group description: 分级管理员删除用户组 tags: - - open + - open responses: default: description: '' @@ -1371,18 +1371,18 @@ paths: path: /api/v1/open/management/groups/{id}/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: put: operationId: management_grade_manager_update_group description: 分级管理员更新用户组 tags: - - open + - open responses: default: description: '' @@ -1396,19 +1396,19 @@ paths: path: /api/v1/open/management/groups/{id}/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v1/open/management/groups/{id}/actions/policies/: delete: operationId: management_groups_policies_revoke_by_action description: 用户组按整个操作权限回收 tags: - - open + - open responses: default: description: '' @@ -1422,19 +1422,19 @@ paths: path: /api/v1/open/management/groups/{id}/actions/policies/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v1/open/management/groups/{id}/members/: delete: operationId: management_delete_group_members description: 用户组删除成员 tags: - - open + - open responses: default: description: '' @@ -1448,18 +1448,18 @@ paths: path: /api/v1/open/management/groups/{id}/members/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: get: operationId: management_group_members description: 用户组成员列表 tags: - - open + - open responses: default: description: '' @@ -1473,18 +1473,18 @@ paths: path: /api/v1/open/management/groups/{id}/members/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: post: operationId: management_add_group_members description: 用户组添加成员 tags: - - open + - open responses: default: description: '' @@ -1498,19 +1498,19 @@ paths: path: /api/v1/open/management/groups/{id}/members/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v1/open/management/groups/{id}/policies/: delete: operationId: management_groups_policies_delete description: 用户组权限回收 tags: - - open + - open responses: default: description: '' @@ -1524,18 +1524,18 @@ paths: path: /api/v1/open/management/groups/{id}/policies/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: post: operationId: management_groups_policies description: 用户组授权 tags: - - open + - open responses: default: description: '' @@ -1549,19 +1549,19 @@ paths: path: /api/v1/open/management/groups/{id}/policies/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v1/open/management/users/grade_managers/: get: operationId: management_users_grade_managers description: 用户加入的分级管理员列表 tags: - - open + - open responses: default: description: '' @@ -1575,19 +1575,19 @@ paths: path: /api/v1/open/management/users/grade_managers/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v1/open/management/users/grade_managers/{id}/groups/: get: operationId: management_users_grade_managers_groups description: 用户在某个分级管理员下加入的用户组列表 tags: - - open + - open responses: default: description: '' @@ -1601,19 +1601,19 @@ paths: path: /api/v1/open/management/users/grade_managers/{id}/groups/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v1/open/systems/{system_id}/policies: get: operationId: open_system_policies description: 拉取系统下某个操作的策略列表 tags: - - system + - system responses: default: description: '' @@ -1630,20 +1630,20 @@ paths: upstreams: loadbalance: roundrobin hosts: - - host: http://{env.backend} - weight: 100 - transformHeaders: {} + - host: http://{env.backend} + weight: 100 + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v1/open/systems/{system_id}/policies/-/subjects: get: operationId: open_system_policies_subjects description: 根据策略 ID 拉群策略对应的用户信息 tags: - - system + - system responses: default: description: '' @@ -1660,20 +1660,20 @@ paths: upstreams: loadbalance: roundrobin hosts: - - host: http://{env.backend} - weight: 100 - transformHeaders: {} + - host: http://{env.backend} + weight: 100 + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v1/open/systems/{system_id}/policies/{policy_id}: get: operationId: open_system_get_policy description: 获取某条策略详情 tags: - - system + - system responses: default: description: '' @@ -1690,20 +1690,20 @@ paths: upstreams: loadbalance: roundrobin hosts: - - host: http://{env.backend} - weight: 100 - transformHeaders: {} + - host: http://{env.backend} + weight: 100 + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v1/open/users/{user_id}/groups: get: operationId: open_user_groups description: 查询用户加入的组列表(注意用户-组关系存在有限期, 只会返回未过期的组列表) tags: - - open + - open responses: default: description: '' @@ -1720,20 +1720,20 @@ paths: upstreams: loadbalance: roundrobin hosts: - - host: http://{env.backend} - weight: 100 - transformHeaders: {} + - host: http://{env.backend} + weight: 100 + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v1/policy/auth: post: operationId: policy_auth description: 直接鉴权 tags: - - policy + - policy responses: default: description: '' @@ -1750,20 +1750,20 @@ paths: upstreams: loadbalance: roundrobin hosts: - - host: http://{env.backend} - weight: 100 - transformHeaders: {} + - host: http://{env.backend} + weight: 100 + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v1/policy/auth_by_actions: post: operationId: policy_auth_by_actions description: 批量action直接鉴权 tags: - - policy + - policy responses: default: description: '' @@ -1780,20 +1780,20 @@ paths: upstreams: loadbalance: roundrobin hosts: - - host: http://{env.backend} - weight: 100 - transformHeaders: {} + - host: http://{env.backend} + weight: 100 + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v1/policy/auth_by_resources: post: operationId: policy_auth_by_resources description: 批量资源直接鉴权 tags: - - policy + - policy responses: default: description: '' @@ -1810,20 +1810,20 @@ paths: upstreams: loadbalance: roundrobin hosts: - - host: http://{env.backend} - weight: 100 - transformHeaders: {} + - host: http://{env.backend} + weight: 100 + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v1/policy/query: post: operationId: policy_query description: 策略查询 tags: - - policy + - policy responses: default: description: '' @@ -1840,20 +1840,20 @@ paths: upstreams: loadbalance: roundrobin hosts: - - host: http://{env.backend} - weight: 100 - transformHeaders: {} + - host: http://{env.backend} + weight: 100 + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v1/policy/query_by_actions: post: operationId: policy_query_by_actions description: 批量拉取一批操作的权限策略 tags: - - policy + - policy responses: default: description: '' @@ -1870,20 +1870,20 @@ paths: upstreams: loadbalance: roundrobin hosts: - - host: http://{env.backend} - weight: 100 - transformHeaders: {} + - host: http://{env.backend} + weight: 100 + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v1/policy/query_by_ext_resources: post: operationId: policy_query_by_ext_resources description: 批量第三方依赖鉴权策略查询 tags: - - policy + - policy responses: default: description: '' @@ -1900,20 +1900,20 @@ paths: upstreams: loadbalance: roundrobin hosts: - - host: http://{env.backend} - weight: 100 - transformHeaders: {} + - host: http://{env.backend} + weight: 100 + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v1/systems/{system_id}/policies: get: operationId: system_policies description: 拉取系统下某个操作的策略列表(废弃, 请使用open_system_policies) tags: - - system + - system responses: default: description: '' @@ -1930,20 +1930,20 @@ paths: upstreams: loadbalance: roundrobin hosts: - - host: http://{env.backend} - weight: 100 - transformHeaders: {} + - host: http://{env.backend} + weight: 100 + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v1/systems/{system_id}/policies/-/subjects: get: operationId: system_policies_subjects description: 根据策略 ID 拉群策略对应的用户信息(废弃, 请使用open_system_policies_subjects) tags: - - system + - system responses: default: description: '' @@ -1960,20 +1960,20 @@ paths: upstreams: loadbalance: roundrobin hosts: - - host: http://{env.backend} - weight: 100 - transformHeaders: {} + - host: http://{env.backend} + weight: 100 + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v1/systems/{system_id}/policies/{policy_id}: get: operationId: system_get_policy description: 获取某条策略详情(废弃, 请使用open_system_get_policy) tags: - - system + - system responses: default: description: '' @@ -1990,20 +1990,20 @@ paths: upstreams: loadbalance: roundrobin hosts: - - host: http://{env.backend} - weight: 100 - transformHeaders: {} + - host: http://{env.backend} + weight: 100 + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v1/web/: x-bk-apigateway-method-any: operationId: api_v1_web_any description: SaaS调用后台 API 入口 tags: - - web + - web responses: default: description: '' @@ -2020,21 +2020,21 @@ paths: upstreams: loadbalance: roundrobin hosts: - - host: http://{env.backend} - weight: 100 - transformHeaders: {} + - host: http://{env.backend} + weight: 100 + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v2/open/management/systems/{system_id}/applications/{callback_id}/approve/: post: operationId: v2_management_application_approve description: 申请单审批回调 tags: - - open - - v2 + - open + - v2 responses: default: description: '' @@ -2048,20 +2048,20 @@ paths: path: /api/v2/open/management/systems/{system_id}/applications/{callback_id}/approve/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v2/open/management/systems/{system_id}/applications/{callback_id}/cancel/: put: operationId: v2_management_application_cancel description: 取消申请单 tags: - - open - - v2 + - open + - v2 responses: default: description: '' @@ -2075,20 +2075,20 @@ paths: path: /api/v2/open/management/systems/{system_id}/applications/{callback_id}/cancel/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v2/open/management/systems/{system_id}/departments/{department_id}/groups/belong/: get: operationId: v2_management_check_department_group_belong description: 批量校验部门是否归属用户组 tags: - - open - - v2 + - open + - v2 responses: default: description: '' @@ -2102,20 +2102,20 @@ paths: path: /api/v2/open/management/systems/{system_id}/departments/{department_id}/groups/belong/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v2/open/management/systems/{system_id}/grade_managers/: post: operationId: v2_management_grade_manager_create description: 创建分级管理员 tags: - - open - - v2 + - open + - v2 responses: default: description: '' @@ -2129,20 +2129,20 @@ paths: path: /api/v2/open/management/systems/{system_id}/grade_managers/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v2/open/management/systems/{system_id}/grade_managers/-/applications/: post: operationId: v2_management_grade_manager_applications description: 创建分级管理员申请 tags: - - open - - v2 + - open + - v2 responses: default: description: '' @@ -2156,20 +2156,20 @@ paths: path: /api/v2/open/management/systems/{system_id}/grade_managers/-/applications/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v2/open/management/systems/{system_id}/grade_managers/{id}/: delete: operationId: v2_management_delete_grade_manager description: 删除分级管理员 tags: - - open - - v2 + - open + - v2 responses: default: description: '' @@ -2183,19 +2183,19 @@ paths: path: /api/v2/open/management/systems/{system_id}/grade_managers/{id}/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: get: operationId: v2_management_grade_manager_detail description: 分级管理员详情 tags: - - open - - v2 + - open + - v2 responses: default: description: '' @@ -2209,19 +2209,19 @@ paths: path: /api/v2/open/management/systems/{system_id}/grade_managers/{id}/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: put: operationId: v2_management_update_grade_manager description: 更新分级管理员 tags: - - open - - v2 + - open + - v2 responses: default: description: '' @@ -2235,20 +2235,20 @@ paths: path: /api/v2/open/management/systems/{system_id}/grade_managers/{id}/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v2/open/management/systems/{system_id}/grade_managers/{id}/applications/: post: operationId: v2_management_update_grade_manager_application description: 创建更新分级管理员申请 tags: - - open - - v2 + - open + - v2 responses: default: description: '' @@ -2262,20 +2262,20 @@ paths: path: /api/v2/open/management/systems/{system_id}/grade_managers/{id}/applications/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v2/open/management/systems/{system_id}/grade_managers/{id}/groups/: get: operationId: v2_management_grade_manager_list_groups description: 分级管理员用户组列表 tags: - - open - - v2 + - open + - v2 responses: default: description: '' @@ -2289,19 +2289,19 @@ paths: path: /api/v2/open/management/systems/{system_id}/grade_managers/{id}/groups/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: post: operationId: v2_management_grade_manager_create_groups description: 分级管理员批量创建用户组 tags: - - open - - v2 + - open + - v2 responses: default: description: '' @@ -2315,20 +2315,20 @@ paths: path: /api/v2/open/management/systems/{system_id}/grade_managers/{id}/groups/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v2/open/management/systems/{system_id}/grade_managers/{id}/subject_templates/: get: operationId: v2_management_grade_manager_list_subject_templates description: 分级管理员人员模版列表 tags: - - open - - v2 + - open + - v2 responses: default: description: '' @@ -2342,20 +2342,20 @@ paths: path: /api/v2/open/management/systems/{system_id}/grade_managers/{id}/subject_templates/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v2/open/management/systems/{system_id}/grade_managers/{id}/subset_managers/: get: operationId: v2_management_grade_manager_list_subset_manager description: 分级管理员查询二级管理员列表 tags: - - open - - v2 + - open + - v2 responses: default: description: '' @@ -2369,19 +2369,19 @@ paths: path: /api/v2/open/management/systems/{system_id}/grade_managers/{id}/subset_managers/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: post: operationId: v2_management_grade_manager_create_subset_manager description: 分级管理员创建二级管理员 tags: - - open - - v2 + - open + - v2 responses: default: description: '' @@ -2395,20 +2395,20 @@ paths: path: /api/v2/open/management/systems/{system_id}/grade_managers/{id}/subset_managers/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v2/open/management/systems/{system_id}/groups/-/applications/: post: operationId: v2_management_groups_applications description: 创建用户组申请单 tags: - - open - - v2 + - open + - v2 responses: default: description: '' @@ -2422,20 +2422,20 @@ paths: path: /api/v2/open/management/systems/{system_id}/groups/-/applications/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v2/open/management/systems/{system_id}/groups/-/renew/applications/: post: operationId: v2_management_groups_renew_applications description: 用户组续期申请单 tags: - - open - - v2 + - open + - v2 responses: default: description: '' @@ -2449,20 +2449,20 @@ paths: path: /api/v2/open/management/systems/{system_id}/groups/-/renew/applications/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v2/open/management/systems/{system_id}/groups/{id}/: delete: operationId: v2_management_grade_manager_delete_group description: 分级管理员删除用户组 tags: - - open - - v2 + - open + - v2 responses: default: description: '' @@ -2476,19 +2476,19 @@ paths: path: /api/v2/open/management/systems/{system_id}/groups/{id}/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: put: operationId: v2_management_grade_manager_update_group description: 分级管理员更新用户组 tags: - - open - - v2 + - open + - v2 responses: default: description: '' @@ -2502,20 +2502,20 @@ paths: path: /api/v2/open/management/systems/{system_id}/groups/{id}/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v2/open/management/systems/{system_id}/groups/{id}/actions/-/policies/: delete: operationId: v2_management_groups_policies_revoke_by_action description: 用户组按整个操作权限回收 tags: - - open - - v2 + - open + - v2 responses: default: description: '' @@ -2529,20 +2529,20 @@ paths: path: /api/v2/open/management/systems/{system_id}/groups/{id}/actions/-/policies/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v2/open/management/systems/{system_id}/groups/{id}/members/: delete: operationId: v2_management_delete_group_members description: 用户组删除成员 tags: - - open - - v2 + - open + - v2 responses: default: description: '' @@ -2556,19 +2556,19 @@ paths: path: /api/v2/open/management/systems/{system_id}/groups/{id}/members/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: get: operationId: v2_management_group_members description: 用户组成员列表 tags: - - open - - v2 + - open + - v2 responses: default: description: '' @@ -2582,19 +2582,19 @@ paths: path: /api/v2/open/management/systems/{system_id}/groups/{id}/members/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: post: operationId: v2_management_add_group_members description: 用户组添加成员 tags: - - open - - v2 + - open + - v2 responses: default: description: '' @@ -2608,20 +2608,20 @@ paths: path: /api/v2/open/management/systems/{system_id}/groups/{id}/members/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v2/open/management/systems/{system_id}/groups/{id}/members/-/expired_at/: put: operationId: v2_management_update_group_members_expired_at description: 更新用户组成员有效期 tags: - - open - - v2 + - open + - v2 responses: default: description: '' @@ -2635,20 +2635,20 @@ paths: path: /api/v2/open/management/systems/{system_id}/groups/{id}/members/-/expired_at/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v2/open/management/systems/{system_id}/groups/{id}/policies/: delete: operationId: v2_management_groups_policies_revoke description: 用户组权限回收 tags: - - open - - v2 + - open + - v2 responses: default: description: '' @@ -2662,19 +2662,19 @@ paths: path: /api/v2/open/management/systems/{system_id}/groups/{id}/policies/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: get: operationId: v2_management_groups_policies_list description: 查询用户组自定义权限 tags: - - open - - v2 + - open + - v2 responses: default: description: '' @@ -2688,19 +2688,19 @@ paths: path: /api/v2/open/management/systems/{system_id}/groups/{id}/policies/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: post: operationId: v2_management_groups_policies_grant description: 用户组授权 tags: - - open - - v2 + - open + - v2 responses: default: description: '' @@ -2714,20 +2714,20 @@ paths: path: /api/v2/open/management/systems/{system_id}/groups/{id}/policies/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v2/open/management/systems/{system_id}/groups/{id}/policies/-/actions/: get: operationId: v2_management_groups_policies_action_list description: 查询用户组有权限的操作 tags: - - open - - v2 + - open + - v2 responses: default: description: '' @@ -2741,20 +2741,20 @@ paths: path: /api/v2/open/management/systems/{system_id}/groups/{id}/policies/-/actions/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v2/open/management/systems/{system_id}/subset_managers/{id}/: delete: operationId: v2_management_subset_manager_delete description: 删除二级管理员 tags: - - open - - v2 + - open + - v2 responses: default: description: '' @@ -2768,19 +2768,19 @@ paths: path: /api/v2/open/management/systems/{system_id}/subset_managers/{id}/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: get: operationId: v2_management_subset_manager_detail description: 二级管理员详情 tags: - - open - - v2 + - open + - v2 responses: default: description: '' @@ -2794,19 +2794,19 @@ paths: path: /api/v2/open/management/systems/{system_id}/subset_managers/{id}/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: post: operationId: v2_management_subset_manager_update description: 二级管理员更新 tags: - - open - - v2 + - open + - v2 responses: default: description: '' @@ -2820,20 +2820,20 @@ paths: path: /api/v2/open/management/systems/{system_id}/subset_managers/{id}/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v2/open/management/systems/{system_id}/subset_managers/{id}/groups/: get: operationId: v2_management_subset_manager_list_groups description: 二级管理员用户组列表 tags: - - open - - v2 + - open + - v2 responses: default: description: '' @@ -2847,19 +2847,19 @@ paths: path: /api/v2/open/management/systems/{system_id}/subset_managers/{id}/groups/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: post: operationId: v2_management_subset_manager_create_groups description: 二级管理员批量创建用户组 tags: - - open - - v2 + - open + - v2 responses: default: description: '' @@ -2873,20 +2873,20 @@ paths: path: /api/v2/open/management/systems/{system_id}/subset_managers/{id}/groups/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v2/open/management/systems/{system_id}/users/{user_id}/groups/belong/: get: operationId: v2_management_check_user_group_belong description: 批量校验用户是否归属用户组 tags: - - open - - v2 + - open + - v2 responses: default: description: '' @@ -2900,20 +2900,20 @@ paths: path: /api/v2/open/management/systems/{system_id}/users/{user_id}/groups/belong/ matchSubpath: false timeout: 0 - upstreams: {} - transformHeaders: {} + upstreams: { } + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v2/policy/systems/{system_id}/auth/: post: operationId: v2_policy_auth description: v2直接鉴权 tags: - - policy - - v2 + - policy + - v2 responses: default: description: '' @@ -2930,21 +2930,21 @@ paths: upstreams: loadbalance: roundrobin hosts: - - host: http://{env.backend} - weight: 100 - transformHeaders: {} + - host: http://{env.backend} + weight: 100 + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v2/policy/systems/{system_id}/auth_by_actions/: post: operationId: v2_policy_auth_by_actions description: 批量操作鉴权 tags: - - policy - - v2 + - policy + - v2 responses: default: description: '' @@ -2961,21 +2961,21 @@ paths: upstreams: loadbalance: roundrobin hosts: - - host: http://{env.backend} - weight: 100 - transformHeaders: {} + - host: http://{env.backend} + weight: 100 + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v2/policy/systems/{system_id}/query/: post: operationId: v2_policy_query description: 策略查询 tags: - - policy - - v2 + - policy + - v2 responses: default: description: '' @@ -2992,21 +2992,21 @@ paths: upstreams: loadbalance: roundrobin hosts: - - host: http://{env.backend} - weight: 100 - transformHeaders: {} + - host: http://{env.backend} + weight: 100 + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v2/policy/systems/{system_id}/query_by_actions/: post: operationId: v2_policy_query_by_actions description: 批量操作策略查询 tags: - - policy - - v2 + - policy + - v2 responses: default: description: '' @@ -3023,20 +3023,20 @@ paths: upstreams: loadbalance: roundrobin hosts: - - host: http://{env.backend} - weight: 100 - transformHeaders: {} + - host: http://{env.backend} + weight: 100 + transformHeaders: { } authConfig: userVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /healthz: get: operationId: healthz description: 接口检查服务是否健康 tags: - - basic + - basic responses: default: description: '' @@ -3053,21 +3053,21 @@ paths: upstreams: loadbalance: roundrobin hosts: - - host: http://{env.backend} - weight: 100 - transformHeaders: {} + - host: http://{env.backend} + weight: 100 + transformHeaders: { } authConfig: userVerifiedRequired: false appVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /metrics: get: operationId: metrics description: 接口暴露程序metrics tags: - - basic + - basic responses: default: description: '' @@ -3084,21 +3084,21 @@ paths: upstreams: loadbalance: roundrobin hosts: - - host: http://{env.backend} - weight: 100 - transformHeaders: {} + - host: http://{env.backend} + weight: 100 + transformHeaders: { } authConfig: userVerifiedRequired: false appVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /ping: get: operationId: ping description: 接口检查连通性 tags: - - basic + - basic responses: default: description: '' @@ -3115,21 +3115,21 @@ paths: upstreams: loadbalance: roundrobin hosts: - - host: http://{env.backend} - weight: 100 - transformHeaders: {} + - host: http://{env.backend} + weight: 100 + transformHeaders: { } authConfig: userVerifiedRequired: false appVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /version: get: operationId: version description: 接口检查程序版本 tags: - - basic + - basic responses: default: description: '' @@ -3146,167 +3146,251 @@ paths: upstreams: loadbalance: roundrobin hosts: - - host: http://{env.backend} - weight: 100 - transformHeaders: {} + - host: http://{env.backend} + weight: 100 + transformHeaders: { } authConfig: userVerifiedRequired: false appVerifiedRequired: false resourcePermissionRequired: false - disabledStages: [] + disabledStages: [ ] descriptionEn: /api/v1/open/admin/groups/: - post: - operationId: admin_create_groups - description: 超管批量创建用户组 - tags: - - open - responses: - default: - description: '' - x-bk-apigateway-resource: - isPublic: true - allowApplyPermission: true - matchSubpath: false - backend: - type: HTTP - method: post - path: /api/v1/open/admin/groups/ - matchSubpath: false - timeout: 0 - upstreams: { } - transformHeaders: { } - authConfig: - userVerifiedRequired: false - resourcePermissionRequired: false - disabledStages: [ ] - descriptionEn: + post: + operationId: admin_create_groups + description: 超管批量创建用户组 + tags: + - open + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: post + path: /api/v1/open/admin/groups/ + matchSubpath: false + timeout: 0 + upstreams: { } + transformHeaders: { } + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [ ] + descriptionEn: /api/v1/open/admin/groups/{id}/: - delete: - operationId: admin_delete_group - description: 超管删除指定用户组 - tags: - - open - responses: - default: - description: '' - x-bk-apigateway-resource: - isPublic: true - allowApplyPermission: true - matchSubpath: false - backend: - type: HTTP - method: delete - path: /api/v1/open/admin/groups/{id}/ - matchSubpath: false - timeout: 0 - upstreams: { } - transformHeaders: { } - authConfig: - userVerifiedRequired: false - resourcePermissionRequired: false - disabledStages: [ ] - descriptionEn: - put: - operationId: admin_update_group - description: 超管更新指定用户组 - tags: - - open - responses: - default: - description: '' - x-bk-apigateway-resource: - isPublic: true - allowApplyPermission: true - matchSubpath: false - backend: - type: HTTP - method: put - path: /api/v1/open/admin/groups/{id}/ - matchSubpath: false - timeout: 0 - upstreams: { } - transformHeaders: { } - authConfig: - userVerifiedRequired: false - resourcePermissionRequired: false - disabledStages: [ ] - descriptionEn: + delete: + operationId: admin_delete_group + description: 超管删除指定用户组 + tags: + - open + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: delete + path: /api/v1/open/admin/groups/{id}/ + matchSubpath: false + timeout: 0 + upstreams: { } + transformHeaders: { } + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [ ] + descriptionEn: + put: + operationId: admin_update_group + description: 超管更新指定用户组 + tags: + - open + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: put + path: /api/v1/open/admin/groups/{id}/ + matchSubpath: false + timeout: 0 + upstreams: { } + transformHeaders: { } + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [ ] + descriptionEn: /api/v1/open/admin/groups/{id}/policies/: - post: - operationId: admin_groups_policies_grant - description: 超管授权用户组 - tags: - - open - responses: - default: - description: '' - x-bk-apigateway-resource: - isPublic: true - allowApplyPermission: true - matchSubpath: false - backend: - type: HTTP - method: post - path: /api/v1/open/admin/groups/{id}/policies/ - matchSubpath: false - timeout: 0 - upstreams: { } - transformHeaders: { } - authConfig: - userVerifiedRequired: false - resourcePermissionRequired: false - disabledStages: [ ] - descriptionEn: + post: + operationId: admin_groups_policies_grant + description: 超管授权用户组 + tags: + - open + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: post + path: /api/v1/open/admin/groups/{id}/policies/ + matchSubpath: false + timeout: 0 + upstreams: { } + transformHeaders: { } + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [ ] + descriptionEn: /api/v1/open/admin/systems/{system_id}/provider_config/: - get: - operationId: admin_list_provider_config - description: 系统回调信息查询 - tags: - - open - responses: - default: - description: '' - x-bk-apigateway-resource: - isPublic: true - allowApplyPermission: true - matchSubpath: false - backend: - type: HTTP - method: get - path: /api/v1/open/admin/systems/{system_id}/provider_config/ - matchSubpath: false - timeout: 0 - upstreams: { } - transformHeaders: { } - authConfig: - userVerifiedRequired: false - resourcePermissionRequired: false - disabledStages: [ ] - descriptionEn: + get: + operationId: admin_list_provider_config + description: 系统回调信息查询 + tags: + - open + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: get + path: /api/v1/open/admin/systems/{system_id}/provider_config/ + matchSubpath: false + timeout: 0 + upstreams: { } + transformHeaders: { } + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [ ] + descriptionEn: /api/v1/open/admin/templates/: - post: - operationId: admin_create_templates - description: 超管创建模板 - tags: - - open - responses: - default: - description: '' - x-bk-apigateway-resource: - isPublic: true - allowApplyPermission: true - matchSubpath: false - backend: - type: HTTP - method: post - path: /api/v1/open/admin/templates/ - matchSubpath: false - timeout: 0 - upstreams: { } - transformHeaders: { } - authConfig: - userVerifiedRequired: false - resourcePermissionRequired: false - disabledStages: [ ] - descriptionEn: + post: + operationId: admin_create_templates + description: 超管创建模板 + tags: + - open + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: true + allowApplyPermission: true + matchSubpath: false + backend: + type: HTTP + method: post + path: /api/v1/open/admin/templates/ + matchSubpath: false + timeout: 0 + upstreams: { } + transformHeaders: { } + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [ ] + descriptionEn: + /api/v1/open/admin/systems/: + get: + operationId: open_admin_systems + description: 获取系统列表 + tags: + - open + - open/admin + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: false + allowApplyPermission: false + matchSubpath: false + backend: + type: HTTP + method: get + path: /api/v1/open/admin/systems/ + matchSubpath: false + timeout: 0 + upstreams: { } + transformHeaders: { } + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [ ] + descriptionEn: + /api/v1/open/admin/roles/system_managers/systems/{system_id}/members/: + get: + operationId: open_admin_roles_system_managers_members + description: 获取某个系统的系统管理员列表 + tags: + - open + - open/admin + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: false + allowApplyPermission: false + matchSubpath: false + backend: + type: HTTP + method: get + path: /api/v1/open/admin/roles/system_managers/systems/{system_id}/members/ + matchSubpath: false + timeout: 0 + upstreams: { } + transformHeaders: { } + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [ ] + descriptionEn: + /api/v1/model/share/systems/{system_id}/query: + get: + operationId: model_share_system_query + description: '模型共享: 查询 system 通用信息' + tags: + - securityAudit + responses: + default: + description: '' + x-bk-apigateway-resource: + isPublic: false + allowApplyPermission: false + matchSubpath: false + backend: + type: HTTP + method: get + path: /api/v1/model/share/systems/{system_id}/query + matchSubpath: false + timeout: 0 + upstreams: + loadbalance: roundrobin + hosts: + - host: http://{env.backend} + weight: 100 + transformHeaders: { } + authConfig: + userVerifiedRequired: false + resourcePermissionRequired: false + disabledStages: [ ] + descriptionEn: diff --git a/saas/resources/apigateway/docs/en/application_grant_policy.md.j2 b/saas/resources/apigateway/docs/en/application_grant_policy.md.j2 index 5e39c0dac..c125c90a7 100644 --- a/saas/resources/apigateway/docs/en/application_grant_policy.md.j2 +++ b/saas/resources/apigateway/docs/en/application_grant_policy.md.j2 @@ -65,7 +65,7 @@ the `create_job` operation of the `bk_job` system is not associated with any res ], "applicant": "user001", "reason": "for grant policies", - "expired_at: 1704042061 + "expired_at": 1704042061 } ``` @@ -87,11 +87,11 @@ the `view_job` operation of the `bk_job` system is associated with the `job` res [ # an array represents a topology path of an instance, and the topology path must be consistent with the resource link of the instance view, business (biz)-job (job) { "type": "biz", # the first layer of resources in the instance view - "id": "biz1", + "id": "biz1" }, { "type": "job", # the second layer of the resource topology path in the instance view - "id": "job1", + "id": "job1" } ] ] @@ -123,11 +123,11 @@ the `execute_job` operation of the `bk_job` system is associated with the `job` [ # 业务(biz)-作业(job) { "type": "biz", - "id": "biz1", + "id": "biz1" }, { "type": "job", - "id": "job1", + "id": "job1" } ] ] @@ -139,16 +139,16 @@ the `execute_job` operation of the `bk_job` system is associated with the `job` [ # 4层的拓扑路径, 必须与实例视图的资源链路一致: 业务(biz)-集群(set)-模块(module)-主机(host) { "type": "biz", - "id": "biz1", + "id": "biz1" }, { "type": "set", - "id": "set1", + "id": "set1" }, { "type": "module", - "id": "module1", + "id": "module1" }, { "type": "host", - "id": "host1", + "id": "host1" } ] ], diff --git a/saas/resources/apigateway/docs/en/management_groups_policies_delete.md.j2 b/saas/resources/apigateway/docs/en/management_groups_policies_delete.md.j2 index d5785226c..749fdddd0 100644 --- a/saas/resources/apigateway/docs/en/management_groups_policies_delete.md.j2 +++ b/saas/resources/apigateway/docs/en/management_groups_policies_delete.md.j2 @@ -5,9 +5,9 @@ | Field | Type | Required | Location | Description | | | group_id | int | path | yes | user_group_id | group_id | int | path | yes | user_group_id | -| system | string | body | Yes | Access to system unique identifier | -| actions | array[object] | yes | body | actions | -| resources | array[object] | yes | body | resource topology, the order of the resource types must be the same as the order in which the actions are registered | +| system | string | body | yes | Access to system unique identifier | +| actions | array[object] | body | yes | actions | +| resources | array[object] | body | yes | resource topology, the order of the resource types must be the same as the order in which the actions are registered | actions diff --git a/saas/resources/apigateway/docs/en/management_users_grade_managers.md.j2 b/saas/resources/apigateway/docs/en/management_users_grade_managers.md.j2 index 23d4bcd1f..b1bf6537c 100644 --- a/saas/resources/apigateway/docs/en/management_users_grade_managers.md.j2 +++ b/saas/resources/apigateway/docs/en/management_users_grade_managers.md.j2 @@ -5,8 +5,8 @@ | Field | Type | Required | Location | Description | | --------|--------|--------|--------|--------|--------|--------| -| system | string| yes | body | System ID, i.e. query the list of hierarchical administrators created by a system | -| uesr_id | string | yes | body | User ID, i.e. username | +| system | string| yes | query | System ID, i.e. query the list of hierarchical administrators created by a system | +| uesr_id | string | yes | query | User ID, i.e. username | #### Response diff --git a/saas/resources/apigateway/docs/zh/application_grant_policy.md.j2 b/saas/resources/apigateway/docs/zh/application_grant_policy.md.j2 index 02f2e8325..3c9d60725 100644 --- a/saas/resources/apigateway/docs/zh/application_grant_policy.md.j2 +++ b/saas/resources/apigateway/docs/zh/application_grant_policy.md.j2 @@ -65,7 +65,7 @@ related_resource_types.attributes.values ], "applicant": "user001", "reason": "for grant policies", - "expired_at: 1704042061 + "expired_at": 1704042061 } ``` @@ -87,11 +87,11 @@ related_resource_types.attributes.values [ # 一个数组表示一个实例的拓扑路径, 拓扑路径必须与实例视图的资源链路一致, 业务(biz)-作业(job) { "type": "biz", # 实例视图中资源的第一层业务 - "id": "biz1", + "id": "biz1" }, { "type": "job", # 实例视图中资源拓扑路径的第二层作业 - "id": "job1", + "id": "job1" } ] ] @@ -125,11 +125,11 @@ related_resource_types.attributes.values [ # 业务(biz)-作业(job) { "type": "biz", - "id": "biz1", + "id": "biz1" }, { "type": "job", - "id": "job1", + "id": "job1" } ] ] @@ -141,16 +141,16 @@ related_resource_types.attributes.values [ # 4层的拓扑路径, 必须与实例视图的资源链路一致: 业务(biz)-集群(set)-模块(module)-主机(host) { "type": "biz", - "id": "biz1", + "id": "biz1" }, { "type": "set", - "id": "set1", + "id": "set1" }, { "type": "module", - "id": "module1", + "id": "module1" }, { "type": "host", - "id": "host1", + "id": "host1" } ] ], diff --git a/saas/resources/apigateway/docs/zh/management_groups_policies_delete.md.j2 b/saas/resources/apigateway/docs/zh/management_groups_policies_delete.md.j2 index a1bb1618b..37d353dad 100644 --- a/saas/resources/apigateway/docs/zh/management_groups_policies_delete.md.j2 +++ b/saas/resources/apigateway/docs/zh/management_groups_policies_delete.md.j2 @@ -2,12 +2,12 @@ #### Parameters -| 字段 | 类型 | 位置 | 必须 | 描述 | -|---|---|---|---|---| -| group_id | int | path | 是 | 用户组ID | -| system | string | body | 是 | 接入系统唯一标识 | -| actions | array[object] | 是 | body | 操作 | -| resources | array[object] | 是 | body | 资源拓扑, 资源类型的顺序必须操作注册时的顺序一致 | +| 字段 | 类型 | 位置 | 必须 | 描述 | +|---|-----------------------|------|-|---| +| group_id | int | path | 是 | 用户组ID | +| system | string | body | 是 | 接入系统唯一标识 | +| actions | array[object] | body | 是 | 操作 | +| resources | array[object] | body | 是 | 资源拓扑, 资源类型的顺序必须操作注册时的顺序一致 | actions diff --git a/saas/resources/apigateway/docs/zh/management_users_grade_managers.md.j2 b/saas/resources/apigateway/docs/zh/management_users_grade_managers.md.j2 index 8c31c5fe0..210b0da1b 100644 --- a/saas/resources/apigateway/docs/zh/management_users_grade_managers.md.j2 +++ b/saas/resources/apigateway/docs/zh/management_users_grade_managers.md.j2 @@ -3,10 +3,10 @@ #### Parameters -| 字段 | 类型 |是否必须 | 位置 |描述 | -|--------|--------|--------|--------|--------| -| system | string| 是 | body | 系统ID,即查询由某个系统创建的分级管理员列表 | -| uesr_id | string | 是 | body | 用户ID,即用户名 | +| 字段 | 类型 |是否必须 | 位置 |描述 | +|--------|--------|--------|-------|--------| +| system | string| 是 | query | 系统ID,即查询由某个系统创建的分级管理员列表 | +| uesr_id | string | 是 | query | 用户ID,即用户名 | #### Response diff --git a/saas/resources/version_log/change_log.md b/saas/resources/version_log/change_log.md index 77e759aca..e692f630f 100644 --- a/saas/resources/version_log/change_log.md +++ b/saas/resources/version_log/change_log.md @@ -1,3 +1,26 @@ + +# V1.10.30 版本更新日志 + +### 新增功能 + +* 增加当用户拥有管理员身份时且当前页面属于个人工作台staff角色场景下时,支持管理员菜单页面快捷跳转 +* 全局配置版本升级,支持产品名称和title区别文案 + +### 缺陷修复 + +* 修复用户组—>分级管理员权限下依赖操作会偶现自动关联不在授权范围内的实例 +* 修复申请自定义权限部分系统的操作存在批量编辑后操作关联的资源实例显示异常 +* 修复二级管理员—>分级管理员权限下依赖操作会偶现自动关联不在授权范围内的实例 +* 修复删除人员模板最后一页唯一一条模板数据,提示数据不存在 +* 修复添加自定义权限-查看已经选择的数据时,已选择的操作个数会消失 +* 修复新建权限模板时推荐权限输入空格点击保存,前端未做判断 +* 修复用户组资源实例表格自定义权限聚合后在选择权限模板后重新聚合会偶现resouce_group为空情况 +* 修复自定义权限查看实例资源组件有多个资源类型tab项时无法删除实例 +* 修复新用户无任何权限申请跳转到权限中心资源实例应该置空而非无限制 +* 修改国际化language的cookie有限期默认为一年 + +--- + # V1.10.29 版本更新日志 diff --git a/saas/resources/version_log/change_log_en.md b/saas/resources/version_log/change_log_en.md index c8a395a64..c6e0d0549 100644 --- a/saas/resources/version_log/change_log_en.md +++ b/saas/resources/version_log/change_log_en.md @@ -1,3 +1,26 @@ + +# V1.10.30 Version Update Log + +### New Features + +* Added support for quick navigation to the admin menu page when the user has admin rights and the current page is under the personal workstation staff role scenario. +* Upgraded global configuration version to support distinct wording for product name and title. + +### Bug Fixes + +* Fixed an issue where the user group -> hierarchical admin permissions occasionally auto-associated instances outside the authorized scope. +* Fixed an issue with custom permission requests where batch editing operations displayed abnormal resource instances. +* Fixed an issue where secondary admin -> hierarchical admin permissions occasionally auto-associated instances outside the authorized scope. +* Fixed an issue where deleting the last template data on the last page of the personnel template prompted that the data did not exist. +* Fixed an issue where the number of selected operations disappeared when viewing already selected data in custom permissions. +* Fixed an issue where the frontend did not validate spaces input in recommended permissions when creating a new permission template and clicking save. +* Fixed an issue where custom permissions in the user group resource instance table, after aggregation, occasionally resulted in `resource_group` being empty when re-aggregating after selecting a permission template. +* Fixed an issue where instances could not be deleted when the custom permission view instance resource component had multiple resource type tabs. +* Fixed an issue where new users with no permissions were redirected to the permission center with resource instances set to unrestricted instead of empty. +* Modified the expiration period of the internationalization language cookie to default to one year. + +--- + ## V1.10.29 Version Update Log