Merge pull request #2164 from jumpserver/dev

v2.28.0-rc1
This commit is contained in:
Jiangjie.Bai
2022-11-10 17:45:47 +08:00
committed by GitHub
23 changed files with 6105 additions and 3754 deletions

View File

@@ -1,7 +1,5 @@
FROM node:14.16 as stage-build
ARG TARGETARCH
ARG VERSION
ENV VERSION=$VERSION
ARG NPM_REGISTRY="https://registry.npmmirror.com"
ENV NPM_REGISTY=$NPM_REGISTRY
@@ -12,10 +10,15 @@ RUN set -ex \
&& yarn config set registry ${NPM_REGISTRY} \
&& yarn config set cache-folder /root/.cache/yarn/lina
ADD package.json yarn.lock /data
RUN --mount=type=cache,target=/root/.cache/yarn \
yarn install
ARG VERSION
ENV VERSION=$VERSION
ADD . /data
RUN --mount=type=cache,target=/root/.cache/yarn \
sed -i "s@Version <strong>.*</strong>@Version <strong>${VERSION}</strong>@g" src/layout/components/Footer/index.vue \
&& yarn install \
&& yarn build
FROM nginx:alpine

View File

@@ -0,0 +1,61 @@
<template>
<el-row :gutter="10">
<div v-if="isAllEmpty()" style="text-align: center">
{{ this.$t('common.NoContent') }}
</div>
<div v-else>
<el-col :span="rightEmpty() ? 24 : 12">
<div v-if="!leftEmpty()">
<el-alert type="info" effect="dark" :closable="false" style="width: 100%;">{{ row.leftTitle }}</el-alert>
<div v-for="(value, key, index) in row.left" :key="index" class="text item">
<el-tag type="info" :hit="true"><strong>{{ key }}: </strong>{{ value }}</el-tag>
</div>
</div>
</el-col>
<el-col :span="leftEmpty() ? 24 : 12">
<div v-if="!rightEmpty()">
<el-alert type="success" effect="dark" :closable="false" style="width: 100%;">{{ row.rightTitle }}</el-alert>
<div v-for="(value, key, index) in row.right" :key="index">
<el-tag type="info" :hit="true"><strong>{{ key }}: </strong>{{ value }}</el-tag>
</div>
</div>
</el-col>
</div>
</el-row>
</template>
<script>
export default {
name: 'TwoTabFormatter',
props: {
row: {
type: Object,
default: () => ({})
}
},
methods: {
isEmpty(content) {
return !content || JSON.stringify(content) === '{}'
},
leftEmpty() {
return this.isEmpty(this.row.left)
},
rightEmpty() {
return this.isEmpty(this.row.right)
},
isAllEmpty() {
return this.leftEmpty() && this.rightEmpty()
}
}
}
</script>
<style scoped>
.el-tag{
width: 100%;
white-space: normal;
height:auto;
}
</style>

View File

@@ -12,6 +12,7 @@ import DialogDetailFormatter from './DialogDetailFormatter'
import EditableInputFormatter from './EditableInputFormatter'
import StatusFormatter from './StatusFormatter'
import TagsFormatter from './TagsFormatter'
import TwoTabFormatter from './TwoTabFormatter'
export default {
DetailFormatter,
@@ -27,7 +28,8 @@ export default {
ArrayFormatter,
EditableInputFormatter,
StatusFormatter,
TagsFormatter
TagsFormatter,
TwoTabFormatter
}
export {
@@ -44,5 +46,6 @@ export {
ArrayFormatter,
EditableInputFormatter,
StatusFormatter,
TagsFormatter
TagsFormatter,
TwoTabFormatter
}

View File

@@ -47,6 +47,7 @@
"sqlserver": "SQLServer",
"redis": "Redis",
"mongodb": "MongoDB",
"clickhouse": "ClickHouse",
"k8s": "kubernetes"
},
"applicationsCategory": {
@@ -244,7 +245,9 @@
"View": "View",
"LoginIP": "Login IP",
"LoginCity": "Login city",
"LoginDate": "Login date"
"LoginDate": "Login date",
"BeforeChange": "Before change",
"AfterChange": "After change"
},
"auth": {
"LoginRequiredMsg": "You account has logout, Please login again",
@@ -254,6 +257,7 @@
"ReLoginErr": "Login time has exceeded 5 minutes, please login again"
},
"common": {
"NoContent": "No content",
"NeedAddAppsOrSystemUserErrMsg": "Please add apps or system user",
"VerificationCodeSent": "The verification code has been sent",
"SendVerificationCode": "Send verification code",
@@ -1435,6 +1439,7 @@
"HuaweiCloud": "Huawei Cloud",
"BaiduCloud": "Baidu Cloud",
"JDCloud": "JD Cloud",
"KingSoftCloud": "KingSoft Cloud",
"Azure":"Azure(China)",
"Azure_Int": "Azure(International)",
"HostnameStrategy": "Used to produce the asset hostname. For example, 1. Instance name (instanceDemo)2. Instance name and Partial IP (instanceDemo-250.1)",

View File

@@ -52,6 +52,7 @@
"sqlserver": "SQLServer",
"redis": "Redis",
"mongodb": "MongoDB",
"clickhouse": "ClickHouse",
"k8s": "Kubernetes"
},
"applicationsCategory": {
@@ -249,7 +250,9 @@
"SystemUserName": "システムユーザー名",
"LoginIP": "ログインIP",
"LoginCity": "ログイン都市",
"LoginDate": "ログイン日"
"LoginDate": "ログイン日",
"BeforeChange": "変更前",
"AfterChange": "変更後"
},
"auth": {
"LoginRequiredMsg": "アカウントが終了しました。ログインし直してください",
@@ -259,6 +262,7 @@
"ReLoginErr": "ログイン時間が 5 分を超えました。もう一度ログインしてください"
},
"common": {
"NoContent": "まだ内容がない",
"NeedAddAppsOrSystemUserErrMsg": "アプリケーションまたはシステムユーザーを追加してください",
"VerificationCodeSent": "検証コードが送信されました",
"SendVerificationCode": "認証コードの送信",
@@ -1478,6 +1482,7 @@
"HuaweiCloud": "ファーウェイ雲",
"BaiduCloud": "百度雲",
"JDCloud": "京東雲",
"KingSoftCloud": "金山雲",
"Azure": "Azure(中国)",
"Azure_Int": "Azure (国際)",
"HostnameStrategy": "資産を生成するためにホスト名。例: 1. インスタンス名 (instanceDemo) 2.インスタンス名と一部IP (下位2桁) (instanceDemo-250.1)",

View File

@@ -52,6 +52,7 @@
"sqlserver": "SQLServer",
"redis": "Redis",
"mongodb": "MongoDB",
"clickhouse": "ClickHouse",
"k8s": "Kubernetes"
},
"applicationsCategory": {
@@ -249,7 +250,9 @@
"SystemUserName": "系统用户名",
"LoginIP": "登录IP",
"LoginCity": "登录城市",
"LoginDate": "登录日期"
"LoginDate": "登录日期",
"BeforeChange": "变更前",
"AfterChange": "变更后"
},
"auth": {
"LoginRequiredMsg": "账号已退出,请重新登录",
@@ -259,6 +262,7 @@
"ReLoginErr": "登录时长已超过 5 分钟,请重新登录"
},
"common": {
"NoContent": "暂无内容",
"NeedAddAppsOrSystemUserErrMsg": "需要添加应用或系统用户",
"VerificationCodeSent": "验证码已发送",
"SendVerificationCode": "发送验证码",
@@ -1479,6 +1483,7 @@
"HuaweiCloud": "华为云",
"BaiduCloud": "百度云",
"JDCloud": "京东云",
"KingSoftCloud": "金山云",
"Azure":"Azure(中国)",
"Azure_Int": "Azure(国际)",
"HostnameStrategy": "用于生成资产主机名。例如1. 实例名称 (instanceDemo)2. 实例名称和部分IP(后两位) (instanceDemo-250.1)",

View File

@@ -78,7 +78,6 @@ export default {
hasRefresh: true,
hasExport: false,
hasImport: false,
hasMoreActions: false,
createRoute: () => {
return {
name: 'AccountBackupPlanCreate'

View File

@@ -123,7 +123,6 @@ export default {
hasRefresh: true,
hasExport: false,
hasImport: false,
hasMoreActions: false,
searchConfig: {
getUrlQuery: false
},

View File

@@ -107,7 +107,6 @@ export default {
hasRefresh: true,
hasExport: false,
hasImport: false,
hasMoreActions: false,
createRoute: () => {
return {
name: 'AssetChangeAuthPlanCreate'

View File

@@ -84,8 +84,7 @@ export default {
createRoute: 'AssetAclCreate',
hasRefresh: true,
hasExport: false,
hasImport: false,
hasMoreActions: false
hasImport: false
}
}
}

View File

@@ -52,6 +52,7 @@ export const DATABASE_CATEGORY = 'db'
export const SQLSERVER = 'sqlserver'
export const REDIS = 'redis'
export const MONGODB = 'mongodb'
export const CLICKHOUSE = 'clickhouse'
export const DATABASE = [
{
@@ -89,6 +90,13 @@ export const DATABASE = [
type: 'primary',
category: DATABASE_CATEGORY,
has: hasLicence
},
{
name: CLICKHOUSE,
title: i18n.t(`applications.applicationsType.${CLICKHOUSE}`),
type: 'primary',
category: DATABASE_CATEGORY,
has: hasLicence
}
]

View File

@@ -4,7 +4,7 @@
<script type="text/jsx">
import GenericListTable from '@/layout/components/GenericListTable'
import { ACCOUNT_PROVIDER_ATTRS_MAP, aliyun, aws_china, aws_international, huaweicloud, qcloud, qcloud_lighthouse, azure, azure_international, vmware, nutanix, qingcloud_private, huaweicloud_private, ctyun_private, openstack, gcp, baiducloud, jdcloud, fc, lan } from '../const'
import { ACCOUNT_PROVIDER_ATTRS_MAP, aliyun, aws_china, aws_international, huaweicloud, qcloud, qcloud_lighthouse, azure, azure_international, vmware, nutanix, qingcloud_private, huaweicloud_private, ctyun_private, openstack, gcp, baiducloud, jdcloud, kingsoftcloud, fc, lan } from '../const'
export default {
name: 'AccountList',
@@ -98,6 +98,10 @@ export default {
name: jdcloud,
title: ACCOUNT_PROVIDER_ATTRS_MAP[jdcloud].title
},
{
name: kingsoftcloud,
title: ACCOUNT_PROVIDER_ATTRS_MAP[kingsoftcloud].title
},
{
name: aws_china,
title: ACCOUNT_PROVIDER_ATTRS_MAP[aws_china].title

View File

@@ -24,7 +24,7 @@ export default {
fields: [
[this.$t('common.Basic'), ['name']],
[this.$t('xpack.Cloud.CloudSource'), ['account', 'regions']],
[this.$t('xpack.Cloud.SaveSetting'), ['hostname_strategy', 'node', 'unix_admin_user', 'windows_admin_user', 'protocols', 'ip_network_segment_group', 'is_always_update']],
[this.$t('xpack.Cloud.SaveSetting'), ['hostname_strategy', 'node', 'unix_admin_user', 'windows_admin_user', 'protocols', 'ip_network_segment_group', 'sync_ip_type', 'is_always_update']],
[this.$t('xpack.Timer'), ['is_periodic', 'crontab', 'interval']],
[this.$t('common.Other'), ['comment']]
],

View File

@@ -4,6 +4,7 @@ export const gcp = 'gcp'
export const aliyun = 'aliyun'
export const baiducloud = 'baiducloud'
export const jdcloud = 'jdcloud'
export const kingsoftcloud = 'kingsoftcloud'
export const aws_international = 'aws_international'
export const aws_china = 'aws_china'
export const huaweicloud = 'huaweicloud'
@@ -52,6 +53,11 @@ export const ACCOUNT_PROVIDER_ATTRS_MAP = {
title: i18n.t('xpack.Cloud.JDCloud'),
attrs: ['access_key_id', 'access_key_secret']
},
[kingsoftcloud]: {
name: kingsoftcloud,
title: i18n.t('xpack.Cloud.KingSoftCloud'),
attrs: ['access_key_id', 'access_key_secret']
},
[qcloud]: {
name: qcloud,
title: i18n.t('xpack.Cloud.Qcloud'),

View File

@@ -80,7 +80,6 @@ export default {
hasImport: false,
hasRefresh: true,
hasSearch: true,
hasMoreActions: false,
createRoute: 'CommandFilterCreate'
}
}

View File

@@ -42,7 +42,6 @@ export default {
}
},
headerActions: {
hasMoreActions: false,
createRoute: 'DomainCreate'
},
notice: this.$t('assets.DomainHelpMessage')

View File

@@ -27,7 +27,6 @@ export default {
}
},
headerActions: {
hasMoreActions: false,
createRoute: 'LabelCreate'
}
}

View File

@@ -49,6 +49,7 @@ export default {
case 'sqlserver':
case 'redis':
case 'mongodb':
case 'clickhouse':
return Database
case 'k8s':
return K8S

View File

@@ -1,23 +1,43 @@
<template>
<GenericListPage :table-config="tableConfig" :header-actions="headerActions" />
<div>
<GenericListPage :table-config="tableConfig" :header-actions="headerActions" />
<el-dialog
:title="this.$t('route.OperateLog')"
:visible.sync="logDetailVisible"
width="70%"
>
<TwoTabFormatter :row="rowObj" />
</el-dialog>
</div>
</template>
<script>
import GenericListPage from '@/layout/components/GenericListPage'
import { getDaysAgo, getDaysFuture } from '@/utils/common'
import TwoTabFormatter from '@/components/TableFormatters/TwoTabFormatter'
import { ActionsFormatter } from '@/components/TableFormatters'
export default {
components: {
GenericListPage
GenericListPage,
TwoTabFormatter
},
data() {
const vm = this
const now = new Date()
const dateFrom = getDaysAgo(7, now).toISOString()
const dateTo = getDaysFuture(1, now).toISOString()
return {
rowObj: {
left: '',
rigth: '',
leftTitle: vm.$t('audits.BeforeChange'),
rightTitle: vm.$t('audits.AfterChange')
},
logDetailVisible: false,
tableConfig: {
url: '/api/v1/audits/operate-logs/',
columns: ['user', 'action_display', 'resource_type_display', 'resource', 'remote_addr', 'datetime'],
columns: ['user', 'action_display', 'resource_type_display', 'resource', 'remote_addr', 'datetime', 'actions'],
columnsMeta: {
user: {
showOverflowTooltip: true
@@ -36,7 +56,35 @@ export default {
width: '140px'
},
action_display: {
width: '90px'
width: '70px'
},
actions: {
width: '70px',
formatter: ActionsFormatter,
formatterArgs: {
hasUpdate: false,
canUpdate: false,
hasDelete: false,
canDelete: false,
hasClone: false,
canClone: false,
extraActions: [
{
name: 'View',
title: this.$t('common.View'),
type: 'primary',
callback: ({ row }) => {
vm.$axios.get(
`/api/v1/audits/operate-logs/${row.id}/?type=action_detail`,
).then(res => {
vm.rowObj.left = res.before
vm.rowObj.right = res.after
vm.logDetailVisible = true
})
}
}
]
}
}
},
extraQuery: {

View File

@@ -37,8 +37,7 @@ import DetailCard from '@/components/DetailCard'
import QuickActions from '@/components/QuickActions'
import UserConfirmDialog from '@/components/UserConfirmDialog'
import { toSafeLocalDateStr } from '@/utils/common'
import { getProfile } from '@/api/users'
import { mapState } from 'vuex'
import store from '@/store'
export default {
name: 'ProfileInfo',
@@ -48,9 +47,14 @@ export default {
QuickActions,
UserConfirmDialog
},
props: {
object: {
type: Object,
default: () => store.state.users.profile
}
},
data() {
return {
object: this.userProfile || {},
url: `/api/v1/users/profile/`,
showPasswordDialog: false,
currentEdit: '',
@@ -213,9 +217,6 @@ export default {
}
},
computed: {
...mapState({
userProfile: state => state.users.profile
}),
detailCardItems() {
return [
{
@@ -298,12 +299,6 @@ export default {
return url
}
},
created() {
getProfile().then(res => {
this.object = res
this.$store.commit('users/SET_PROFILE', res)
})
},
methods: {
updateUserReceiveBackends(val) {
this.$axios.patch(
@@ -311,6 +306,7 @@ export default {
{ 'receive_backends': this.getReceiveBackendList() }
).then(res => {
this.$message.success(this.$t('common.updateSuccessMsg'))
this.$store.dispatch('users/getProfile', true)
}).catch(err => {
this.$message.error(this.$t('common.updateErrorMsg' + ' ' + err))
})

View File

@@ -37,6 +37,12 @@ export default {
[
'TERMINAL_MAGNUS_ENABLED'
]
],
[
`Web ${comp}(Luna)`,
[
'TERMINAL_GRAPHICAL_RESOLUTION'
]
]
],
fieldsMeta: {

View File

@@ -171,6 +171,9 @@ export default {
if (value.update_password !== undefined) {
delete value.update_password
}
if (value.source !== 'local') {
delete value.need_update_password
}
return value
}
}

9644
yarn.lock

File diff suppressed because it is too large Load Diff