mirror of
https://github.com/jumpserver/lina.git
synced 2026-01-29 21:28:52 +00:00
@@ -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
|
||||
|
||||
61
src/components/TableFormatters/TwoTabFormatter.vue
Normal file
61
src/components/TableFormatters/TwoTabFormatter.vue
Normal 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>
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)",
|
||||
|
||||
@@ -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)",
|
||||
|
||||
@@ -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)",
|
||||
|
||||
@@ -78,7 +78,6 @@ export default {
|
||||
hasRefresh: true,
|
||||
hasExport: false,
|
||||
hasImport: false,
|
||||
hasMoreActions: false,
|
||||
createRoute: () => {
|
||||
return {
|
||||
name: 'AccountBackupPlanCreate'
|
||||
|
||||
@@ -123,7 +123,6 @@ export default {
|
||||
hasRefresh: true,
|
||||
hasExport: false,
|
||||
hasImport: false,
|
||||
hasMoreActions: false,
|
||||
searchConfig: {
|
||||
getUrlQuery: false
|
||||
},
|
||||
|
||||
@@ -107,7 +107,6 @@ export default {
|
||||
hasRefresh: true,
|
||||
hasExport: false,
|
||||
hasImport: false,
|
||||
hasMoreActions: false,
|
||||
createRoute: () => {
|
||||
return {
|
||||
name: 'AssetChangeAuthPlanCreate'
|
||||
|
||||
@@ -84,8 +84,7 @@ export default {
|
||||
createRoute: 'AssetAclCreate',
|
||||
hasRefresh: true,
|
||||
hasExport: false,
|
||||
hasImport: false,
|
||||
hasMoreActions: false
|
||||
hasImport: false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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']]
|
||||
],
|
||||
|
||||
@@ -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'),
|
||||
|
||||
@@ -80,7 +80,6 @@ export default {
|
||||
hasImport: false,
|
||||
hasRefresh: true,
|
||||
hasSearch: true,
|
||||
hasMoreActions: false,
|
||||
createRoute: 'CommandFilterCreate'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,6 @@ export default {
|
||||
}
|
||||
},
|
||||
headerActions: {
|
||||
hasMoreActions: false,
|
||||
createRoute: 'DomainCreate'
|
||||
},
|
||||
notice: this.$t('assets.DomainHelpMessage')
|
||||
|
||||
@@ -27,7 +27,6 @@ export default {
|
||||
}
|
||||
},
|
||||
headerActions: {
|
||||
hasMoreActions: false,
|
||||
createRoute: 'LabelCreate'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@ export default {
|
||||
case 'sqlserver':
|
||||
case 'redis':
|
||||
case 'mongodb':
|
||||
case 'clickhouse':
|
||||
return Database
|
||||
case 'k8s':
|
||||
return K8S
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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))
|
||||
})
|
||||
|
||||
@@ -37,6 +37,12 @@ export default {
|
||||
[
|
||||
'TERMINAL_MAGNUS_ENABLED'
|
||||
]
|
||||
],
|
||||
[
|
||||
`Web ${comp}(Luna)`,
|
||||
[
|
||||
'TERMINAL_GRAPHICAL_RESOLUTION'
|
||||
]
|
||||
]
|
||||
],
|
||||
fieldsMeta: {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user