mirror of
https://github.com/jumpserver/lina.git
synced 2026-01-15 14:24:39 +00:00
feat: 改密计划支持数据库改密 (#991)
* feat: 改密计划支持数据库改密 * perf: 修改应用账号 * merge: dev * perf: 暂存修改数据库 * fix: bug * fix: bug * perf: 优化系统用户详情,增加应用列表 * perf: 修改clone * fix: 修复更新系统用户bug Co-authored-by: ibuler <ibuler@qq.com> Co-authored-by: feng626 <1304903146@qq.com>
This commit is contained in:
committed by
GitHub
parent
411fca98b0
commit
52e2d58567
@@ -17,7 +17,7 @@
|
||||
<div>
|
||||
<el-form label-position="right" label-width="80px" :model="authInfo">
|
||||
<el-form-item :label="this.$t('applications.appName')">
|
||||
<el-input v-model="account['app_name']" readonly />
|
||||
<el-input v-model="account['app_display']" readonly />
|
||||
</el-form-item>
|
||||
<el-form-item :label="this.$t('assets.Username')">
|
||||
<el-input v-model="account['username']" readonly />
|
||||
@@ -62,8 +62,7 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
getAuthInfo() {
|
||||
console.log(this.account)
|
||||
const url = `/api/v1/applications/account-secrets/${this.account.uid}/`
|
||||
const url = `/api/v1/applications/account-secrets/${this.account.id}/`
|
||||
this.$axios.get(url, { disableFlashErrorMsg: true }).then(resp => {
|
||||
this.authInfo = resp
|
||||
this.showAuthInfo = true
|
||||
|
||||
@@ -48,11 +48,11 @@ export default {
|
||||
tableConfig: {
|
||||
url: this.url,
|
||||
columns: [
|
||||
'app_name', 'username', 'category_display',
|
||||
'app_display', 'username', 'category_display',
|
||||
'type_display', 'systemuser', 'actions'
|
||||
],
|
||||
columnsMeta: {
|
||||
app_name: {
|
||||
app_display: {
|
||||
showOverflowTooltip: true,
|
||||
formatter: DetailFormatter,
|
||||
formatterArgs: {
|
||||
|
||||
@@ -23,5 +23,6 @@ export { default as Switcher } from './FormFields/Swicher'
|
||||
export { default as SummaryCard } from './SummaryCard'
|
||||
export { default as UploadField } from './FormFields/UploadField'
|
||||
export { default as AccountListTable } from './AccountListTable/index'
|
||||
export { default as AppAccountListTable } from './AppAccountListTable'
|
||||
export { default as AssetRelationCard } from './AssetRelationCard'
|
||||
export { default as MFAVerifyDialog } from './MFAVerifyDialog'
|
||||
|
||||
@@ -30,9 +30,11 @@
|
||||
"applications": {
|
||||
"": "",
|
||||
"updateAccountMsg": "请更新系统用户的账号信息",
|
||||
"associateApplication": "关联应用",
|
||||
"RemoteApp": "远程应用",
|
||||
"Database": "数据库",
|
||||
"Cloud": "云",
|
||||
"App": "应用",
|
||||
"applicationsType": {
|
||||
"chrome": "Chrome",
|
||||
"mysql_workbench": "MySQL Workbench",
|
||||
@@ -84,6 +86,7 @@
|
||||
"DBInfo": "数据库信息"
|
||||
},
|
||||
"assets": {
|
||||
"AppList": "应用列表",
|
||||
"AssociateSystemUsers": "关联系统用户",
|
||||
"AssociateAssets": "关联资产",
|
||||
"AssociateNodes": "关联节点",
|
||||
@@ -1127,17 +1130,31 @@
|
||||
"xpack": {
|
||||
"Admin": "管理员",
|
||||
"Asset": "资产",
|
||||
"Database": "数据库",
|
||||
"AssetCount": "资产数量",
|
||||
"Auditor": "审计员",
|
||||
"ChangeAuthPlan": {
|
||||
"AddAsset": "添加资产",
|
||||
"AddNode": "添加节点",
|
||||
"AddSystemUser": "添加系统用户",
|
||||
"Asset": "资产",
|
||||
"Database": "数据库",
|
||||
"DatabaseId": "数据库Id",
|
||||
"AppAmount": "应用数量",
|
||||
"SystemUserAmount": "系统用户数量",
|
||||
"SystemUser": "系统用户",
|
||||
"SystemUserId": "系统用户Id",
|
||||
"AssetAmount": "资产数量",
|
||||
"AssetAndNode": "资产和节点",
|
||||
"ChangeAuthPlan": "改密计划",
|
||||
"ChangeAuthPlanCreate": "创建改密计划",
|
||||
"ChangeAuthPlanUpdate": "更新改密计划",
|
||||
"AssetChangeAuthPlan": "资产改密计划",
|
||||
"AppChangeAuthPlan": "应用改密计划",
|
||||
"AssetChangeAuthPlanCreate": "创建资产改密计划",
|
||||
"AppChangeAuthPlanCreate": "创建应用改密计划",
|
||||
"AssetChangeAuthPlanUpdate": "更新资产改密计划",
|
||||
"AppChangeAuthPlanUpdate": "更新应用改密计划",
|
||||
"SymbolSet": "特殊符号集合",
|
||||
"SymbolSetHelpText": "请输入此类型数据库支持的特殊符号集合,若生成的随机密码中有此类数据库不支持的特殊字符,改密计划将会失败",
|
||||
"CyclePerform": "周期执行",
|
||||
"DateJoined": "创建日期",
|
||||
"DateStart": "开始日期",
|
||||
|
||||
@@ -29,9 +29,11 @@
|
||||
"applications": {
|
||||
"": "",
|
||||
"updateAccountMsg": "Please update system user account info",
|
||||
"associateApplication": "Associate application",
|
||||
"RemoteApp": "Remote app",
|
||||
"Database": "Database",
|
||||
"Cloud": "Cloud",
|
||||
"App": "Application",
|
||||
"applicationsType": {
|
||||
"chrome": "Chrome",
|
||||
"mysql_workbench": "MySQL Workbench",
|
||||
@@ -83,6 +85,7 @@
|
||||
"DBInfo": "Database Info"
|
||||
},
|
||||
"assets": {
|
||||
"AppList": "Application list",
|
||||
"AssociateSystemUsers": "Associate system users",
|
||||
"AssociateAssets": "Associate assets",
|
||||
"AssociateNodes": "Associate nodes",
|
||||
@@ -1097,17 +1100,29 @@
|
||||
"xpack": {
|
||||
"Admin": "Admin",
|
||||
"Asset": "Asset",
|
||||
"Database": "Database",
|
||||
"AssetCount": "Asset count",
|
||||
"Auditor": "Auditor",
|
||||
"ChangeAuthPlan": {
|
||||
"AddAsset": "Add asset",
|
||||
"AddNode": "Add node",
|
||||
"AddSystemUser": "Add systemuser",
|
||||
"Asset": "Asset",
|
||||
"Database": "Database",
|
||||
"DatabaseId": "Database Id",
|
||||
"SystemUser": "SystemUser",
|
||||
"SystemUserId": "SystemUser Id",
|
||||
"AssetAmount": "Asset",
|
||||
"AssetAndNode": "Asset and Node",
|
||||
"ChangeAuthPlan": "Change Auth Plan",
|
||||
"ChangeAuthPlanCreate": "Create change auth plan",
|
||||
"ChangeAuthPlanUpdate": "Update change auth plan",
|
||||
"AssetChangeAuthPlan": "Asset Change Auth Plan",
|
||||
"AppChangeAuthPlan": "App Change Auth Plan",
|
||||
"AssetChangeAuthPlanCreate": "Create Asset change auth plan",
|
||||
"AppChangeAuthPlanCreate": "Create App change auth plan",
|
||||
"AssetChangeAuthPlanUpdate": "Update Asset change auth plan",
|
||||
"AppChangeAuthPlanUpdate": "Update App change auth plan",
|
||||
"SymbolSet": "Special symbol set",
|
||||
"SymbolSetHelpText": "Please enter the special symbol set supported by this type of database. If there are special characters in the generated random password that are not supported by this type of database, the password change plan will fail",
|
||||
"CyclePerform": "Cycle perform",
|
||||
"DateJoined": "Date joined",
|
||||
"DateStart": "Date start",
|
||||
|
||||
@@ -8,9 +8,21 @@
|
||||
</template>
|
||||
|
||||
<div>
|
||||
<el-tabs v-if="submenu.length > 0" slot="submenu" v-model="iActiveMenu" class="page-submenu" @tab-click="handleTabClick">
|
||||
<el-tabs
|
||||
v-if="submenu.length > 0"
|
||||
slot="submenu"
|
||||
v-model="iActiveMenu"
|
||||
class="page-submenu"
|
||||
@tab-click="handleTabClick"
|
||||
>
|
||||
<template v-for="item in submenu">
|
||||
<el-tab-pane :key="item.name" :label-content="item.labelContent" :name="item.name" :disabled="item.disabled">
|
||||
<el-tab-pane
|
||||
v-if="checkShow(item)"
|
||||
:key="item.name"
|
||||
:label-content="item.labelContent"
|
||||
:name="item.name"
|
||||
:disabled="item.disabled"
|
||||
>
|
||||
<span slot="label">
|
||||
<i v-if="item.icon" class="fa " :class="item.icon" />
|
||||
{{ item.title }}
|
||||
@@ -68,6 +80,13 @@ export default {
|
||||
this.iActiveMenu = this.getPropActiveTab()
|
||||
},
|
||||
methods: {
|
||||
checkShow(item) {
|
||||
let hidden = item.hidden
|
||||
if (typeof hidden === 'function') {
|
||||
hidden = hidden()
|
||||
}
|
||||
return !hidden
|
||||
},
|
||||
handleTabClick(tab) {
|
||||
this.$emit('tab-click', tab)
|
||||
this.$emit('update:activeMenu', tab.name)
|
||||
@@ -104,15 +123,16 @@ export default {
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.page-submenu >>> .el-tabs__header {
|
||||
background-color: white;
|
||||
margin-left: -25px;
|
||||
padding-left: 25px;
|
||||
margin-right: -25px;
|
||||
padding-right: 25px;
|
||||
margin-top: -30px;
|
||||
}
|
||||
.page-submenu >>> .el-tabs__nav-wrap {
|
||||
position: static;
|
||||
}
|
||||
.page-submenu >>> .el-tabs__header {
|
||||
background-color: white;
|
||||
margin-left: -25px;
|
||||
padding-left: 25px;
|
||||
margin-right: -25px;
|
||||
padding-right: 25px;
|
||||
margin-top: -30px;
|
||||
}
|
||||
|
||||
.page-submenu >>> .el-tabs__nav-wrap {
|
||||
position: static;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -79,40 +79,83 @@ export default [
|
||||
{
|
||||
path: 'change-auth-plan',
|
||||
component: empty,
|
||||
meta: { title: i18n.t('xpack.ChangeAuthPlan.ChangeAuthPlan'), activeMenu: '/accounts/change-auth-plan/plan' },
|
||||
redirect: '',
|
||||
meta: { title: i18n.t('xpack.ChangeAuthPlan.ChangeAuthPlan') },
|
||||
children: [
|
||||
{
|
||||
path: '',
|
||||
component: () => import('@/views/accounts/ChangeAuthPlan/index.vue'),
|
||||
name: 'ChangeAuthPlanIndex',
|
||||
meta: { title: i18n.t('xpack.ChangeAuthPlan.ChangeAuthPlan'), activeMenu: '/accounts/change-auth-plan' }
|
||||
},
|
||||
{
|
||||
path: 'plan',
|
||||
component: () => import('@/views/accounts/ChangeAuthPlan/ChangeAuthPlanList.vue'),
|
||||
name: 'ChangeAuthPlanList',
|
||||
meta: { title: i18n.t('xpack.ChangeAuthPlan.ChangeAuthPlan'), activeMenu: '/accounts/change-auth-plan/plan' }
|
||||
component: () => import('@/views/accounts/ChangeAuthPlan/AssetChangeAuthPlan/ChangeAuthPlanList.vue'),
|
||||
name: 'AssetChangeAuthPlanList',
|
||||
meta: { title: i18n.t('xpack.ChangeAuthPlan.AssetChangeAuthPlan'), activeMenu: '/accounts/change-auth-plan' },
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: 'plan/create',
|
||||
component: () => import('@/views/accounts/ChangeAuthPlan/ChangeAuthPlanCreateUpdate.vue'),
|
||||
name: 'ChangeAuthPlanCreate',
|
||||
meta: { title: i18n.t('xpack.ChangeAuthPlan.ChangeAuthPlanCreate'), activeMenu: '/accounts/change-auth-plan/plan', action: 'create' },
|
||||
component: () => import('@/views/accounts/ChangeAuthPlan/AssetChangeAuthPlan/ChangeAuthPlanCreateUpdate.vue'),
|
||||
name: 'AssetChangeAuthPlanCreate',
|
||||
meta: { title: i18n.t('xpack.ChangeAuthPlan.AssetChangeAuthPlanCreate'), activeMenu: '/accounts/change-auth-plan', action: 'create' },
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: 'plan/:id/update',
|
||||
component: () => import('@/views/accounts/ChangeAuthPlan/ChangeAuthPlanCreateUpdate.vue'),
|
||||
name: 'ChangeAuthPlanUpdate',
|
||||
meta: { title: i18n.t('xpack.ChangeAuthPlan.ChangeAuthPlanUpdate'), activeMenu: '/accounts/change-auth-plan/plan', action: 'update' },
|
||||
component: () => import('@/views/accounts/ChangeAuthPlan/AssetChangeAuthPlan/ChangeAuthPlanCreateUpdate.vue'),
|
||||
name: 'AssetChangeAuthPlanUpdate',
|
||||
meta: { title: i18n.t('xpack.ChangeAuthPlan.AssetChangeAuthPlanUpdate'), activeMenu: '/accounts/change-auth-plan', action: 'update' },
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: 'plan/:id',
|
||||
component: () => import('@/views/accounts/ChangeAuthPlan/ChangeAuthPlanDetail/index.vue'),
|
||||
name: 'ChangeAuthPlanDetail',
|
||||
meta: { title: i18n.t('xpack.ChangeAuthPlan.ChangeAuthPlan'), activeMenu: '/accounts/change-auth-plan/plan' },
|
||||
component: () => import('@/views/accounts/ChangeAuthPlan/AssetChangeAuthPlan/ChangeAuthPlanDetail/index.vue'),
|
||||
name: 'AssetChangeAuthPlanDetail',
|
||||
meta: { title: i18n.t('xpack.ChangeAuthPlan.AssetChangeAuthPlan'), activeMenu: '/accounts/change-auth-plan' },
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: 'plan-execution/:id',
|
||||
component: () => import('@/views/accounts/ChangeAuthPlan/ChangeAuthPlanDetail/ChangeAuthPlanExecution/ChangeAuthPlanExecutionDetail/index.vue'),
|
||||
component: () => import('@/views/accounts/ChangeAuthPlan/AssetChangeAuthPlan/ChangeAuthPlanDetail/ChangeAuthPlanExecution/ChangeAuthPlanExecutionDetail/index.vue'),
|
||||
name: 'ChangeAuthPlanExecutionDetail',
|
||||
meta: { title: i18n.t('xpack.ChangeAuthPlan.ExecutionDetail'), activeMenu: '/accounts/change-auth-plan/plan' },
|
||||
meta: { title: i18n.t('xpack.ChangeAuthPlan.ExecutionDetail'), activeMenu: '/accounts/change-auth-plan' },
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: 'app-plan',
|
||||
component: () => import('@/views/accounts/ChangeAuthPlan/AppChangeAuthPlan/AppChangeAuthPlanList.vue'),
|
||||
name: 'AppChangeAuthPlanList',
|
||||
meta: { title: i18n.t('xpack.ChangeAuthPlan.AppChangeAuthPlan'), activeMenu: '/accounts/change-auth-plan' },
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: 'app-plan/create',
|
||||
component: () => import('@/views/accounts/ChangeAuthPlan/AppChangeAuthPlan/AppChangeAuthPlanCreateUpdate.vue'),
|
||||
name: 'AppChangeAuthPlanCreate',
|
||||
meta: { title: i18n.t('xpack.ChangeAuthPlan.AssetChangeAuthPlanCreate'), activeMenu: '/accounts/change-auth-plan', action: 'create' },
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: 'app-plan/:id',
|
||||
component: () => import('@/views/accounts/ChangeAuthPlan/AppChangeAuthPlan/ChangeAuthPlanDetail/index.vue'),
|
||||
name: 'AppChangeAuthPlanDetail',
|
||||
meta: { title: i18n.t('xpack.ChangeAuthPlan.AppChangeAuthPlan'), activeMenu: '/accounts/change-auth-plan' },
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: 'app-plan/:id/update',
|
||||
component: () => import('@/views/accounts/ChangeAuthPlan/AppChangeAuthPlan/AppChangeAuthPlanCreateUpdate.vue'),
|
||||
name: 'AppChangeAuthPlanUpdate',
|
||||
meta: { title: i18n.t('xpack.ChangeAuthPlan.AppChangeAuthPlanUpdate'), activeMenu: '/accounts/change-auth-plan', action: 'update' },
|
||||
hidden: true
|
||||
},
|
||||
{
|
||||
path: 'app-plan-execution/:id',
|
||||
component: () => import('@/views/accounts/ChangeAuthPlan/AppChangeAuthPlan/ChangeAuthPlanDetail/AppChangeAuthPlanExecution/ChangeAuthPlanExecutionDetail/index.vue'),
|
||||
name: 'AppChangeAuthPlanExecutionDetail',
|
||||
meta: { title: i18n.t('xpack.ChangeAuthPlan.ExecutionDetail'), activeMenu: '/accounts/change-auth-plan' },
|
||||
hidden: true
|
||||
}
|
||||
]
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
<template>
|
||||
<GenericCreateUpdatePage v-bind="$data" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { GenericCreateUpdatePage } from '@/layout/components'
|
||||
import getFields from '@/views/accounts/ChangeAuthPlan/fields'
|
||||
|
||||
export default {
|
||||
name: 'AppChangeAuthPlanCreateUpdate',
|
||||
components: {
|
||||
GenericCreateUpdatePage
|
||||
},
|
||||
data() {
|
||||
const fields = getFields.bind(this)()
|
||||
return {
|
||||
url: '/api/v1/xpack/change-auth-plan/app-plan/',
|
||||
fields: [
|
||||
[this.$t('common.Basic'), ['name']],
|
||||
[this.$t('assets.Applications'), ['category', 'type', 'apps', 'system_users']],
|
||||
[this.$t('xpack.ChangeAuthPlan.PasswordStrategy'), ['password_strategy', 'password', 'password_rules']],
|
||||
[this.$t('xpack.Timer'), ['is_periodic', 'crontab', 'interval']],
|
||||
[this.$t('common.Other'), ['comment']]
|
||||
],
|
||||
initial: {
|
||||
type: this.$route.query.type,
|
||||
category: this.$route.query.category,
|
||||
password_strategy: 'custom',
|
||||
is_periodic: true,
|
||||
password_rules: {
|
||||
length: 30
|
||||
},
|
||||
interval: 24
|
||||
},
|
||||
fieldsMeta: {
|
||||
type: {
|
||||
type: 'select',
|
||||
disabled: true
|
||||
},
|
||||
category: {
|
||||
hidden: () => true
|
||||
},
|
||||
apps: {
|
||||
label: this.$t('assets.Applications'),
|
||||
el: {
|
||||
value: [],
|
||||
ajax: {
|
||||
url: `/api/v1/applications/applications/?category=${this.$route.query.category}&type=${this.$route.query.type}`,
|
||||
transformOption: (item) => {
|
||||
return { label: item.name + ' (' + item.type_display + ')', value: item.id }
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
system_users: {
|
||||
el: {
|
||||
value: [],
|
||||
ajax: {
|
||||
url: (function() {
|
||||
let url = '/api/v1/assets/system-users/'
|
||||
const queryType = this.$route.query.type
|
||||
if (this.$route.query.category === 'remote_app') {
|
||||
url += `?protocol=rdp`
|
||||
} else if (queryType) {
|
||||
url += `?protocol=${queryType}`
|
||||
}
|
||||
return url
|
||||
}.bind(this)()),
|
||||
transformOption: (item) => {
|
||||
if (this.$route.query.type === 'k8s') {
|
||||
return { label: item.name, value: item.id }
|
||||
}
|
||||
const username = item.username || '*'
|
||||
return { label: item.name + '(' + username + ')', value: item.id }
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
password: fields.password,
|
||||
password_rules: fields.database_password_rules,
|
||||
is_periodic: fields.is_periodic,
|
||||
password_strategy: fields.password_strategy,
|
||||
crontab: fields.crontab,
|
||||
interval: fields.interval
|
||||
},
|
||||
createSuccessNextRoute: { name: 'ChangeAuthPlanIndex' },
|
||||
updateSuccessNextRoute: { name: 'ChangeAuthPlanIndex' },
|
||||
cleanFormValue(data) {
|
||||
if (data['password_strategy'] === 'custom') {
|
||||
delete data['password_rules']
|
||||
} else {
|
||||
delete data['password']
|
||||
}
|
||||
if (data['interval'] === '') {
|
||||
delete data['interval']
|
||||
}
|
||||
return data
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,129 @@
|
||||
<template>
|
||||
<GenericListTable :table-config="tableConfig" :header-actions="headerActions" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { GenericListTable } from '@/layout/components'
|
||||
import { DetailFormatter } from '@/components/TableFormatters'
|
||||
import { openTaskPage } from '@/utils/jms'
|
||||
import { DATABASE } from '@/views/perms/const'
|
||||
|
||||
export default {
|
||||
name: 'AppChangeAuthPlanList',
|
||||
components: {
|
||||
GenericListTable
|
||||
},
|
||||
data() {
|
||||
const vm = this
|
||||
return {
|
||||
tableConfig: {
|
||||
url: '/api/v1/xpack/change-auth-plan/app-plan/',
|
||||
columns: [
|
||||
'name', 'password_strategy_display',
|
||||
'periodic_display', 'run_times', 'comment', 'org_name', 'actions'
|
||||
],
|
||||
columnsShow: {
|
||||
min: ['name', 'actions'],
|
||||
default: ['name', 'password_strategy_display', 'periodic_display', 'run_times', 'actions']
|
||||
},
|
||||
columnsMeta: {
|
||||
name: {
|
||||
formatter: DetailFormatter,
|
||||
formatterArgs: {
|
||||
route: 'AppChangeAuthPlanDetail'
|
||||
}
|
||||
},
|
||||
systemuser_display: {
|
||||
label: vm.$t('xpack.ChangeAuthPlan.SystemUser'),
|
||||
width: '300px',
|
||||
showOverflowTooltip: true
|
||||
},
|
||||
password_strategy_display: {
|
||||
label: vm.$t('xpack.ChangeAuthPlan.PasswordStrategy'),
|
||||
width: '220px',
|
||||
showOverflowTooltip: true
|
||||
},
|
||||
periodic_display: {
|
||||
label: vm.$t('xpack.ChangeAuthPlan.Timer'),
|
||||
showOverflowTooltip: true,
|
||||
width: '150px'
|
||||
},
|
||||
run_times: {
|
||||
label: vm.$t('xpack.ChangeAuthPlan.ExecutionTimes'),
|
||||
width: '87px',
|
||||
formatter: DetailFormatter,
|
||||
formatterArgs: {
|
||||
route: 'AppChangeAuthPlanDetail',
|
||||
routeQuery: {
|
||||
activeTab: 'AppChangeAuthPlanExecutionList'
|
||||
}
|
||||
}
|
||||
},
|
||||
comment: {
|
||||
width: '90px'
|
||||
},
|
||||
actions: {
|
||||
width: '164px',
|
||||
formatterArgs: {
|
||||
onClone: ({ row }) => {
|
||||
vm.$router.push({
|
||||
name: 'AppChangeAuthPlanCreate',
|
||||
query: {
|
||||
clone_from: row.id,
|
||||
category: row.category.toLowerCase(),
|
||||
type: row.type.toLowerCase()
|
||||
}
|
||||
})
|
||||
},
|
||||
onUpdate: ({ row }) => {
|
||||
vm.$router.push({
|
||||
name: 'AppChangeAuthPlanUpdate',
|
||||
params: { id: row.id },
|
||||
query: {
|
||||
category: row.category.toLowerCase(),
|
||||
type: row.type.toLowerCase()
|
||||
}
|
||||
})
|
||||
},
|
||||
extraActions: [
|
||||
{
|
||||
title: vm.$t('xpack.Execute'),
|
||||
name: 'execute',
|
||||
type: 'info',
|
||||
callback: function({ row }) {
|
||||
this.$axios.post(
|
||||
`/api/v1/xpack/change-auth-plan/app-plan-execution/`,
|
||||
{ plan: row.id }
|
||||
).then(res => {
|
||||
openTaskPage(res['task'])
|
||||
})
|
||||
}.bind(this)
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
headerActions: {
|
||||
hasRefresh: true,
|
||||
hasExport: false,
|
||||
hasImport: false,
|
||||
hasMoreActions: false,
|
||||
moreCreates: {
|
||||
callback: (option) => {
|
||||
vm.$router.push({ name: 'AppChangeAuthPlanCreate', query: {
|
||||
category: option.category.toLowerCase(),
|
||||
type: option.name.toLowerCase()
|
||||
}})
|
||||
},
|
||||
dropdown: DATABASE
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,68 @@
|
||||
<template>
|
||||
<el-row :gutter="20">
|
||||
<el-col :md="14" :sm="24">
|
||||
<DetailCard :items="detailItems" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import DetailCard from '@/components/DetailCard'
|
||||
import { toSafeLocalDateStr } from '@/utils/common'
|
||||
|
||||
export default {
|
||||
name: 'AppChangeAuthPlanExecutionInfo',
|
||||
components: {
|
||||
DetailCard
|
||||
},
|
||||
props: {
|
||||
object: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
detailItems() {
|
||||
return [
|
||||
{
|
||||
key: this.$t('xpack.ChangeAuthPlan.Database'),
|
||||
value: this.object.apps_display.join(', ')
|
||||
},
|
||||
{
|
||||
key: this.$t('xpack.ChangeAuthPlan.SystemUser'),
|
||||
value: this.object.system_users_display.join(', ')
|
||||
},
|
||||
{
|
||||
key: this.$t('xpack.ChangeAuthPlan.AppAmount'),
|
||||
value: this.object.apps_amount
|
||||
},
|
||||
{
|
||||
key: this.$t('xpack.ChangeAuthPlan.SystemUserAmount'),
|
||||
value: this.object.system_users_amount
|
||||
},
|
||||
{
|
||||
key: this.$t('xpack.ChangeAuthPlan.PasswordStrategy'),
|
||||
value: this.object.password_strategy_display
|
||||
},
|
||||
{
|
||||
key: this.$t('xpack.ChangeAuthPlan.TimeDelta'),
|
||||
value: this.object.timedelta.toFixed(2) + 's'
|
||||
},
|
||||
{
|
||||
key: this.$t('xpack.ChangeAuthPlan.DateStart'),
|
||||
value: toSafeLocalDateStr(this.object.date_start)
|
||||
}
|
||||
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,92 @@
|
||||
<template>
|
||||
<GenericListTable :table-config="tableConfig" :header-actions="headerActions" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import GenericListTable from '@/layout/components/GenericListTable'
|
||||
|
||||
export default {
|
||||
name: 'AppChangeAuthPlanExecutionTaskList',
|
||||
components: {
|
||||
GenericListTable
|
||||
},
|
||||
props: {
|
||||
object: {
|
||||
type: Object,
|
||||
required: true,
|
||||
default: () => ({})
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tableConfig: {
|
||||
url: `/api/v1/xpack/change-auth-plan/app-plan-execution-subtask/?plan_execution_id=${this.object.id}`,
|
||||
columns: [
|
||||
'app_display', 'system_user_display', 'is_success', 'reason', 'timedelta', 'date_start', 'actions'
|
||||
],
|
||||
columnsMeta: {
|
||||
app_display: {
|
||||
label: this.$t('xpack.ChangeAuthPlan.Database'),
|
||||
formatter: function(row, column, cellValue, index) {
|
||||
const to = {
|
||||
name: 'DatabaseAppDetail',
|
||||
params: { id: row.app }
|
||||
}
|
||||
return <router-link to={ to } >{ row.app_display }</router-link>
|
||||
}
|
||||
},
|
||||
system_user_display: {
|
||||
label: this.$t('xpack.ChangeAuthPlan.SystemUser')
|
||||
},
|
||||
is_success: {
|
||||
label: this.$t('xpack.ChangeAuthPlan.Success')
|
||||
},
|
||||
timedelta: {
|
||||
label: this.$t('xpack.ChangeAuthPlan.TimeDelta'),
|
||||
width: '90px',
|
||||
formatter: function(row) {
|
||||
return row.timedelta.toFixed(2) + 's'
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
formatterArgs: {
|
||||
hasDelete: false,
|
||||
hasUpdate: false,
|
||||
hasClone: false,
|
||||
extraActions: [
|
||||
{
|
||||
name: 'retry',
|
||||
type: 'info',
|
||||
title: this.$t('xpack.ChangeAuthPlan.Retry'),
|
||||
callback: function({ row, tableData }) {
|
||||
this.$axios.put(
|
||||
`/api/v1/xpack/change-auth-plan/app-plan-execution-subtask/${row.id}/`,
|
||||
).then(res => {
|
||||
window.open(`/#/ops/celery/task/${res.task}/log/`, '_blank', 'toolbar=yes, width=900, height=600')
|
||||
})
|
||||
}.bind(this)
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
headerActions: {
|
||||
hasSearch: true,
|
||||
hasRefresh: true,
|
||||
hasLeftActions: true,
|
||||
hasRightActions: true,
|
||||
hasExport: false,
|
||||
hasImport: false,
|
||||
hasCreate: false,
|
||||
hasBulkDelete: false,
|
||||
hasBulkUpdate: false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,55 @@
|
||||
<template>
|
||||
<GenericDetailPage :object.sync="execution" :active-menu.sync="config.activeMenu" v-bind="config" v-on="$listeners">
|
||||
<keep-alive>
|
||||
<component :is="config.activeMenu" :object="execution" />
|
||||
</keep-alive>
|
||||
</GenericDetailPage>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { GenericDetailPage } from '@/layout/components'
|
||||
import AppChangeAuthPlanExecutionInfo from './ChangeAuthPlanExecutionInfo'
|
||||
import AppChangeAuthPlanExecutionTaskList from './ChangeAuthPlanExecutionTaskList'
|
||||
|
||||
export default {
|
||||
name: 'AppChangeAuthPlanExecutionDetail',
|
||||
components: {
|
||||
GenericDetailPage,
|
||||
AppChangeAuthPlanExecutionInfo,
|
||||
AppChangeAuthPlanExecutionTaskList
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
execution: { id: '' },
|
||||
config: {
|
||||
activeMenu: 'AppChangeAuthPlanExecutionInfo',
|
||||
actions: {
|
||||
hasUpdate: false,
|
||||
hasDelete: false
|
||||
},
|
||||
submenu: [
|
||||
{
|
||||
title: this.$t('common.BasicInfo'),
|
||||
name: 'AppChangeAuthPlanExecutionInfo'
|
||||
},
|
||||
{
|
||||
title: this.$t('xpack.ChangeAuthPlan.TaskList'),
|
||||
name: 'AppChangeAuthPlanExecutionTaskList'
|
||||
}
|
||||
],
|
||||
getTitle: this.getExecutionTitle
|
||||
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getExecutionTitle() {
|
||||
return `${this.$route.meta.title}: ${this.execution.id}`
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,122 @@
|
||||
<template>
|
||||
<GenericListTable :table-config="tableConfig" :header-actions="headerActions" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import GenericListTable from '@/layout/components/GenericListTable'
|
||||
|
||||
export default {
|
||||
name: 'AppChangeAuthPlanExecutionList',
|
||||
components: {
|
||||
GenericListTable
|
||||
},
|
||||
props: {
|
||||
object: {
|
||||
type: Object,
|
||||
required: true,
|
||||
default: () => ({})
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tableConfig: {
|
||||
url: `/api/v1/xpack/change-auth-plan/app-plan-execution/?plan_id=${this.object.id}`,
|
||||
columns: [
|
||||
'username', 'result_summary', 'password_strategy_display', 'timedelta', 'trigger_display',
|
||||
'apps_amount', 'system_users_amount', 'date_start', 'actions'
|
||||
],
|
||||
columnsShow: {
|
||||
min: ['actions'],
|
||||
default: [
|
||||
'username', 'password_strategy_display',
|
||||
'timedelta', 'trigger_display', 'date_start', 'actions', 'result_summary'
|
||||
]
|
||||
},
|
||||
columnsMeta: {
|
||||
username: {
|
||||
label: this.$t('xpack.ChangeAuthPlan.Username')
|
||||
},
|
||||
apps_amount: {
|
||||
label: this.$t('xpack.ChangeAuthPlan.AppAmount')
|
||||
},
|
||||
system_users_amount: {
|
||||
label: this.$t('xpack.ChangeAuthPlan.SystemUserAmount')
|
||||
},
|
||||
systemusers: {
|
||||
label: this.$t('xpack.ChangeAuthPlan.SystemUser')
|
||||
},
|
||||
result_summary: {
|
||||
label: this.$t('xpack.ChangeAuthPlan.Result'),
|
||||
width: '80px',
|
||||
showOverflowTooltip: true,
|
||||
formatter: function(row) {
|
||||
const summary = <div>
|
||||
<span class='text-primary'>{row.result_summary.succeed}</span>/
|
||||
<span class='text-danger'>{row.result_summary.failed}</span>/
|
||||
<span>{row.result_summary.total}</span>
|
||||
</div>
|
||||
return summary
|
||||
}
|
||||
},
|
||||
password_strategy_display: {
|
||||
label: this.$t('xpack.ChangeAuthPlan.PasswordStrategy'),
|
||||
width: '220px',
|
||||
showOverflowTooltip: true
|
||||
},
|
||||
timedelta: {
|
||||
label: this.$t('xpack.ChangeAuthPlan.TimeDelta'),
|
||||
width: '90px',
|
||||
formatter: function(row) {
|
||||
return row.timedelta.toFixed(2) + 's'
|
||||
}
|
||||
},
|
||||
date_start: {
|
||||
showOverflowTooltip: true
|
||||
},
|
||||
actions: {
|
||||
formatterArgs: {
|
||||
hasDelete: false,
|
||||
hasUpdate: false,
|
||||
hasClone: false,
|
||||
extraActions: [
|
||||
{
|
||||
name: 'log',
|
||||
type: 'primary',
|
||||
title: this.$t('xpack.ChangeAuthPlan.Log'),
|
||||
callback: function({ row }) {
|
||||
window.open(`/#/ops/celery/task/${row.id}/log/`, '_blank', 'toolbar=yes, width=900, height=600')
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'detail',
|
||||
title: this.$t('xpack.ChangeAuthPlan.Detail'),
|
||||
type: 'info',
|
||||
callback: function({ row }) {
|
||||
return this.$router.push({ name: 'AppChangeAuthPlanExecutionDetail', params: { id: row.id }})
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
headerActions: {
|
||||
hasSearch: true,
|
||||
hasRefresh: true,
|
||||
hasRightActions: true,
|
||||
hasLeftActions: true,
|
||||
hasMoreActions: false,
|
||||
hasExport: false,
|
||||
hasImport: false,
|
||||
hasCreate: false,
|
||||
hasBulkDelete: false,
|
||||
hasBulkUpdate: false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,96 @@
|
||||
<template>
|
||||
<el-row :gutter="20">
|
||||
<el-col :md="14" :sm="24">
|
||||
<DetailCard :items="detailItems" />
|
||||
</el-col>
|
||||
<el-col :md="10" :sm="24">
|
||||
<QuickActions :actions="quickActions" type="primary" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { DetailCard, QuickActions } from '@/components'
|
||||
import { toSafeLocalDateStr } from '@/utils/common'
|
||||
|
||||
export default {
|
||||
name: 'AppChangeAuthPlanInfo',
|
||||
components: {
|
||||
DetailCard,
|
||||
QuickActions
|
||||
},
|
||||
props: {
|
||||
object: {
|
||||
type: Object,
|
||||
required: true,
|
||||
default: () => ({})
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
quickActions: [
|
||||
{
|
||||
title: this.$t('xpack.ChangeAuthPlan.ManualExecutePlan'),
|
||||
attrs: {
|
||||
type: 'primary',
|
||||
label: this.$t('xpack.ChangeAuthPlan.Execute')
|
||||
},
|
||||
callbacks: {
|
||||
click: function() {
|
||||
this.$axios.post(
|
||||
`/api/v1/xpack/change-auth-plan/app-plan-execution/`,
|
||||
{ plan: this.object.id }
|
||||
).then(res => {
|
||||
window.open(`/#/ops/celery/task/${res.task}/log/`, '_blank', 'toolbar=yes, width=900, height=600')
|
||||
})
|
||||
}.bind(this)
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
detailItems() {
|
||||
return [
|
||||
{
|
||||
key: this.$t('xpack.ChangeAuthPlan.Name'),
|
||||
value: this.object.name
|
||||
},
|
||||
{
|
||||
key: this.$t('xpack.ChangeAuthPlan.SystemUser'),
|
||||
value: this.object.systemuser_display
|
||||
},
|
||||
{
|
||||
key: this.$t('xpack.ChangeAuthPlan.PasswordStrategy'),
|
||||
value: this.object.password_strategy_display
|
||||
},
|
||||
{
|
||||
key: this.$t('xpack.ChangeAuthPlan.RegularlyPerform'),
|
||||
value: this.object.crontab
|
||||
},
|
||||
{
|
||||
key: this.$t('xpack.ChangeAuthPlan.CyclePerform'),
|
||||
value: this.object.interval
|
||||
|
||||
},
|
||||
{
|
||||
key: this.$t('xpack.ChangeAuthPlan.DateJoined'),
|
||||
value: toSafeLocalDateStr(this.object.date_created)
|
||||
},
|
||||
{
|
||||
key: this.$t('xpack.ChangeAuthPlan.DateUpdated'),
|
||||
value: toSafeLocalDateStr(this.object.date_updated)
|
||||
},
|
||||
{
|
||||
key: this.$t('common.Comment'),
|
||||
value: this.object.comment
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,105 @@
|
||||
<template>
|
||||
<el-row :gutter="20">
|
||||
<el-col :md="14" :sm="24">
|
||||
<GenericListTable ref="listTable" :table-config="tableConfig" :header-actions="headerActions" />
|
||||
</el-col>
|
||||
<el-col :md="10" :sm="24">
|
||||
<RelationCard type="info" style="margin-top: 15px" v-bind="systemuserRelationConfig" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import GenericListTable from '@/layout/components/GenericListTable'
|
||||
import RelationCard from '@/components/RelationCard/index'
|
||||
import { DeleteActionFormatter } from '@/components/TableFormatters'
|
||||
|
||||
export default {
|
||||
name: 'ChangeAuthPlanDatabase',
|
||||
components: {
|
||||
GenericListTable, RelationCard
|
||||
},
|
||||
props: {
|
||||
object: {
|
||||
type: Object,
|
||||
required: true,
|
||||
default: () => ({})
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tableConfig: {
|
||||
url: `/api/v1/xpack/change-auth-plan/app-plan/${this.object.id}/systemusers/`,
|
||||
columns: [
|
||||
'name', 'username', 'delete_action'
|
||||
],
|
||||
columnsMeta: {
|
||||
delete_action: {
|
||||
prop: 'id',
|
||||
label: this.$t('common.Actions'),
|
||||
align: 'center',
|
||||
width: 150,
|
||||
objects: this.object.system_users,
|
||||
formatter: DeleteActionFormatter,
|
||||
onDelete: function(col, row, cellValue, reload) {
|
||||
this.$axios.patch(
|
||||
`/api/v1/xpack/change-auth-plan/app-plan/${this.object.id}/systemusers/?action=remove`,
|
||||
{ system_users: [row.id] }
|
||||
).then(res => {
|
||||
this.$message.success(this.$t('common.deleteSuccessMsg'))
|
||||
reload()
|
||||
}).catch(error => {
|
||||
this.$message.error(this.$t('common.deleteErrorMsg') + ' ' + error)
|
||||
})
|
||||
}.bind(this)
|
||||
}
|
||||
},
|
||||
tableAttrs: {
|
||||
border: false
|
||||
}
|
||||
},
|
||||
headerActions: {
|
||||
hasSearch: true,
|
||||
hasRefresh: true,
|
||||
hasLeftActions: true,
|
||||
hasRightActions: true,
|
||||
hasExport: false,
|
||||
hasImport: false,
|
||||
hasCreate: false,
|
||||
hasMoreActions: false
|
||||
},
|
||||
systemuserRelationConfig: {
|
||||
icon: 'fa-edit',
|
||||
title: this.$t('xpack.ChangeAuthPlan.AddSystemUser'),
|
||||
objectsAjax: {
|
||||
url: `/api/v1/assets/system-users/?protocol=${this.object.type}`,
|
||||
transformOption: (item) => {
|
||||
return { label: item.name + '(' + item.username + ')', value: item.id }
|
||||
}
|
||||
},
|
||||
// hasObjectsId: this.object.systemuser,
|
||||
showHasObjects: false,
|
||||
performAdd: (items, that) => {
|
||||
const relationUrl = `/api/v1/xpack/change-auth-plan/app-plan/${this.object.id}/systemusers/?action=add`
|
||||
const systemusers = items.map(v => v.value)
|
||||
const iHasObjects = that.iHasObjects.map(v => v.value)
|
||||
const data = {
|
||||
system_users: Array.from(new Set([...iHasObjects, ...systemusers]))
|
||||
}
|
||||
return this.$axios.patch(relationUrl, data)
|
||||
},
|
||||
onAddSuccess: (objects, that) => {
|
||||
that.iHasObjects = [...that.iHasObjects, ...objects]
|
||||
that.$refs.select2.clearSelected()
|
||||
this.$message.success(this.$t('common.updateSuccessMsg'))
|
||||
this.$refs.listTable.$refs.ListTable.reloadTable()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,50 @@
|
||||
<template>
|
||||
<GenericDetailPage :object.sync="plan" :active-menu.sync="config.activeMenu" v-bind="config">
|
||||
<keep-alive>
|
||||
<component :is="config.activeMenu" :object="plan" />
|
||||
</keep-alive>
|
||||
</GenericDetailPage>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { GenericDetailPage } from '@/layout/components'
|
||||
import ChangeAuthPlanDatabase from './ChangeAuthPlanApp/index'
|
||||
import AppChangeAuthPlanInfo from './AppChangeAuthPlanInfo'
|
||||
import AppChangeAuthPlanExecutionList from './AppChangeAuthPlanExecution/ChangeAuthPlanExecutionList'
|
||||
|
||||
export default {
|
||||
name: 'AppChangeAuthPlanDetail',
|
||||
components: {
|
||||
GenericDetailPage,
|
||||
ChangeAuthPlanDatabase,
|
||||
AppChangeAuthPlanInfo,
|
||||
AppChangeAuthPlanExecutionList
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
plan: { name: '', comment: '' },
|
||||
config: {
|
||||
activeMenu: 'AppChangeAuthPlanInfo',
|
||||
submenu: [
|
||||
{
|
||||
title: this.$t('common.BasicInfo'),
|
||||
name: 'AppChangeAuthPlanInfo'
|
||||
},
|
||||
{
|
||||
title: this.$t('xpack.ChangeAuthPlan.SystemUser'),
|
||||
name: 'ChangeAuthPlanDatabase'
|
||||
},
|
||||
{
|
||||
title: this.$t('xpack.ChangeAuthPlan.ExecutionList'),
|
||||
name: 'AppChangeAuthPlanExecutionList'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,72 @@
|
||||
<template>
|
||||
<GenericCreateUpdatePage v-bind="$data" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { GenericCreateUpdatePage } from '@/layout/components'
|
||||
import getFields from '@/views/accounts/ChangeAuthPlan/fields'
|
||||
|
||||
export default {
|
||||
name: 'AssetChangeAuthPlanCreateUpdate',
|
||||
components: {
|
||||
GenericCreateUpdatePage
|
||||
},
|
||||
data() {
|
||||
const fields = getFields.bind(this)()
|
||||
return {
|
||||
url: '/api/v1/xpack/change-auth-plan/plan/',
|
||||
fields: [
|
||||
[this.$t('common.Basic'), ['name']],
|
||||
[this.$t('xpack.Asset'), ['username', 'assets', 'nodes']],
|
||||
[this.$t('xpack.ChangeAuthPlan.PasswordStrategy'), ['is_password', 'password_strategy', 'password', 'password_rules']],
|
||||
[this.$t('xpack.ChangeAuthPlan.SecretKeyStrategy'), ['is_ssh_key', 'ssh_key_strategy', 'private_key']],
|
||||
[this.$t('xpack.Timer'), ['is_periodic', 'crontab', 'interval']],
|
||||
[this.$t('common.Other'), ['comment']]
|
||||
],
|
||||
initial: {
|
||||
password_strategy: 'custom',
|
||||
ssh_key_strategy: 'add',
|
||||
is_periodic: true,
|
||||
is_password: true,
|
||||
is_ssh_key: false,
|
||||
password_rules: {
|
||||
length: 30
|
||||
},
|
||||
interval: 24
|
||||
},
|
||||
fieldsMeta: {
|
||||
username: fields.username,
|
||||
assets: fields.assets,
|
||||
password: fields.password,
|
||||
password_rules: fields.asset_password_rules,
|
||||
private_key: fields.private_key,
|
||||
nodes: fields.nodes,
|
||||
is_periodic: fields.is_periodic,
|
||||
is_password: fields.is_password,
|
||||
is_ssh_key: fields.is_ssh_key,
|
||||
password_strategy: fields.password_strategy,
|
||||
ssh_key_strategy: fields.ssh_key_strategy,
|
||||
crontab: fields.crontab,
|
||||
interval: fields.interval
|
||||
},
|
||||
createSuccessNextRoute: { name: 'ChangeAuthPlanIndex' },
|
||||
updateSuccessNextRoute: { name: 'ChangeAuthPlanIndex' },
|
||||
cleanFormValue(data) {
|
||||
if (data['password_strategy'] === 'custom') {
|
||||
delete data['password_rules']
|
||||
} else {
|
||||
delete data['password']
|
||||
}
|
||||
if (data['interval'] === '') {
|
||||
delete data['interval']
|
||||
}
|
||||
return data
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -103,7 +103,7 @@ export default {
|
||||
disabled: this.$store.getters.currentOrgIsRoot,
|
||||
hasObjectsId: this.object.nodes,
|
||||
performAdd: (items, that) => {
|
||||
const relationUrl = `/api/v1/xpack/change-auth-plan/plan/${this.object.id}/`
|
||||
const relationUrl = `/api/v1/xpack/change-auth-plan/plan/${this.object.id}/nodes/?action=add`
|
||||
const nodes = items.map(v => v.value)
|
||||
const iHasObjects = that.iHasObjects.map(v => v.value)
|
||||
const data = {
|
||||
@@ -118,13 +118,10 @@ export default {
|
||||
this.$refs.listTable.$refs.ListTable.reloadTable()
|
||||
},
|
||||
performDelete: (item) => {
|
||||
const nodes = this.object.nodes
|
||||
const deleteNode = item.value
|
||||
nodes.splice(nodes.indexOf(deleteNode), 1)
|
||||
const data = {
|
||||
nodes: nodes
|
||||
nodes: [item.value]
|
||||
}
|
||||
const relationUrl = `/api/v1/xpack/change-auth-plan/plan/${this.object.id}/`
|
||||
const relationUrl = `/api/v1/xpack/change-auth-plan/plan/${this.object.id}/nodes/?action=remove`
|
||||
return this.$axios.patch(relationUrl, data)
|
||||
},
|
||||
onDeleteSuccess: (obj, that) => {
|
||||
@@ -1,16 +1,16 @@
|
||||
<template>
|
||||
<GenericListPage :table-config="tableConfig" :header-actions="headerActions" />
|
||||
<GenericListTable :table-config="tableConfig" :header-actions="headerActions" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { GenericListPage } from '@/layout/components'
|
||||
import { GenericListTable } from '@/layout/components'
|
||||
import { DetailFormatter } from '@/components/TableFormatters'
|
||||
import { openTaskPage } from '@/utils/jms'
|
||||
|
||||
export default {
|
||||
name: 'ChangeAuthPlanList',
|
||||
name: 'AssetChangeAuthPlanList',
|
||||
components: {
|
||||
GenericListPage
|
||||
GenericListTable
|
||||
},
|
||||
data() {
|
||||
const vm = this
|
||||
@@ -26,6 +26,12 @@ export default {
|
||||
default: ['name', 'username', 'password_strategy_display', 'periodic_display', 'run_times', 'actions']
|
||||
},
|
||||
columnsMeta: {
|
||||
name: {
|
||||
formatter: DetailFormatter,
|
||||
formatterArgs: {
|
||||
route: 'AssetChangeAuthPlanDetail'
|
||||
}
|
||||
},
|
||||
username: {
|
||||
showOverflowTooltip: true
|
||||
},
|
||||
@@ -52,9 +58,9 @@ export default {
|
||||
width: '87px',
|
||||
formatter: DetailFormatter,
|
||||
formatterArgs: {
|
||||
route: 'ChangeAuthPlanDetail',
|
||||
route: 'AssetChangeAuthPlanDetail',
|
||||
routeQuery: {
|
||||
activeTab: 'ChangeAuthPlanExecutionList'
|
||||
activeTab: 'AssetChangeAuthPlanExecutionList'
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -64,6 +70,12 @@ export default {
|
||||
actions: {
|
||||
width: '164px',
|
||||
formatterArgs: {
|
||||
onClone: ({ row }) => {
|
||||
vm.$router.push({ name: 'AssetChangeAuthPlanCreate', query: { clone_from: row.id }})
|
||||
},
|
||||
onUpdate: ({ row }) => {
|
||||
vm.$router.push({ name: 'AssetChangeAuthPlanUpdate', params: { id: row.id }})
|
||||
},
|
||||
extraActions: [
|
||||
{
|
||||
title: vm.$t('xpack.Execute'),
|
||||
@@ -87,7 +99,12 @@ export default {
|
||||
hasRefresh: true,
|
||||
hasExport: false,
|
||||
hasImport: false,
|
||||
hasMoreActions: false
|
||||
hasMoreActions: false,
|
||||
createRoute: () => {
|
||||
return {
|
||||
name: 'AssetChangeAuthPlanCreate'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,164 +0,0 @@
|
||||
<template>
|
||||
<GenericCreateUpdatePage v-bind="$data" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { GenericCreateUpdatePage } from '@/layout/components'
|
||||
import { AssetSelect } from '@/components'
|
||||
import { Required } from '@/components/DataForm/rules'
|
||||
|
||||
export default {
|
||||
name: 'ChangeAuthPlanCreateUpdate',
|
||||
components: {
|
||||
GenericCreateUpdatePage
|
||||
},
|
||||
data() {
|
||||
var validatorInterval = (rule, value, callback) => {
|
||||
if (parseInt(value) < 1) {
|
||||
return callback(new Error(this.$t('xpack.ChangeAuthPlan.validatorMessage.EnsureThisValueIsGreaterThanOrEqualTo1')))
|
||||
}
|
||||
callback()
|
||||
}
|
||||
return {
|
||||
url: '/api/v1/xpack/change-auth-plan/plan/',
|
||||
fields: [
|
||||
[this.$t('common.Basic'), ['name']],
|
||||
[this.$t('xpack.Asset'), ['username', 'assets', 'nodes']],
|
||||
[this.$t('xpack.ChangeAuthPlan.PasswordStrategy'), ['is_password', 'password_strategy', 'password', 'password_rules']],
|
||||
[this.$t('xpack.ChangeAuthPlan.SecretKeyStrategy'), ['is_ssh_key', 'ssh_key_strategy', 'private_key']],
|
||||
[this.$t('xpack.Timer'), ['is_periodic', 'crontab', 'interval']],
|
||||
[this.$t('common.Other'), ['comment']]
|
||||
],
|
||||
initial: {
|
||||
password_strategy: 'custom',
|
||||
ssh_key_strategy: 'add',
|
||||
is_periodic: true,
|
||||
is_password: true,
|
||||
is_ssh_key: false,
|
||||
password_rules: {
|
||||
length: 30
|
||||
},
|
||||
interval: 24
|
||||
},
|
||||
fieldsMeta: {
|
||||
username: {
|
||||
helpText: this.$t('xpack.ChangeAuthPlan.HelpText.UsernameOfCreateUpdatePage')
|
||||
},
|
||||
assets: {
|
||||
type: 'assetSelect',
|
||||
component: AssetSelect,
|
||||
rules: [
|
||||
{ required: false }
|
||||
],
|
||||
label: this.$t('xpack.Asset')
|
||||
},
|
||||
password: {
|
||||
hidden: (formValue) => {
|
||||
return formValue.password_strategy !== 'custom' || formValue.is_password === false
|
||||
},
|
||||
rules: [
|
||||
{ required: this.$route.meta.action === 'create', message: this.$t('common.fieldRequiredError'), trigger: 'blur' }
|
||||
]
|
||||
},
|
||||
password_rules: {
|
||||
type: 'group',
|
||||
items: this.generatePasswordRulesItemsFields()
|
||||
},
|
||||
private_key: {
|
||||
el: {
|
||||
type: 'textarea',
|
||||
placeholder: '-----BEGIN OPENSSH PRIVATE KEY-----',
|
||||
autosize: { minRows: 3 }
|
||||
},
|
||||
hidden: (formValue) => {
|
||||
return formValue.is_ssh_key === false
|
||||
},
|
||||
rules: [
|
||||
{ required: this.$route.meta.action === 'create', message: this.$t('common.fieldRequiredError'), trigger: 'blur' }
|
||||
]
|
||||
},
|
||||
nodes: {
|
||||
label: this.$t('xpack.Node'),
|
||||
el: {
|
||||
value: [],
|
||||
ajax: {
|
||||
url: '/api/v1/assets/nodes/',
|
||||
transformOption: (item) => {
|
||||
return { label: item.full_value, value: item.id }
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
is_periodic: {
|
||||
type: 'switch'
|
||||
},
|
||||
is_password: {
|
||||
type: 'switch'
|
||||
},
|
||||
is_ssh_key: {
|
||||
type: 'switch'
|
||||
},
|
||||
password_strategy: {
|
||||
label: this.$t('xpack.ChangeAuthPlan.PasswordStrategy'),
|
||||
hidden: (formValue) => {
|
||||
return formValue.is_password === false
|
||||
}
|
||||
},
|
||||
ssh_key_strategy: {
|
||||
label: this.$t('xpack.ChangeAuthPlan.SecretKeyStrategy'),
|
||||
hidden: (formValue) => {
|
||||
return formValue.is_ssh_key === false
|
||||
}
|
||||
},
|
||||
crontab: {
|
||||
label: this.$t('xpack.RegularlyPerform'),
|
||||
hidden: (formValue) => {
|
||||
return formValue.is_periodic === false
|
||||
},
|
||||
helpText: this.$t('xpack.HelpText.CrontabOfCreateUpdatePage')
|
||||
},
|
||||
interval: {
|
||||
label: this.$t('xpack.CyclePerform'),
|
||||
hidden: (formValue) => {
|
||||
return formValue.is_periodic === false
|
||||
},
|
||||
helpText: this.$t('xpack.HelpText.IntervalOfCreateUpdatePage'),
|
||||
rules: [
|
||||
{ validator: validatorInterval }
|
||||
]
|
||||
}
|
||||
},
|
||||
cleanFormValue(data) {
|
||||
if (data['password_strategy'] === 'custom') {
|
||||
delete data['password_rules']
|
||||
} else {
|
||||
delete data['password']
|
||||
}
|
||||
if (data['interval'] === '') {
|
||||
delete data['interval']
|
||||
}
|
||||
return data
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
generatePasswordRulesItemsFields() {
|
||||
const itemsFields = []
|
||||
const items = [
|
||||
{ id: 'length', prop: 'length', label: this.$t('xpack.ChangeAuthPlan.PasswordLength') }
|
||||
]
|
||||
items.forEach((item, index, array) => {
|
||||
itemsFields.push({
|
||||
id: item.id, prop: item.prop, el: {}, attrs: {}, type: 'input', label: item.label, rules: [Required],
|
||||
hidden: (formValue) => { return ['random_one', 'random_all'].indexOf(formValue.password_strategy) === -1 || formValue.is_password === false }
|
||||
})
|
||||
})
|
||||
return itemsFields
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
225
src/views/accounts/ChangeAuthPlan/fields.js
Normal file
225
src/views/accounts/ChangeAuthPlan/fields.js
Normal file
@@ -0,0 +1,225 @@
|
||||
import i18n from '@/i18n/i18n'
|
||||
import { AssetSelect } from '@/components'
|
||||
import Select2 from '@/components/FormFields/Select2'
|
||||
import { Required } from '@/components/DataForm/rules'
|
||||
|
||||
var validatorInterval = (rule, value, callback) => {
|
||||
if (parseInt(value) < 1) {
|
||||
return callback(new Error(i18n.t('xpack.ChangeAuthPlan.validatorMessage.EnsureThisValueIsGreaterThanOrEqualTo1')))
|
||||
}
|
||||
callback()
|
||||
}
|
||||
|
||||
function getAssetPasswordRulesItems() {
|
||||
return [
|
||||
{
|
||||
id: 'length', prop: 'length', label: i18n.t('xpack.ChangeAuthPlan.PasswordLength'),
|
||||
rules: [Required], hidden: (formValue) => {
|
||||
return ['random_one', 'random_all'].indexOf(formValue.password_strategy) === -1 || !formValue.is_password
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
function getDatabasePasswordRulesItems() {
|
||||
return [
|
||||
{
|
||||
id: 'length', prop: 'length', label: i18n.t('xpack.ChangeAuthPlan.PasswordLength'),
|
||||
rules: [Required], hidden: (formValue) => {
|
||||
return ['random_one', 'random_all'].indexOf(formValue.password_strategy) === -1
|
||||
}
|
||||
},
|
||||
{
|
||||
id: 'symbol_set', prop: 'symbol_set',
|
||||
label: i18n.t('xpack.ChangeAuthPlan.SymbolSet'),
|
||||
helpText: i18n.t('xpack.ChangeAuthPlan.SymbolSetHelpText'),
|
||||
hidden: (formValue) => {
|
||||
return ['random_one', 'random_all'].indexOf(formValue.password_strategy) === -1
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
function generatePasswordRulesItemsFields(obType) {
|
||||
const itemsFields = []
|
||||
let items
|
||||
if (obType === 'asset') {
|
||||
items = getAssetPasswordRulesItems()
|
||||
} else if (obType === 'database') {
|
||||
items = getDatabasePasswordRulesItems()
|
||||
}
|
||||
items.forEach((item, index, array) => {
|
||||
itemsFields.push({
|
||||
id: item.id, prop: item.prop, el: {}, attrs: {}, type: 'input', label: item.label, rules: item.rules, helpText: item.helpText,
|
||||
hidden: item.hidden })
|
||||
})
|
||||
return itemsFields
|
||||
}
|
||||
|
||||
function getFields() {
|
||||
const username = {
|
||||
helpText: i18n.t('xpack.ChangeAuthPlan.HelpText.UsernameOfCreateUpdatePage')
|
||||
}
|
||||
|
||||
const assets = {
|
||||
type: 'assetSelect',
|
||||
component: AssetSelect,
|
||||
rules: [
|
||||
{ required: false }
|
||||
],
|
||||
label: i18n.t('xpack.Asset')
|
||||
}
|
||||
|
||||
const database = {
|
||||
component: Select2,
|
||||
rules: [
|
||||
{ required: true }
|
||||
],
|
||||
label: i18n.t('xpack.Database'),
|
||||
el: {
|
||||
multiple: false,
|
||||
value: [],
|
||||
ajax: {
|
||||
url: '/api/v1/applications/applications/?category=db',
|
||||
transformOption: (item) => {
|
||||
return { label: item.name + '(' + item.type_display + ')', value: item.id, protocol: item.type }
|
||||
}
|
||||
}
|
||||
},
|
||||
on: {
|
||||
changeOptions: ([event], updateform) => {
|
||||
updateform({ systemuser: [] })
|
||||
this.fieldsMeta.systemuser.el.ajax.url = `/api/v1/assets/system-users/?protocol=${event[0].protocol}`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const password = {
|
||||
hidden: (formValue) => {
|
||||
return formValue.password_strategy !== 'custom' || formValue.is_password === false
|
||||
},
|
||||
rules: [
|
||||
{ required: this.$route.meta.action === 'create', message: i18n.t('common.fieldRequiredError'), trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
|
||||
const asset_password_rules = {
|
||||
type: 'group',
|
||||
items: generatePasswordRulesItemsFields('asset')
|
||||
}
|
||||
|
||||
const database_password_rules = {
|
||||
type: 'group',
|
||||
items: generatePasswordRulesItemsFields('database')
|
||||
}
|
||||
|
||||
const private_key = {
|
||||
el: {
|
||||
type: 'textarea',
|
||||
placeholder: '-----BEGIN OPENSSH PRIVATE KEY-----',
|
||||
autosize: { minRows: 3 }
|
||||
},
|
||||
hidden: (formValue) => {
|
||||
return formValue.is_ssh_key === false
|
||||
},
|
||||
rules: [
|
||||
{ required: this.$route.meta.action === 'create', message: this.$t('common.fieldRequiredError'), trigger: 'blur' }
|
||||
]
|
||||
}
|
||||
|
||||
const nodes = {
|
||||
label: i18n.t('xpack.Node'),
|
||||
el: {
|
||||
value: [],
|
||||
ajax: {
|
||||
url: '/api/v1/assets/nodes/',
|
||||
transformOption: (item) => {
|
||||
return { label: item.full_value, value: item.id }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const is_password = {
|
||||
type: 'switch'
|
||||
}
|
||||
|
||||
const is_ssh_key = {
|
||||
type: 'switch'
|
||||
}
|
||||
|
||||
const password_strategy = {
|
||||
label: i18n.t('xpack.ChangeAuthPlan.PasswordStrategy'),
|
||||
hidden: (formValue) => {
|
||||
return formValue.is_password === false
|
||||
}
|
||||
}
|
||||
|
||||
const ssh_key_strategy = {
|
||||
label: i18n.t('xpack.ChangeAuthPlan.SecretKeyStrategy'),
|
||||
hidden: (formValue) => {
|
||||
return formValue.is_ssh_key === false
|
||||
}
|
||||
}
|
||||
|
||||
const systemuser = {
|
||||
component: Select2,
|
||||
label: i18n.t('xpack.ChangeAuthPlan.SystemUser'),
|
||||
rules: [
|
||||
{ required: true }
|
||||
],
|
||||
el: {
|
||||
value: [],
|
||||
ajax: {
|
||||
url: '/api/v1/assets/system-users/',
|
||||
transformOption: (item) => {
|
||||
return { label: item.name + '(' + item.username + ')', value: item.id }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const is_periodic = {
|
||||
type: 'switch'
|
||||
}
|
||||
|
||||
const crontab = {
|
||||
label: i18n.t('xpack.RegularlyPerform'),
|
||||
hidden: (formValue) => {
|
||||
return formValue.is_periodic === false
|
||||
},
|
||||
helpText: i18n.t('xpack.HelpText.CrontabOfCreateUpdatePage')
|
||||
}
|
||||
|
||||
const interval = {
|
||||
label: i18n.t('xpack.CyclePerform'),
|
||||
hidden: (formValue) => {
|
||||
return formValue.is_periodic === false
|
||||
},
|
||||
helpText: i18n.t('xpack.HelpText.IntervalOfCreateUpdatePage'),
|
||||
rules: [
|
||||
{ validator: validatorInterval }
|
||||
]
|
||||
}
|
||||
|
||||
return {
|
||||
username: username,
|
||||
assets: assets,
|
||||
database: database,
|
||||
systemuser: systemuser,
|
||||
password: password,
|
||||
password_strategy: password_strategy,
|
||||
ssh_key_strategy: ssh_key_strategy,
|
||||
private_key: private_key,
|
||||
asset_password_rules: asset_password_rules,
|
||||
database_password_rules: database_password_rules,
|
||||
nodes: nodes,
|
||||
is_password: is_password,
|
||||
is_periodic: is_periodic,
|
||||
is_ssh_key: is_ssh_key,
|
||||
crontab: crontab,
|
||||
interval: interval
|
||||
}
|
||||
}
|
||||
|
||||
export default getFields
|
||||
42
src/views/accounts/ChangeAuthPlan/index.vue
Normal file
42
src/views/accounts/ChangeAuthPlan/index.vue
Normal file
@@ -0,0 +1,42 @@
|
||||
<template>
|
||||
<TabPage :active-menu.sync="config.activeMenu" :submenu="config.submenu">
|
||||
<keep-alive>
|
||||
<component :is="config.activeMenu" />
|
||||
</keep-alive>
|
||||
</TabPage>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { TabPage } from '@/layout/components'
|
||||
import AssetChangeAuthPlanList from './AssetChangeAuthPlan/ChangeAuthPlanList'
|
||||
import AppChangeAuthPlanList from './AppChangeAuthPlan/AppChangeAuthPlanList'
|
||||
export default {
|
||||
name: 'Index',
|
||||
components: {
|
||||
TabPage,
|
||||
AssetChangeAuthPlanList,
|
||||
AppChangeAuthPlanList
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
config: {
|
||||
activeMenu: 'AssetChangeAuthPlanList',
|
||||
submenu: [
|
||||
{
|
||||
title: this.$t('xpack.ChangeAuthPlan.AssetChangeAuthPlan'),
|
||||
name: 'AssetChangeAuthPlanList'
|
||||
},
|
||||
{
|
||||
title: this.$t('xpack.ChangeAuthPlan.AppChangeAuthPlan'),
|
||||
name: 'AppChangeAuthPlanList'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,35 @@
|
||||
<template>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="20">
|
||||
<AppAccountListTable ref="ListTable" :url="accountUrl" :has-import="false" :has-clone="false" />
|
||||
</el-col>
|
||||
<el-col :span="4" />
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import { AppAccountListTable } from '@/components'
|
||||
|
||||
export default {
|
||||
name: 'AccountList',
|
||||
components: {
|
||||
AppAccountListTable
|
||||
},
|
||||
props: {
|
||||
object: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
accountUrl: `/api/v1/applications/accounts/?systemuser=${this.object.id}`
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang='less' scoped>
|
||||
|
||||
</style>
|
||||
126
src/views/assets/SystemUser/SystemUserDetail/AppList.vue
Normal file
126
src/views/assets/SystemUser/SystemUserDetail/AppList.vue
Normal file
@@ -0,0 +1,126 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="16">
|
||||
<ListTable ref="ListTable" :table-config="tableConfig" :header-actions="headerActions" />
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<RelationCard ref="assetSelect" type="primary" style="margin-top: 15px" v-bind="appRelationConfig" />
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ListTable from '@/components/ListTable'
|
||||
import { DetailFormatter } from '@/components/TableFormatters'
|
||||
import RelationCard from '@/components/RelationCard'
|
||||
|
||||
export default {
|
||||
name: 'AssetList',
|
||||
components: {
|
||||
RelationCard,
|
||||
ListTable
|
||||
},
|
||||
props: {
|
||||
object: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
const vm = this
|
||||
return {
|
||||
tableConfig: {
|
||||
name: 'AppList',
|
||||
url: `/api/v1/applications/accounts/?systemuser=${this.object.id}`,
|
||||
columns: ['app_display', 'actions'],
|
||||
columnsMeta: {
|
||||
app_display: {
|
||||
label: this.$t('applications.App'),
|
||||
showOverflowTooltip: true,
|
||||
formatter: DetailFormatter,
|
||||
formatterArgs: {
|
||||
getRoute({ row }) {
|
||||
const categoryRouteMapper = {
|
||||
'remote_app': 'RemoteAppDetail',
|
||||
'db': 'DatabaseAppDetail',
|
||||
'cloud': 'KubernetesAppDetail'
|
||||
}
|
||||
const name = categoryRouteMapper[row.category]
|
||||
return {
|
||||
name: name,
|
||||
params: { id: row.app }
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
formatterArgs: {
|
||||
hasUpdate: false, // can set function(row, value)
|
||||
hasDelete: false, // can set function(row, value)
|
||||
hasClone: false,
|
||||
moreActionsTitle: this.$t('common.More'),
|
||||
extraActions: [
|
||||
{
|
||||
name: 'Delete',
|
||||
title: this.$t('common.Delete'),
|
||||
type: 'danger',
|
||||
can: !this.$store.getters.currentOrgIsRoot,
|
||||
callback: (val) => {
|
||||
this.$axios.delete(`/api/v1/applications/accounts/${val.row.id}/`).then(() => {
|
||||
this.$message.success(this.$t('common.deleteSuccessMsg'))
|
||||
this.$refs.ListTable.reloadTable()
|
||||
})
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
headerActions: {
|
||||
hasLeftActions: false,
|
||||
hasBulkDelete: false,
|
||||
hasImport: false,
|
||||
hasCreate: false
|
||||
},
|
||||
appRelationConfig: {
|
||||
icon: 'fa-edit',
|
||||
title: this.$t('applications.associateApplication'),
|
||||
disabled: this.$store.getters.currentOrgIsRoot,
|
||||
objectsAjax: {
|
||||
url: `/api/v1/applications/applications/?type=${vm.object.protocol}`,
|
||||
transformOption: (item) => {
|
||||
return { label: item.name + ' (' + item.type_display + ')', value: item.id }
|
||||
}
|
||||
},
|
||||
showHasObjects: false,
|
||||
performAdd: (items) => {
|
||||
const objectId = this.object.id
|
||||
const relationUrl = `/api/v1/applications/accounts/`
|
||||
const appsId = items.map(v => v.value)
|
||||
const data = []
|
||||
for (const appId of appsId) {
|
||||
data.push({ systemuser: objectId, app: appId })
|
||||
}
|
||||
return this.$axios.post(relationUrl, data)
|
||||
},
|
||||
onAddSuccess: (objects, that) => {
|
||||
this.$log.debug('Select value', that.select2.value)
|
||||
that.iHasObjects = [...that.iHasObjects, ...objects]
|
||||
that.$refs.select2.clearSelected()
|
||||
this.$message.success(this.$t('common.updateSuccessMsg'))
|
||||
this.$refs.ListTable.reloadTable()
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang='less' scoped>
|
||||
|
||||
</style>
|
||||
@@ -11,13 +11,18 @@ import { GenericDetailPage, TabPage } from '@/layout/components'
|
||||
import Detail from './Detail.vue'
|
||||
import AssetList from './AssetList.vue'
|
||||
import AccountList from './AccountList.vue'
|
||||
import AppList from './AppList'
|
||||
import AppAccountList from './AppAccountList'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
GenericDetailPage,
|
||||
TabPage,
|
||||
Detail,
|
||||
AssetList,
|
||||
AccountList
|
||||
AccountList,
|
||||
AppList,
|
||||
AppAccountList
|
||||
},
|
||||
data() {
|
||||
const vm = this
|
||||
@@ -32,11 +37,31 @@ export default {
|
||||
},
|
||||
{
|
||||
title: this.$t('assets.AssetList'),
|
||||
name: 'AssetList'
|
||||
name: 'AssetList',
|
||||
hidden: () => {
|
||||
return !vm.systemUser['is_asset_protocol']
|
||||
}
|
||||
},
|
||||
{
|
||||
title: this.$t('assets.AccountList'),
|
||||
name: 'AccountList'
|
||||
name: 'AccountList',
|
||||
hidden: () => {
|
||||
return !vm.systemUser['is_asset_protocol']
|
||||
}
|
||||
},
|
||||
{
|
||||
title: this.$t('assets.AppList'),
|
||||
name: 'AppList',
|
||||
hidden: () => {
|
||||
return vm.systemUser['is_asset_protocol']
|
||||
}
|
||||
},
|
||||
{
|
||||
title: this.$t('assets.AccountList'),
|
||||
name: 'AppAccountList',
|
||||
hidden: () => {
|
||||
return vm.systemUser['is_asset_protocol']
|
||||
}
|
||||
}
|
||||
],
|
||||
hasRightSide: true,
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
<template>
|
||||
<h1 />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Vault'
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
Reference in New Issue
Block a user