import qs from 'qs'
import { SERVER_TYPE, SMART_SSH_FORM_DECORATORS } from '@Compute/constants'
import VncInfoFetcher from '@Compute/sections/VncInfoFetcher'
import { disableDeleteAction } from '@/utils/common/tableActions'
import { typeClouds, findPlatform } from '@/utils/common/hypervisor'
import i18n from '@/locales'
import { HOST_CPU_ARCHS } from '@/constants/compute'
import { PROVIDER_MAP, BRAND_MAP } from '@/constants'
import { hasSetupKey, isLicense2 } from '@/utils/auth'
import { KVM_SHARE_STORAGES } from '@/constants/storage'
import { POLICY_RES_NAME_KEY_MAP } from '@/constants/policy'
import { commonUnabled, cloudEnabled, cloudUnabledTip, commonEnabled, commonTip, validateRescueMode } from '../utils'
const getSingleActions = function (ctx) {
let hasBastionService = false
const that = ctx || this
const { services = [] } = that.$store?.getters?.userInfo || {}
const bastionService = services.find(val => val.type === 'bastionhost')
if (bastionService && bastionService.status === true) {
hasBastionService = true
}
return [
{
label: i18n.t('compute.text_341'),
permission: 'server_get_vnc',
actions: obj => {
let ret = []
const vncRemote = {
label: i18n.t('compute.text_1274'),
action: () => {
const success = () => {
const isValidURL = str => {
const regex = /(\w+):\/\/(\w+:{0,1}\w*)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%!-/]))?/
if (!regex.test(str)) {
return false
} else {
return true
}
}
const params = {}
if (obj.hypervisor === typeClouds.hypervisorMap.openstack.key) {
params.origin = true
}
this.webconsoleManager.performAction({
id: 'server',
action: obj.id,
data: params,
}).then(({ data }) => {
if (isValidURL(data.connect_params)) {
this.open(obj, data.connect_params)
} else {
this.openWebConsole(obj, data)
}
})
}
if (this.enableMFA) {
this.createDialog('SecretVertifyDialog', {
success,
})
} else {
success()
}
},
meta: () => {
const ret = {
validate: true,
tooltip: '',
}
if (obj.provider === 'OneCloud') {
ret.validate = obj.power_states === 'on'
ret.tooltip = obj.power_states === 'on' ? '' : i18n.t('compute.power_states_check_tip', [i18n.t('common_239'), `【${i18n.t('compute.text_574')}】`])
} else {
ret.validate = obj.power_states === 'unknown' ? cloudEnabled('vnc', obj) : obj.power_states === 'on'
ret.tooltip = obj.power_states === 'unknown' ? cloudUnabledTip('vnc', obj) : (obj.power_states === 'on' ? '' : i18n.t('compute.power_states_check_tip', [i18n.t('common_239'), `【${i18n.t('compute.text_574')}】`]))
if (cloudEnabled('vnc', obj) === false) {
ret.validate = false
ret.tooltip = cloudUnabledTip('vnc', obj)
}
}
return ret
},
}
if (obj.provider === 'OneCloud' && obj.status === 'running') {
vncRemote.render = (obj, params, h) => {
return
}
}
ret.push(vncRemote)
const mapIpActions = (ipInfoList) => {
const options = []
ipInfoList.forEach(ipInfo => {
const actionType = ipInfo.actionType
const ipAddr = ipInfo.ipAddr
const meta = () => {
const ret = {
validate: false,
tooltip: null,
}
const rescueModeValid = validateRescueMode(obj)
if (!rescueModeValid.validate) return rescueModeValid
// if (obj.os_type === 'Windows') {
// ret.tooltip = i18n.t('compute.text_344')
// return ret
// }
ret.validate = cloudEnabled(actionType, obj)
ret.tooltip = cloudUnabledTip(actionType, obj)
return ret
}
const openWebconsole = async (prms, id) => {
const params = {
id: 'ssh',
action: id,
data: {
id,
ip: ipAddr,
...prms,
type: 'server',
},
}
this.webconsoleManager.performAction(params).then(({ data }) => {
const connectParams = qs.parse(data.connect_params)
// 验证账号密码
if (connectParams.is_need_login === 'true') {
this.createDialog('SshAuthDialog', {
manager: this.webconsoleManager,
params,
errorMsg: connectParams.login_error_message,
data: { name: obj.name, ip: ipAddr, id: obj.id, resource: 'servers' },
success: (data) => {
this.openWebConsole(obj, data, 'ws')
},
})
return
}
// 无需验证账号密码
this.openWebConsole(obj, data, 'ws')
})
}
const isWindows = obj.os_type === 'Windows' || (obj.metadata?.os_distribution === 'Windows')
if (!isWindows) {
options.push({
label: `SSH ${ipAddr}`,
permission: 'server_perform_list_forward,server_perform_open_forward',
meta,
render: (obj, params, h) => {
let styleObj = {
padding: '0 10px',
fontSize: '12px',
}
const isRunning = obj.power_states === 'on'
if (!isRunning || obj.rescue_mode === true) {
styleObj = {
...styleObj,
cursor: 'not-allowed',
color: 'rgba(0, 0, 0, 0.25)',
}
}
const sshConnectHandle = () => {
const success = () => {
openWebconsole({ port: 22 }, obj.id)
}
if (this.enableMFA) {
this.createDialog('SecretVertifyDialog', {
success,
})
} else {
success()
}
}
const sshSettingInfoHandle = () => {
this.createDialog('SmartFormDialog', {
title: i18n.t('compute.custom_ssh_connect', ['SSH']),
data: [obj],
callback: async (data) => {
openWebconsole({ port: data.port, username: data.username, password: data.password }, obj.id)
},
decorators: SMART_SSH_FORM_DECORATORS,
})
}
return
{ }}>{`SSH ${ipAddr.length > 17 ? `${ipAddr.slice(0, 17)}...` : ipAddr}`}
{
isRunning ?
{ }} />
: null
}
},
})
} else {
const rdpSettingInfoHandle = () => {
this.createDialog('SmartFormDialog', {
title: i18n.t('compute.custom_ssh_connect', ['RDP']),
data: [obj],
callback: async (data) => {
handleRdpConnect(obj, data, 'rdp')
},
decorators: SMART_SSH_FORM_DECORATORS,
})
}
const handleRdpConnect = (obj, prms = {}) => {
const width = window.innerWidth
const height = window.innerHeight - 37
const params = {
id: 'server-rdp',
action: obj.id,
data: {
host: ipAddr,
width,
height,
...prms,
},
}
this.webconsoleManager.performAction(params).then(({ data }) => {
const connectParams = qs.parse(data.connect_params)
// 验证账号密码
if (connectParams.is_need_login === 'true') {
this.createDialog('RdpAuthDialog', {
manager: this.webconsoleManager,
params,
errorMsg: connectParams.login_error_message,
data: { name: obj.name, ip: ipAddr },
success: (data) => {
this.openWebConsole(obj, data, 'rdp')
},
})
return
}
// 无需验证账号密码
this.openWebConsole(obj, data, 'rdp')
}).catch((ex) => {
const { details } = ex.response.data
this.createDialog('RdpAuthDialog', {
manager: this.webconsoleManager,
params,
errorMsg: details,
data: { name: obj.name, ip: ipAddr },
success: (data) => {
this.openWebConsole(obj, data, 'rdp')
},
})
})
}
const rdpConnectHandle = () => {
const success = () => {
handleRdpConnect(obj)
}
if (this.enableMFA) {
this.createDialog('SecretVertifyDialog', {
success,
})
} else {
success()
}
}
options.push({
label: `RDP ${ipAddr}`,
permission: 'server_perform_list_forward,server_perform_open_forward',
meta,
render: (obj, params, h) => {
let styleObj = {
padding: '0 10px',
fontSize: '12px',
}
const isRunning = obj.power_states === 'on'
if (!isRunning || obj.rescue_mode === true) {
styleObj = {
...styleObj,
cursor: 'not-allowed',
color: 'rgba(0, 0, 0, 0.25)',
}
}
return
{ }}>{`RDP ${ipAddr}`}
{
isRunning ?
{ }} />
: null
}
},
})
}
})
return options
}
const ipInfoList = []
if (obj.eip) {
obj.eip.split(',').filter(item => !!item).map(ip => {
ipInfoList.push({
actionType: 'EIP SSH',
ipType: 'eip',
ipAddr: ip,
})
})
}
if (obj.nics) {
obj.nics.map(nic => {
if ((((obj.provider === 'OneCloud' || obj.vpc_id === 'default') && nic.is_default) || obj.provider === 'InCloudSphere') && nic.ip_addr) {
ipInfoList.push({
actionType: 'IP SSH',
ipType: 'nicIP',
ipAddr: nic.ip_addr,
vpcId: nic.vpc_id,
provider: obj.provider,
})
}
if ((((obj.provider === 'OneCloud' || obj.vpc_id === 'default') && nic.is_default) || obj.provider === 'InCloudSphere') && nic.ip6_addr) {
ipInfoList.push({
actionType: 'IP SSH',
ipType: 'nicIP',
ipAddr: nic.ip6_addr,
vpcId: nic.vpc_id,
provider: obj.provider,
})
}
})
}
const sshActions = mapIpActions(ipInfoList)
ret = ret.concat(sshActions)
return ret
},
meta: (obj) => {
let ret = {
validate: true,
tooltip: null,
}
ret = this.$isValidateResourceLock(obj)
return ret
},
hidden: () => this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_web_console'),
},
{
label: i18n.t('compute.text_352'),
actions: (obj) => {
return [
// * 实例状态
{
label: i18n.t('compute.text_353'),
submenus: [
// 同步状态
{
label: i18n.t('compute.perform_sync_status'),
permission: 'server_perform_syncstatus',
action: () => {
this.onManager('performAction', {
steadyStatus: ['running', 'ready'],
id: obj.id,
managerArgs: {
action: 'syncstatus',
},
})
},
meta: () => {
const ret = {
validate: false,
tooltip: null,
}
if (commonUnabled(obj)) return ret
ret.validate = true
return ret
},
hidden: () => this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_syncstatus'),
},
// 开机
{
label: i18n.t('compute.text_272'),
permission: 'server_perform_start',
action: (obj) => {
this.createDialog('VmStartDialog', {
data: [obj],
columns: this.columns,
onManager: this.onManager,
})
},
meta: () => {
return {
validate: cloudEnabled('start', obj),
}
},
hidden: () => this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_start'),
},
// 关机
{
label: i18n.t('compute.text_273'),
permission: 'server_perform_stop',
action: () => {
this.createDialog('VmShutDownDialog', {
data: [obj],
columns: this.columns,
onManager: this.onManager,
})
},
meta: () => {
return { validate: cloudEnabled('stop', obj) }
},
hidden: () => this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_stop'),
},
// 重启
{
label: i18n.t('compute.text_274'),
permission: 'server_perform_restart',
action: () => {
this.createDialog('VmRestartDialog', {
data: [obj],
columns: this.columns,
onManager: this.onManager,
})
},
meta: () => {
return {
validate: cloudEnabled('restart', obj),
}
},
hidden: () => this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_restart'),
},
// 重置
{
label: i18n.t('compute.text_354'),
permission: 'server_perform_reset',
action: () => {
this.createDialog('VmResetDialog', {
data: [obj],
columns: this.columns,
onManager: this.onManager,
})
},
meta: () => {
const provider = obj.provider
const ret = {
validate: false,
tooltip: null,
}
if (obj.hypervisor === typeClouds.hypervisorMap.bingocloud.key) {
ret.tooltip = i18n.t('compute.text_473', [typeClouds.hypervisorMap.bingocloud.label])
return ret
}
if (obj.brand !== BRAND_MAP.OneCloud.key) {
ret.tooltip = i18n.t('compute.text_473', [PROVIDER_MAP[provider].label])
return ret
}
return {
validate: (obj.status === 'running' || obj.status === 'stop_fail') && !commonUnabled(obj),
}
},
hidden: () => !(hasSetupKey(['onecloud'])) || this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_reset'),
},
// 挂起
{
label: i18n.t('compute.text_1128'),
permission: 'server_perform_suspend',
action: () => {
this.createDialog('VmSuspendDialog', {
data: [obj],
columns: this.columns,
onManager: this.onManager,
})
},
meta: () => {
const provider = obj.provider
const ret = {
validate: false,
tooltip: null,
}
if (![BRAND_MAP.VMware.key, BRAND_MAP.OneCloud.key].includes(obj.brand)) {
ret.tooltip = i18n.t('compute.text_473', [PROVIDER_MAP[provider].label])
return ret
}
if (obj.status !== 'running') {
ret.validate = false
ret.tooltip = i18n.t('compute.text_1130')
return ret
}
ret.validate = true
return ret
},
hidden: () => !(hasSetupKey(['vmware'])) || this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_suspend'),
},
// 恢复
{
label: i18n.t('compute.text_478'),
permission: 'server_perform_resume',
action: () => {
this.createDialog('VmResumeDialog', {
data: [obj],
columns: this.columns,
onManager: this.onManager,
})
},
meta: () => {
const provider = obj.provider
const ret = {
validate: false,
tooltip: null,
}
if (obj.brand !== BRAND_MAP.VMware.key && obj.brand !== BRAND_MAP.OneCloud.key) {
ret.tooltip = i18n.t('compute.text_473', [PROVIDER_MAP[provider].label])
return ret
}
if (obj.status !== 'suspend') {
ret.validate = false
ret.tooltip = i18n.t('compute.text_1131')
return ret
}
ret.validate = true
return ret
},
hidden: () => !(hasSetupKey(['vmware'])) || this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_resume'),
},
// 进入紧急模式
{
label: i18n.t('compute.start_rescue'),
permission: 'server_perform_start_rescue',
action: () => {
this.createDialog('VmStartRescueDialog', {
data: [obj],
columns: this.columns,
onManager: this.onManager,
refresh: this.refresh,
})
},
meta: () => {
const ret = { validate: true }
const provider = obj.provider
if (obj.brand !== BRAND_MAP.OneCloud.key) {
ret.validate = false
ret.tooltip = i18n.t('compute.text_473', [PROVIDER_MAP[provider].label])
return ret
}
if (obj.rescue_mode === true) {
ret.validate = false
ret.tooltip = i18n.t('compute.start_rescue.validate_tooltip')
return ret
}
return ret
},
hidden: () => !(hasSetupKey(['onecloud'])) || this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_start_rescue'),
},
// 退出紧急模式
{
label: i18n.t('compute.stop_rescue'),
permission: 'server_perform_stop_rescue',
action: () => {
this.createDialog('VmStopRescueDialog', {
data: [obj],
columns: this.columns,
onManager: this.onManager,
refresh: this.refresh,
})
},
meta: () => {
const ret = { validate: true }
const provider = obj.provider
if (obj.brand !== BRAND_MAP.OneCloud.key) {
ret.validate = false
ret.tooltip = i18n.t('compute.text_473', [PROVIDER_MAP[provider].label])
return ret
}
if (obj.rescue_mode !== true) {
ret.validate = false
ret.tooltip = i18n.t('compute.stop_rescue.validate_tooltip')
return ret
}
return ret
},
hidden: () => !(hasSetupKey(['onecloud'])) || this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_stop_rescue'),
},
// 推送配置
{
label: i18n.t('compute.sync_config'),
permission: 'server_perform_sync_config',
action: () => {
this.createDialog('VmSyncConfigDialog', {
data: [obj],
columns: this.columns,
onManager: this.onManager,
})
},
meta: () => {
const provider = obj.provider
const ret = {
validate: false,
tooltip: null,
}
if (obj.brand !== BRAND_MAP.OneCloud.key) {
ret.tooltip = i18n.t('compute.text_473', [PROVIDER_MAP[provider].label])
return ret
}
if (obj.status !== 'running' && obj.status !== 'ready') {
ret.validate = false
ret.tooltip = i18n.t('compute.text_1126')
return ret
}
ret.validate = true
return ret
},
hidden: () => !(hasSetupKey(['onecloud'])) || this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_sync_config'),
},
// VNC 截图
{
label: i18n.t('compute.vnc_panic_screenshot'),
permission: 'server_perform_screen_dump',
action: async () => {
try {
const res = await new this.$Manager('servers', 'v2').performAction({
id: obj.id,
action: 'screen-dump',
})
if (res.data?.screen_dump) {
this.createDialog('VmVncScreenshotDialog', {
data: obj,
screenshotUrl: res.data.screen_dump,
})
} else {
this.$message.error(this.$t('compute.get_screenshot_error'))
}
} catch (error) {
this.$message.error(this.$t('compute.get_screenshot_error'))
throw error
}
},
meta: (row) => {
const isOneCloud = row.brand === 'OneCloud'
const provider = obj.provider
if (!isOneCloud) {
return {
validate: false,
tooltip: i18n.t('compute.text_473', [PROVIDER_MAP[provider].label]),
}
}
return {
validate: obj.power_states === 'on',
tooltip: obj.power_states === 'on' ? '' : i18n.t('compute.power_states_check_tip', [i18n.t('common_239'), `【${i18n.t('compute.text_574')}】`]),
}
},
hidden: (row) => !(hasSetupKey(['onecloud'])) || this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_screen_dump'),
},
// 手动触发无人值守安装完成
{
label: i18n.t('compute.kickstart_complete'),
permission: 'server_perform_kickstart_complete',
action: () => {
this.createDialog('VmKickstartComplateDialog', {
data: [obj],
columns: this.columns,
onManager: this.onManager,
})
},
meta: () => {
const ret = {
validate: obj.status === 'kickstart_installing',
tooltip: obj.status !== 'kickstart_installing' ? '' : i18n.t('compute.kickstart_complete_tip'),
}
return ret
},
hidden: () => this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_kickstart_complete'),
},
],
},
// * 属性设置
{
label: i18n.t('compute.text_356'),
submenus: [
// 修改属性
{
label: i18n.t('compute.text_247'),
permission: 'server_update',
action: () => {
this.createDialog('VmUpdateDialog', {
data: [obj],
columns: this.columns,
onManager: this.onManager,
})
},
meta: (row) => {
const isOneCloud = row.brand === 'OneCloud'
const provider = obj.provider
const rescueModeValid = validateRescueMode(obj)
if (!rescueModeValid.validate) return rescueModeValid
return {
validate: isOneCloud,
tooltip: !isOneCloud && i18n.t('compute.text_473', [PROVIDER_MAP[provider].label]),
}
},
hidden: (row) => !(hasSetupKey(['onecloud'])) || this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_update'),
},
// 创建相同配置
{
label: i18n.t('compute.text_359'),
permission: 'server_create',
action: () => {
this.$openNewWindowForMenuHook('vminstance_configured_callback_address.create_same_configuration_callback_address', () => {
this.createDialog('VmCloneDialog', {
data: [obj],
columns: this.columns,
onManager: this.onManager,
})
})
},
meta: () => {
const ret = {
validate: false,
tooltip: null,
}
const rescueModeValid = validateRescueMode(obj)
if (!rescueModeValid.validate) return rescueModeValid
if (obj.is_prepaid_recycle) {
ret.tooltip = i18n.t('compute.text_285')
return ret
}
if (obj.brand !== BRAND_MAP.OneCloud.key &&
obj.hypervisor !== typeClouds.hypervisorMap.esxi.key &&
obj.hypervisor !== typeClouds.hypervisorMap.sangfor.key &&
findPlatform(obj.hypervisor) !== SERVER_TYPE.public) {
ret.tooltip = i18n.t('compute.text_473', [typeClouds.hypervisorMap[obj.hypervisor]?.label || ''])
return ret
}
ret.validate = true
return ret
},
hidden: () => !(hasSetupKey(['onecloud', 'public'])) || this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_create_same_config'),
},
// 更改项目
{
label: i18n.t('compute.perform_change_owner', [i18n.t('dictionary.project')]),
permission: 'server_perform_change_owner',
action: () => {
this.createDialog('ChangeOwenrDialog', {
data: [obj],
columns: this.columns,
onManager: this.onManager,
name: i18n.t('dictionary.server'),
resource: 'servers',
})
},
meta: () => {
const ret = {
validate: false,
tooltip: null,
}
const rescueModeValid = validateRescueMode(obj)
if (!rescueModeValid.validate) return rescueModeValid
if (!this.isAdminMode && !this.isDomainMode) {
ret.tooltip = i18n.t('compute.text_613')
return ret
}
if (commonUnabled(obj)) return ret
ret.validate = true
return ret
},
hidden: () => this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_change_owner'),
},
// 到期释放
{
label: i18n.t('compute.text_1132'),
permission: 'server_perform_cancel_expire',
action: () => {
this.createDialog('SetDurationDialog', {
data: [obj],
columns: this.columns,
onManager: this.onManager,
alert: i18n.t('compute.text_1391'),
refresh: this.refresh,
})
},
meta: () => {
const ret = {
validate: false,
tooltip: null,
}
const rescueModeValid = validateRescueMode(obj)
if (!rescueModeValid.validate) return rescueModeValid
if (obj.billing_type === 'prepaid') {
ret.tooltip = i18n.t('compute.text_285')
return ret
}
if (obj.hypervisor === typeClouds.hypervisorMap.bingocloud.key) {
ret.tooltip = i18n.t('compute.text_473', [typeClouds.hypervisorMap.bingocloud.label])
return ret
}
if (obj.hypervisor === typeClouds.hypervisorMap.sangfor.key) {
ret.tooltip = i18n.t('compute.text_473', [typeClouds.hypervisorMap.sangfor.label])
return ret
}
ret.validate = true
return ret
},
hidden: () => this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_cancel_expire'),
},
// 加入反亲和组
{
label: i18n.t('compute.text_1181', [i18n.t('dictionary.instancegroup')]),
permission: 'server_perform_bind_groups,server_perform_unbind_groups',
action: () => {
this.createDialog('VmBindInstanceGroupDialog', {
data: [obj],
columns: this.columns,
onManager: this.onManager,
refresh: this.refresh,
name: i18n.t('dictionary.server'),
})
},
meta: () => {
const provider = obj.provider
const ret = {
validate: false,
tooltip: null,
}
const rescueModeValid = validateRescueMode(obj)
if (!rescueModeValid.validate) return rescueModeValid
if (obj.brand !== BRAND_MAP.OneCloud.key) {
ret.tooltip = i18n.t('compute.text_473', [PROVIDER_MAP[provider].label])
return ret
}
if (!['running', 'ready'].includes(obj.status)) {
ret.tooltip = i18n.t('compute.text_1126')
return ret
}
if (obj.backup_host_id) {
ret.tooltip = i18n.t('compute.text_1283')
return ret
}
ret.validate = true
return ret
},
hidden: () => !(hasSetupKey(['onecloud'])) || this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_add_instancegroup'),
},
// 主机克隆
{
label: i18n.t('compute.text_1208'),
permission: 'server_perform_snapshot_and_clone',
action: () => {
this.$openNewWindowForMenuHook('vminstance_configured_callback_address.host_clone_callback_address', () => {
this.createDialog('VmCloneDeepDialog', {
data: [obj],
columns: this.columns,
onManager: this.onManager,
refresh: this.refresh,
})
})
},
meta: () => {
const provider = obj.provider
const ret = {
validate: false,
tooltip: null,
}
const rescueModeValid = validateRescueMode(obj)
if (!rescueModeValid.validate) return rescueModeValid
if (obj.brand !== BRAND_MAP.OneCloud.key) {
ret.tooltip = i18n.t('compute.text_473', [PROVIDER_MAP[provider].label])
return ret
}
if (!['running', 'ready'].includes(obj.status)) {
ret.tooltip = i18n.t('compute.text_1126')
return ret
}
if (obj.backup_host_id) {
ret.tooltip = i18n.t('compute.text_1283')
return ret
}
ret.validate = true
return ret
},
hidden: () => !(hasSetupKey(['onecloud'])) || this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_clone'),
},
// 续费
{
label: i18n.t('compute.text_1117'),
permission: 'server_perform_renew',
action: () => {
this.$openNewWindowForMenuHook('vminstance_configured_callback_address.renew_callback_address', () => {
this.createDialog('VmResourceFeeDialog', {
data: [obj],
columns: this.columns,
onManager: this.onManager,
})
})
},
meta: () => {
const ret = {
validate: false,
tooltip: null,
}
const rescueModeValid = validateRescueMode(obj)
if (!rescueModeValid.validate) return rescueModeValid
if (findPlatform(obj.hypervisor) !== SERVER_TYPE.public) {
ret.tooltip = i18n.t('compute.text_1118')
return ret
}
if (obj.billing_type !== 'prepaid') {
ret.tooltip = i18n.t('compute.text_1119')
return ret
}
ret.validate = true
return ret
},
hidden: () => !(hasSetupKey(['aliyun', 'qcloud', 'huawei', 'ucloud', 'ecloud', 'jdcloud'])) || this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_Renew'),
},
// 自动续费设置
{
label: i18n.t('compute.text_1120'),
permission: 'server_perform_aet_auto_renew',
action: () => {
this.createDialog('VmResourceRenewFeeDialog', {
data: [obj],
columns: this.columns,
onManager: this.onManager,
refresh: this.refresh,
})
},
meta: () => {
const ret = {
validate: false,
tooltip: null,
}
const rescueModeValid = validateRescueMode(obj)
if (!rescueModeValid.validate) return rescueModeValid
if (findPlatform(obj.hypervisor) !== SERVER_TYPE.public) {
ret.tooltip = i18n.t('compute.text_1118')
return ret
}
if (obj.billing_type !== 'prepaid') {
ret.tooltip = i18n.t('compute.text_1119')
return ret
}
ret.validate = true
return ret
},
hidden: () => !(hasSetupKey(['aliyun', 'qcloud', 'huawei', 'ucloud', 'ecloud', 'jdcloud', 'ctyun'])) || this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_auto_renewal'),
},
// 更改计费模式
{
label: i18n.t('compute.change_billing_type'),
permission: 'server_perform_change_billing_type',
action: () => {
this.createDialog('VmChangeBillingTypeDialog', {
steadyStatus: ['running', 'ready'],
data: [obj],
columns: this.columns,
onManager: this.onManager,
refresh: this.refresh,
})
},
meta: () => {
const ret = {
validate: false,
tooltip: null,
}
const rescueModeValid = validateRescueMode(obj)
if (!rescueModeValid.validate) return rescueModeValid
if (obj.brand !== BRAND_MAP.Aliyun.key && obj.brand !== BRAND_MAP.Qcloud.key) {
ret.tooltip = i18n.t('compute.text_473', [PROVIDER_MAP[obj.provider].label])
return ret
}
ret.validate = true
return ret
},
hidden: () => !(hasSetupKey(['aliyun', 'qcloud'])) || this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_change_billing_type'),
},
],
},
// * 配置修改
{
label: i18n.t('compute.group_action.update_config'),
submenus: [
// 重装系统
{
label: i18n.t('compute.text_357'),
permission: 'server_perform_rebuild_root',
action: () => {
this.createDialog('VmRebuildRootDialog', {
data: [obj],
columns: this.columns,
onManager: this.onManager,
})
},
meta: () => {
const ret = {
validate: false,
tooltip: null,
}
const rescueModeValid = validateRescueMode(obj)
if (!rescueModeValid.validate) return rescueModeValid
if (obj.shutdown_mode === 'stop_charging' && obj.status === 'ready') {
ret.validate = false
ret.tooltip = i18n.t('compute.server.shutdown_mode.tooltip')
return ret
}
if (commonUnabled(obj)) return ret
ret.validate = cloudEnabled('rebuildRoot', obj)
ret.tooltip = cloudUnabledTip('rebuildRoot', obj)
return ret
},
hidden: () => this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_rebuild_root'),
},
// 调整配置
{
label: i18n.t('compute.text_1100'),
permission: 'server_perform_change_config',
action: () => {
this.$openNewWindowForMenuHook('vminstance_configured_callback_address.adjust_configuration_callback_address', () => {
this.$router.push({
name: 'VMInstanceAdjustConfig',
query: {
id: obj.id,
},
})
})
},
meta: () => {
const ret = {
validate: false,
tooltip: null,
}
const rescueModeValid = validateRescueMode(obj)
if (!rescueModeValid.validate) return rescueModeValid
if (obj.backup_host_id) {
ret.tooltip = i18n.t('compute.text_1111')
return ret
}
if (obj.os_arch === HOST_CPU_ARCHS.arm.key && obj.status === 'running') {
ret.tooltip = i18n.t('compute.text_1371')
return ret
}
if (obj.shutdown_mode === 'stop_charging' && obj.status === 'ready') {
ret.validate = false
ret.tooltip = i18n.t('compute.server.shutdown_mode.tooltip')
return ret
}
if (commonUnabled(obj)) return ret
ret.validate = cloudEnabled('adjustConfig', obj)
ret.tooltip = cloudUnabledTip('adjustConfig', obj)
return ret
},
hidden: () => this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_change_config'),
},
// 设置GPU卡
{
label: i18n.t('compute.text_1112'),
permission: 'server_perform_set_isolated_device,attach-isolated-device,server_perform_detach_isolated_device',
action: () => {
this.createDialog('VmAttachGpuDialog', {
data: [obj],
columns: this.columns,
onManager: this.onManager,
})
},
meta: () => {
const provider = obj.provider
const ret = {
validate: false,
tooltip: null,
}
const rescueModeValid = validateRescueMode(obj)
if (!rescueModeValid.validate) return rescueModeValid
if (!this.isAdminMode && !this.isDomainMode) {
ret.tooltip = i18n.t('compute.text_1279', [i18n.t('dictionary.domain')])
return ret
}
if (findPlatform(obj.hypervisor, 'hypervisor') !== SERVER_TYPE.idc) {
ret.tooltip = i18n.t('compute.text_473', [PROVIDER_MAP[provider].label])
return ret
}
ret.validate = cloudEnabled('acttachGpu', obj)
ret.tooltip = cloudUnabledTip('acttachGpu', obj)
return ret
},
hidden: () => !(hasSetupKey(['onecloud'])) || this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_set_gpu'),
},
// 设置USB透传
{
label: i18n.t('compute.text_1399'),
permission: 'server_perform_set_isolated_device,attach-isolated-device,server_perform_detach_isolated_device',
action: () => {
this.createDialog('VmAttachUsbDialog', {
data: [obj],
columns: this.columns,
onManager: this.onManager,
})
},
meta: () => {
const provider = obj.provider
const ret = {
validate: false,
tooltip: null,
}
const rescueModeValid = validateRescueMode(obj)
if (!rescueModeValid.validate) return rescueModeValid
if (!this.isAdminMode && !this.isDomainMode) {
ret.tooltip = i18n.t('compute.text_1279', [i18n.t('dictionary.domain')])
return ret
}
if (findPlatform(obj.hypervisor, 'hypervisor') !== SERVER_TYPE.idc) {
ret.tooltip = i18n.t('compute.text_473', [PROVIDER_MAP[provider].label])
return ret
}
ret.validate = cloudEnabled('acttachUsb', obj)
ret.tooltip = cloudUnabledTip('acttachUsb', obj)
return ret
},
hidden: () => !(hasSetupKey(['onecloud'])) || this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_set_usb'),
},
// 修改启动顺序
{
label: i18n.t('compute.change_boot_index'),
permission: 'server_perform_set_boot_index',
action: () => {
this.createDialog('VmChangeBootIndexDialog', {
data: [obj],
columns: this.columns,
onManager: this.onManager,
})
},
meta: (row) => {
const isOneCloud = row.brand === 'OneCloud'
const provider = obj.provider
const rescueModeValid = validateRescueMode(obj)
if (!rescueModeValid.validate) return rescueModeValid
return {
validate: isOneCloud,
tooltip: !isOneCloud && i18n.t('compute.text_473', [PROVIDER_MAP[provider].label]),
}
},
hidden: (row) => !(hasSetupKey(['onecloud'])) || this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_set_boot_index'),
},
// 更换块存储
{
label: i18n.t('compute.vminstance.change_disk_storage'),
permission: 'server_perform_change_storage',
action: () => {
this.createDialog('VmChangeBlockStorageDialog', {
data: [obj],
columns: this.columns,
onManager: this.onManager,
refresh: this.refresh,
})
},
meta: () => {
const provider = obj.provider
const ret = {
validate: true,
}
const rescueModeValid = validateRescueMode(obj)
if (!rescueModeValid.validate) return rescueModeValid
if (obj.brand !== BRAND_MAP.OneCloud.key) {
ret.validate = false
ret.tooltip = i18n.t('compute.text_473', [PROVIDER_MAP[provider].label])
return ret
}
return {
validate: cloudEnabled('changeBlockStorage', obj),
tooltip: cloudUnabledTip('changeBlockStorage', obj),
}
},
hidden: () => !hasSetupKey(['onecloud']) || this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_change_disk_storage'),
},
// 绑定物理CPU
{
label: i18n.t('compute.bind_physical_cpu'),
permission: 'server_perform_cpuset',
action: () => {
this.createDialog('BindPhysicalCpuDialog', {
data: [obj],
columns: this.columns,
onManager: this.onManager,
alert: i18n.t('compute.text_1391'),
refresh: this.refresh,
})
},
meta: () => {
const ret = {
validate: false,
tooltip: null,
}
const rescueModeValid = validateRescueMode(obj)
if (!rescueModeValid.validate) return rescueModeValid
if (obj.brand !== BRAND_MAP.OneCloud.key) {
ret.tooltip = i18n.t('compute.text_473', [PROVIDER_MAP[obj.provider].label])
return ret
}
return {
...ret,
validate: true,
}
},
hidden: () => !hasSetupKey(['onecloud']) || this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_cpuset_cores'),
},
// 设置磁盘速度
{
label: i18n.t('compute.text_1249'),
permission: 'server_perform_io_throttle',
action: () => {
this.createDialog('VmSetSpeedDialog', {
data: [obj],
columns: this.columns,
onManager: this.onManager,
})
},
meta: () => {
const provider = obj.provider
const ret = {
validate: false,
tooltip: null,
}
const rescueModeValid = validateRescueMode(obj)
if (!rescueModeValid.validate) return rescueModeValid
if (obj.brand !== BRAND_MAP.OneCloud.key) {
ret.tooltip = i18n.t('compute.text_473', [PROVIDER_MAP[provider].label])
return ret
}
if (obj.status !== 'running') {
ret.tooltip = i18n.t('compute.text_1282')
return ret
}
ret.validate = true
return ret
},
hidden: () => !(hasSetupKey(['onecloud'])) || this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_set_disk_speed'),
},
],
},
// * 密码密钥
{
label: i18n.t('compute.text_360'),
submenus: [
// 重置密码
{
label: i18n.t('compute.text_276'),
permission: 'server_perform_set_password',
action: () => {
this.createDialog('VmResetPasswordDialog', {
data: [obj],
columns: this.columns,
onManager: this.onManager,
})
},
meta: () => {
const ret = {
validate: false,
tooltip: null,
}
const rescueModeValid = validateRescueMode(obj)
if (!rescueModeValid.validate) return rescueModeValid
if (commonUnabled(obj)) return ret
if (obj.keypair_id && obj.keypair_id.toLowerCase() !== 'none') {
ret.tooltip = i18n.t('compute.text_277')
return ret
}
ret.validate = cloudEnabled('resetPassword', obj)
ret.tooltip = cloudUnabledTip('resetPassword', obj)
return ret
},
hidden: () => this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_reset_password'),
},
// 绑定密钥
{
label: i18n.t('compute.text_361'),
permission: 'server_perform_deploy',
action: () => {
this.createDialog('VmBindKeypairDialog', {
data: [obj],
columns: this.columns,
onManager: this.onManager,
})
},
meta: () => {
const ret = {
validate: false,
tooltip: null,
}
const rescueModeValid = validateRescueMode(obj)
if (!rescueModeValid.validate) return rescueModeValid
if (obj.hypervisor === typeClouds.hypervisorMap.openstack.key) {
ret.tooltip = i18n.t('compute.text_1284')
return ret
}
if (obj.os_type === 'Windows') {
ret.tooltip = i18n.t('compute.text_1285')
return ret
}
const osType = obj.metadata && obj.metadata.os_name
if (['aws', 'azure', 'google', 'aliyun', 'ksyun'].includes(obj.hypervisor) && osType === 'Windows') {
ret.tooltip = i18n.t('compute.text_1285')
return ret
}
if (commonUnabled(obj)) return ret
if (obj.keypair) {
ret.tooltip = i18n.t('compute.text_363')
return ret
}
ret.validate = cloudEnabled('bindKeyPair', obj)
ret.tooltip = cloudUnabledTip('bindKeyPair', obj)
return ret
},
hidden: () => this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_bind_key'),
},
// 解绑密钥
{
label: i18n.t('compute.text_364'),
permission: 'server_perform_deploy',
action: () => {
this.createDialog('VmUnbindKeypairDialog', {
data: [obj],
columns: this.columns,
onManager: this.onManager,
})
},
meta: () => {
const ret = {
validate: false,
tooltip: null,
}
const rescueModeValid = validateRescueMode(obj)
if (!rescueModeValid.validate) return rescueModeValid
if (commonUnabled(obj)) return ret
if (!obj.keypair) {
ret.tooltip = i18n.t('compute.text_365')
return ret
}
ret.validate = cloudEnabled('unBindKeyPair', obj)
ret.tooltip = cloudUnabledTip('unBindKeyPair', obj)
return ret
},
hidden: () => this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_unbind_key'),
},
// 设置免密登录
{
label: i18n.t('compute.vminstance.actions.setup_ssh_authentication'),
permission: 'server_perform_setup_ssh_proxy',
action: () => {
this.createDialog('SetupSSHDialog', {
data: [obj],
columns: this.columns,
onManager: this.onManager,
})
},
meta: () => {
const ret = {
validate: true,
tooltip: null,
}
if (obj.hypervisor === typeClouds.hypervisorMap.sangfor.key) {
ret.validate = false
ret.tooltip = i18n.t('compute.text_473', [typeClouds.hypervisorMap.sangfor.label])
return ret
}
const rescueModeValid = validateRescueMode(obj)
if (!rescueModeValid.validate) return rescueModeValid
const isLinux = obj.os_type && obj.os_type.toLowerCase() === 'linux'
if (!isLinux) {
ret.validate = false
ret.tooltip = i18n.t('compute.text_362')
return ret
}
if (!commonEnabled(obj, ['running'])) {
ret.validate = false
ret.tooltip = i18n.t('db.text_156')
return ret
}
return ret
},
hidden: () => this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_setup_ssh_proxy'),
},
// 探测免密登录
{
label: i18n.t('compute.vminstance.actions.detect_ssh_authentication'),
permission: 'server_perform_make_sshable',
action: () => {
this.createDialog('DetectSSHDialog', {
data: [obj],
columns: this.columns,
onManager: this.onManager,
})
},
meta: () => {
const ret = {
validate: true,
tooltip: null,
}
if (obj.hypervisor === typeClouds.hypervisorMap.sangfor.key) {
ret.validate = false
ret.tooltip = i18n.t('compute.text_473', [typeClouds.hypervisorMap.sangfor.label])
return ret
}
const rescueModeValid = validateRescueMode(obj)
if (!rescueModeValid.validate) return rescueModeValid
if (!commonEnabled(obj, ['running'])) {
ret.validate = false
ret.tooltip = i18n.t('db.text_156')
return ret
}
return ret
},
hidden: () => this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_detect_ssh_proxy'),
},
],
},
// * 镜像与备份
{
label: i18n.t('compute.group_action.mirror_backup'),
submenus: [
// 保存镜像
{
label: i18n.t('compute.text_1236'),
permission: 'server_perform_save_image',
action: () => {
this.createDialog('VmSaveImageDialog', {
data: [obj],
columns: this.columns,
onManager: this.onManager,
})
},
meta: () => {
const ret = {
validate: false,
tooltip: null,
}
const rescueModeValid = validateRescueMode(obj)
if (!rescueModeValid.validate) return rescueModeValid
// if (findPlatform(obj.hypervisor) === SERVER_TYPE.public) {
// ret.tooltip = i18n.t('compute.text_1286')
// return ret
// }
const noSupportBrand = [
typeClouds.hypervisorMap.openstack?.brand,
typeClouds.hypervisorMap.zstack?.brand,
// typeClouds.hypervisorMap.dstack?.brand,
typeClouds.hypervisorMap.ucloud?.brand,
typeClouds.hypervisorMap.ctyun?.brand,
typeClouds.hypervisorMap.nutanix?.brand,
typeClouds.hypervisorMap.proxmox?.brand,
typeClouds.hypervisorMap.sangfor?.brand,
]
if (noSupportBrand.includes(obj.brand)) {
ret.tooltip = i18n.t('compute.text_1287', [obj.brand])
return ret
}
if (commonUnabled(obj)) return ret
ret.validate = commonEnabled(obj)
ret.tooltip = commonTip(obj)
return ret
},
hidden: () => this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_save_image'),
},
// 挂载ISO
{
label: i18n.t('compute.text_366'),
permission: 'server_perform_insertiso',
action: () => {
this.createDialog('VmMountIsoDialog', {
data: [obj],
columns: this.columns,
onManager: this.onManager,
refresh: this.refresh,
})
},
meta: () => {
const provider = obj.provider
const ret = {
validate: false,
tooltip: null,
}
const rescueModeValid = validateRescueMode(obj)
if (!rescueModeValid.validate) return rescueModeValid
if (obj.hypervisor === typeClouds.hypervisorMap.esxi.key) {
ret.tooltip = i18n.t('compute.text_473', [PROVIDER_MAP[provider].label])
return ret
}
if (findPlatform(obj.hypervisor) === SERVER_TYPE.public) {
ret.tooltip = i18n.t('compute.text_473', [PROVIDER_MAP[provider].label])
return ret
}
if (obj.hypervisor === typeClouds.hypervisorMap.sangfor.key) {
ret.tooltip = i18n.t('compute.text_473', [typeClouds.hypervisorMap.sangfor.label])
return ret
}
if (commonUnabled(obj)) return ret
if (obj.cdrom) {
ret.tooltip = i18n.t('compute.text_1288')
return ret
}
ret.validate = cloudEnabled('insertiso', obj)
ret.tooltip = cloudUnabledTip('insertiso', obj)
return ret
},
hidden: () => !(hasSetupKey(['vmware', 'onecloud'])) || this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_mount_iso'),
},
// 卸载ISO
{
label: i18n.t('compute.text_367'),
permission: 'server_perform_ejectiso',
action: () => {
this.createDialog('VmUnmountIsoDialog', {
data: [obj],
columns: this.columns,
onManager: this.onManager,
refresh: this.refresh,
})
},
meta: () => {
const provider = obj.provider
const ret = {
validate: false,
tooltip: null,
}
const rescueModeValid = validateRescueMode(obj)
if (!rescueModeValid.validate) return rescueModeValid
if (obj.hypervisor === typeClouds.hypervisorMap.esxi.key) {
ret.tooltip = i18n.t('compute.text_473', [PROVIDER_MAP[provider].label])
return ret
}
if (findPlatform(obj.hypervisor) === SERVER_TYPE.public) {
ret.tooltip = i18n.t('compute.text_473', [PROVIDER_MAP[provider].label])
return ret
}
if (obj.hypervisor === typeClouds.hypervisorMap.sangfor.key) {
ret.tooltip = i18n.t('compute.text_473', [typeClouds.hypervisorMap.sangfor.label])
return ret
}
if (commonUnabled(obj)) return ret
if (!obj.cdrom) {
ret.tooltip = i18n.t('compute.text_1289')
return ret
}
ret.validate = cloudEnabled('ejectiso', obj)
ret.tooltip = cloudUnabledTip('ejectiso', obj)
return ret
},
hidden: () => !(hasSetupKey(['vmware', 'onecloud'])) || this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_unmount_iso'),
},
// 创建快照
{
label: i18n.t('compute.text_1276'),
permission: 'snapshots_create,server_perform_instance_backup',
action: () => {
this.$openNewWindowForMenuHook('vminstance_configured_callback_address.create_snapshot_callback_address', () => {
this.createDialog('VmSnapshotCreateDialog', {
data: [obj],
columns: this.columns,
onManager: this.onManager,
refresh: this.refresh,
})
})
},
meta: () => {
const ret = {
validate: false,
tooltip: null,
}
const rescueModeValid = validateRescueMode(obj)
if (!rescueModeValid.validate) return rescueModeValid
if (obj.is_prepaid_recycle) {
ret.tooltip = i18n.t('compute.text_285')
return ret
}
if (obj.backup_host_id) {
ret.tooltip = i18n.t('compute.text_1277')
return ret
}
if (commonUnabled(obj)) return ret
ret.validate = cloudEnabled('createSnapshot', obj)
ret.tooltip = cloudUnabledTip('createSnapshot', obj)
return ret
},
hidden: () => this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_create_snapshot'),
},
// 创建备份
{
label: i18n.t('compute.create_disk_backup2'),
permission: 'server_perform_instance_backup,diskbackups_create,instancebackups_create',
action: () => {
this.createDialog('VmBackupCreateDialog', {
data: [obj],
columns: this.columns,
onManager: this.onManager,
refresh: this.refresh,
})
},
meta: () => {
const ret = {
validate: false,
tooltip: null,
}
const rescueModeValid = validateRescueMode(obj)
if (!rescueModeValid.validate) return rescueModeValid
if (obj.is_prepaid_recycle) {
ret.tooltip = i18n.t('compute.text_285')
return ret
}
if (obj.backup_host_id) {
ret.tooltip = i18n.t('compute.text_1277')
return ret
}
if (commonUnabled(obj)) return ret
ret.validate = cloudEnabled('createBackup', obj)
ret.tooltip = cloudUnabledTip('createBackup', obj)
return ret
},
hidden: () => !hasSetupKey(['onecloud']) || this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_create_backup'),
},
],
},
// * 网络与安全
{
label: i18n.t('compute.text_1290'),
submenus: [
// 关联安全组
{
label: i18n.t('compute.text_1116'),
permissionLabels: [i18n.t('compute.text_1116'), i18n.t('compute.revoke_secgroup'), i18n.t('compute.set_secgroup')],
permission: 'server_perform_add_secgroup,server_perform_revoke_secgroup,server_perform_set_secgroup',
action: () => {
this.createDialog('VmSetSecgroupDialog', {
vm: this,
data: [obj],
columns: this.columns,
onManager: this.onManager,
refresh: this.refresh,
type: 'vminstance',
})
},
meta: () => {
const rescueModeValid = validateRescueMode(obj)
if (!rescueModeValid.validate) return rescueModeValid
const ret = {
validate: cloudEnabled('assignSecgroup', obj),
tooltip: cloudUnabledTip('assignSecgroup', obj),
}
return ret
},
hidden: () => !(hasSetupKey(['onestack', 'onecloud', 'public', 'openstack', 'dstack', 'zstack', 'apsara', 'cloudpods', 'hcso', 'hcs'])) || this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_add_secgroup'),
},
// 绑定eip
{
label: i18n.t('compute.text_1179'),
permission: 'server_perform_create_eip',
action: () => {
this.createDialog('VmBindEipDialog', {
data: [obj],
columns: this.columns,
refresh: this.refresh,
onManager: this.onManager,
})
},
meta: () => {
const ret = {
validate: false,
tooltip: null,
}
const rescueModeValid = validateRescueMode(obj)
if (!rescueModeValid.validate) return rescueModeValid
if (commonUnabled(obj)) return ret
if (obj.eip_mode === 'public_ip' && obj.hypervisor !== 'aws') {
ret.tooltip = i18n.t('compute.public_ip_tooltip')
return ret
}
if (obj.eip_mode !== 'public_ip' && obj.eip) {
ret.tooltip = i18n.t('compute.text_1291')
return ret
}
if (obj.brand === 'OneCloud' && obj.vpc_id === 'default') {
ret.tooltip = i18n.t('compute.text_1292')
return ret
}
if (obj.vpc_external_access_mode === 'none') {
ret.tooltip = i18n.t('compute.disable_bind_eip')
return ret
}
ret.validate = cloudEnabled('bindEip', obj)
ret.tooltip = cloudUnabledTip('bindEip', obj)
return ret
},
hidden: () => !(hasSetupKey(['onestack', 'onecloud', 'public', 'openstack', 'dstack', 'zstack', 'apsara', 'cloudpods', 'hcso', 'hcs'])) || this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_bind_elastic_public_ip'),
},
// 解绑eip
{
label: i18n.t('compute.text_1264'),
permission: 'server_perform_dissociate_eip',
action: () => {
this.createDialog('VmUnbindEipDialog', {
data: [obj],
columns: this.columns,
onManager: this.onManager,
refresh: this.refresh,
})
},
meta: () => {
const ret = {
validate: false,
tooltip: null,
}
const rescueModeValid = validateRescueMode(obj)
if (!rescueModeValid.validate) return rescueModeValid
if (commonUnabled(obj)) return ret
if (obj.eip_mode !== 'elastic_ip') {
ret.tooltip = i18n.t('compute.text_1293')
return ret
}
if (obj.eip_mode === 'public_ip') {
ret.tooltip = i18n.t('compute.text_1294')
return ret
}
ret.validate = cloudEnabled('unbindEip', obj)
ret.tooltip = cloudUnabledTip('unbindEip', obj)
return ret
},
hidden: () => !(hasSetupKey(['onestack', 'onecloud', 'public', 'openstack', 'dstack', 'zstack', 'apsara', 'cloudpods', 'hcso', 'hcs'])) || this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_unbind_elastic_public_ip'),
},
// 公网IP转EIP
{
label: i18n.t('compute.text_1121'),
permission: 'server_perform_publicip_to_eip',
action: () => {
this.createDialog('VmPublicIpToEipDialog', {
data: [obj],
columns: this.columns,
onManager: this.onManager,
refresh: this.refresh,
})
},
meta: () => {
const ret = {
validate: false,
tooltip: null,
}
const rescueModeValid = validateRescueMode(obj)
if (!rescueModeValid.validate) return rescueModeValid
if (obj.eip && obj.eip_mode === 'elastic_ip') {
ret.tooltip = i18n.t('compute.text_1122')
return ret
}
if (obj.eip_mode !== 'public_ip') {
ret.tooltip = i18n.t('compute.text_1123')
return ret
}
ret.validate = cloudEnabled('publicIpToEip', obj)
ret.tooltip = cloudUnabledTip('publicIpToEip', obj)
return ret
},
hidden: () => !(hasSetupKey(['aliyun', 'qcloud'])) || this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_public_ip_to_eip'),
},
// 设置源/目标检查
{
label: i18n.t('compute.text_1124'),
permission: 'server_perform_modify_src_check',
action: () => {
this.createDialog('VmSourceTargetCheckDialog', {
data: [obj],
columns: this.columns,
onManager: this.onManager,
refresh: this.refresh,
})
},
meta: () => {
const provider = obj.provider
const ret = { validate: true, tooltip: null }
const rescueModeValid = validateRescueMode(obj)
if (!rescueModeValid.validate) return rescueModeValid
if (obj.brand !== BRAND_MAP.OneCloud.key) {
ret.validate = false
ret.tooltip = i18n.t('compute.text_473', [PROVIDER_MAP[provider].label])
return ret
}
if (!['running', 'ready'].includes(obj.status)) {
ret.validate = false
ret.tooltip = i18n.t('compute.text_1126')
return ret
}
return ret
},
hidden: () => !(hasSetupKey(['onecloud'])) || this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_set_source_check'),
},
{
label: i18n.t('compute.add_to_bastion'),
permission: 'bastion_servers_create',
action: () => {
this.createDialog('VmAddToBastionDialog', {
data: [obj],
columns: this.columns,
onManager: this.onManager,
refresh: this.refresh,
})
},
meta: (obj) => {
const ret = { validate: true }
if (obj.metadata?.bastion_server) {
ret.validate = false
ret.tooltip = i18n.t('compute.already_in_bastion')
return ret
}
if (obj.status !== 'running') {
ret.validate = false
ret.tooltip = i18n.t('compute.text_1282')
return ret
}
return validateRescueMode(obj)
},
hidden: () => {
if (!this.$appConfig.isPrivate || this.$store.getters.isSysCE || this.$isScopedPolicyMenuHidden('sub_hidden_menus.bastion_host') || (isLicense2() && !hasSetupKey('bastionhost')) || !hasBastionService) {
return true
}
return false
},
},
{
label: i18n.t('compute.remove_from_bastion'),
permission: 'bastion_servers_delete',
action: () => {
this.createDialog('VmRemoveFromBastionDialog', {
data: [obj],
columns: this.columns,
onManager: this.onManager,
refresh: this.refresh,
})
},
meta: (obj) => {
const ret = { validate: true }
if (!obj.metadata?.bastion_server) {
ret.validate = false
return ret
}
if (!['running', 'ready'].includes(obj.status)) {
ret.validate = false
ret.tooltip = i18n.t('compute.text_1126')
return ret
}
return ret
},
hidden: () => {
if (!this.$appConfig.isPrivate || this.$store.getters.isSysCE || this.$isScopedPolicyMenuHidden('sub_hidden_menus.bastion_host') || (isLicense2() && !hasSetupKey('bastionhost')) || !hasBastionService) {
return true
}
return false
},
},
],
},
// * 高可用
{
label: i18n.t('compute.text_1295'),
submenus: [
// 添加备份机
{
label: i18n.t('compute.text_1162'),
permission: 'server_perform_create_backup',
action: () => {
this.createDialog('VmAddBackupDialog', {
data: [obj],
columns: this.columns,
onManager: this.onManager,
})
},
meta: () => {
const provider = obj.provider
const ret = {
validate: false,
tooltip: null,
}
const rescueModeValid = validateRescueMode(obj)
if (!rescueModeValid.validate) return rescueModeValid
if (obj.brand !== BRAND_MAP.OneCloud.key) {
ret.tooltip = i18n.t('compute.text_473', [PROVIDER_MAP[provider].label])
return ret
}
if (!['ready'].includes(obj.status)) {
ret.tooltip = i18n.t('compute.text_1308')
return ret
}
if (obj.backup_host_id) {
ret.tooltip = i18n.t('compute.text_1296')
return ret
}
if (obj.is_gpu) {
ret.tooltip = i18n.t('compute.gpu_not_support_add_host')
return ret
}
if (!this.isAdminMode && !this.isDomainMode) {
ret.tooltip = i18n.t('migration.project.error')
return ret
}
const isLvm = obj.disks_info.some(item => item.storage_type.includes('lvm'))
if (isLvm) {
ret.tooltip = i18n.t('compute.lvm_shared_storage.validate_tooltip')
return ret
}
ret.validate = true
return ret
},
hidden: () => !(hasSetupKey(['onecloud'])) || this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_add_backup'),
},
// 删除备份机
{
label: i18n.t('compute.text_1209'),
permission: 'server_perform_delete_backup',
action: () => {
this.createDialog('VmDeleteBackupDialog', {
data: [obj],
columns: this.columns,
onManager: this.onManager,
})
},
meta: () => {
const provider = obj.provider
const ret = {
validate: false,
tooltip: null,
}
const rescueModeValid = validateRescueMode(obj)
if (!rescueModeValid.validate) return rescueModeValid
if (!obj.backup_host_id) {
ret.tooltip = i18n.t('compute.text_1383')
return ret
}
if (obj.brand !== BRAND_MAP.OneCloud.key) {
ret.tooltip = i18n.t('compute.text_473', [PROVIDER_MAP[provider].label])
return ret
}
if (!this.isAdminMode && !this.isDomainMode) {
ret.tooltip = i18n.t('migration.project.error')
return ret
}
ret.validate = true
return ret
},
hidden: () => !(hasSetupKey(['onecloud'])) || this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_delete_backup'),
},
// 迁移
{
label: i18n.t('compute.text_1127'),
permission: 'server_perform_migrate,server_perform_live_migrate',
action: () => {
this.createDialog('VmTransferDialog', {
data: [obj],
columns: this.columns,
onManager: this.onManager,
})
},
meta: () => {
const ret = { validate: true, tooltip: null }
const rescueModeValid = validateRescueMode(obj)
if (!rescueModeValid.validate) return rescueModeValid
if (!this.isAdminMode && !this.isDomainMode) {
ret.validate = false
ret.tooltip = this.$t('compute.tooltip.check_domain_permission')
return ret
}
if (!['running', 'ready'].includes(obj.status)) {
ret.validate = false
ret.tooltip = this.$t('compute.tooltip.check_status_transfer')
return ret
}
if (obj.backup_host_id) {
ret.validate = false
ret.tooltip = this.$t('compute.tooltip.check_backup_host_transfer')
return ret
}
if (obj.is_gpu) {
ret.validate = false
ret.tooltip = this.$t('compute.tooltip.check_gpu_transfer')
return ret
}
if (obj.cdrom) {
ret.validate = false
ret.tooltip = this.$t('compute.tooltip.check_cdrom_transfer')
return ret
}
ret.validate = cloudEnabled('transfer', obj)
ret.tooltip = cloudUnabledTip('transfer', obj)
return ret
},
hidden: () => !(hasSetupKey(['openstack', 'onecloud', 'vmware'])) || this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_transfer'),
},
// V2V迁移
{
label: i18n.t('compute.v2vtransfer.label'),
permission: 'server_perform_migrate',
action: () => {
this.createDialog('VmV2vTransferDialog', {
data: [obj],
columns: this.columns,
onManager: this.onManager,
successCallback: this.refresh,
})
},
meta: () => {
const ret = { validate: true, tooltip: null }
const rescueModeValid = validateRescueMode(obj)
if (!rescueModeValid.validate) return rescueModeValid
if (!this.isAdminMode && !this.isDomainMode) {
ret.validate = false
ret.tooltip = this.$t('compute.tooltip.check_domain_permission')
return ret
}
if (![BRAND_MAP.Cloudpods.key, BRAND_MAP.VMware.key].includes(obj.brand)) {
ret.validate = false
ret.tooltip = i18n.t('compute.brand_support', [`${BRAND_MAP.Cloudpods.label},${BRAND_MAP.VMware.label}`])
return ret
}
if (!['ready'].includes(obj.status)) {
ret.validate = false
ret.tooltip = this.$t('compute.tooltip.check_ready_status_transfer')
return ret
}
if (obj.backup_host_id) {
ret.validate = false
ret.tooltip = this.$t('compute.tooltip.check_backup_host_transfer')
return ret
}
if (!obj.ips) {
ret.validate = false
ret.tooltip = this.$t('compute.fill_ip_tooltip')
return ret
}
ret.validate = cloudEnabled('v2vTransfer', obj)
ret.tooltip = cloudUnabledTip('v2vTransfer', obj)
return ret
},
hidden: () => !(hasSetupKey(['vmware'])) || this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_transfer'),
},
// 快速恢复
{
label: i18n.t('compute.server.quick.recovery'),
action: () => {
this.createDialog('VmQuickRecoveryDialog', {
data: [obj],
columns: this.columns,
onManager: this.onManager,
})
},
meta: () => {
const ret = {
validate: true,
tooltip: '',
}
const rescueModeValid = validateRescueMode(obj)
if (!rescueModeValid.validate) return rescueModeValid
if (obj.brand !== BRAND_MAP.OneCloud.key) {
ret.validate = false
ret.tooltip = i18n.t('compute.text_473', [PROVIDER_MAP[obj.provider].label])
return ret
}
if (obj.host_service_status !== 'offline') {
ret.validate = false
ret.tooltip = i18n.t('compute.quick.recovery.validate.host_status_tooltip')
return ret
}
const isAllKVMShareStorages = obj.disks_info.every(item => KVM_SHARE_STORAGES.includes(item.storage_type))
if (!isAllKVMShareStorages) {
ret.validate = false
ret.tooltip = i18n.t('compute.quick.recovery.validate.host_status_tooltip')
return ret
}
return ret
},
hidden: () => !hasSetupKey(['onecloud']) || this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_migrate'),
},
],
},
// * 删除
{
label: i18n.t('compute.perform_delete'),
submenus: [
// 设置删除保护
disableDeleteAction(Object.assign(this, {
permission: 'server_update',
}), {
name: i18n.t('dictionary.server'),
meta: () => {
const ret = { validate: true }
if (obj.hypervisor === typeClouds.hypervisorMap.bingocloud.key) {
ret.tooltip = i18n.t('compute.text_473', [typeClouds.hypervisorMap.bingocloud.label])
ret.validate = false
return ret
}
return ret
},
hidden: () => this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_set_delete_protection'),
}),
// 删除
{
label: i18n.t('compute.perform_delete'),
permission: 'server_delete',
action: () => {
this.$openNewWindowForMenuHook('vminstance_configured_callback_address.delete_callback_address', () => {
this.createDialog('DeleteVmDialog', {
vm: this,
data: [obj],
columns: this.columns,
onManager: this.onManager,
title: i18n.t('compute.perform_delete'),
success: () => {
this.destroySidePages()
},
})
})
},
meta: () => {
const ret = { validate: false }
if (obj.hypervisor === typeClouds.hypervisorMap.bingocloud.key) {
ret.tooltip = i18n.t('compute.text_473', [typeClouds.hypervisorMap.bingocloud.label])
return ret
}
const { server_delete_limit = false } = this.$store.getters.globalSetting.value || {}
if (server_delete_limit && obj.status === 'running') {
ret.tooltip = i18n.t('compute.delete_limit')
return ret
}
return this.$getDeleteResult(obj)
},
hidden: () => this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_delete'),
},
],
},
]
},
meta: (obj) => {
let ret = {
validate: true,
tooltip: null,
}
ret = this.$isValidateResourceLock(obj)
return ret
},
},
]
}
export default {
name: POLICY_RES_NAME_KEY_MAP.vminstance.key,
getSingleActions,
}