| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775 |
- <template>
- <page-list
- :fixed="true"
- show-tag-filter
- show-tag-columns
- show-tag-columns2
- show-tag-config
- :list="list"
- :columns="templateListColumns || columns"
- :show-single-actions="isTemplate ? false : showActions"
- :show-group-actions="showGroupActions && showActions"
- :group-actions="groupActions"
- :single-actions="singleActions"
- :export-data-options="exportDataOptions"
- :showSearchbox="showSearchbox"
- :defaultSearchKey="defaultSearchKey"
- :refresh-method="handleListRefresh"
- :tag-config-params="tagConfigParams"
- :tableOverviewIndexs="tableOverviewIndexs"
- :show-page="!isTemplate" />
- </template>
- <script>
- import * as R from 'ramda'
- import { mapGetters } from 'vuex'
- import _ from 'lodash'
- import { SERVER_TYPE } from '@Compute/constants'
- import ListMixin from '@/mixins/list'
- import {
- getNameFilter,
- getBrandFilter,
- getStatusFilter,
- getDomainFilter,
- getTenantFilter,
- getAccountFilter,
- getHostFilter,
- getVpcFilter,
- getOsArchFilter,
- getRegionFilter,
- getZoneFilter,
- getCloudProviderFilter,
- getDescriptionFilter,
- getCreatedAtFilter,
- } from '@/utils/common/tableFilter'
- import { getIpsTableColumn } from '@/utils/common/tableColumn'
- import { disableDeleteAction } from '@/utils/common/tableActions'
- import expectStatus from '@/constants/expectStatus'
- import WindowsMixin from '@/mixins/windows'
- import { typeClouds, findPlatform } from '@/utils/common/hypervisor'
- import GlobalSearchMixin from '@/mixins/globalSearch'
- import ResTemplateListMixin from '@/mixins/resTemplateList'
- import regexp from '@/utils/regexp'
- import { hasSetupKey, isLicense2 } from '@/utils/auth'
- import { sizeToDesignatedUnit } from '@/utils/utils'
- import { Manager } from '@/utils/manager'
- import { PROVIDER_MAP, BRAND_MAP } from '@/constants'
- import { KVM_SHARE_STORAGES } from '@/constants/storage'
- import SingleActionsMixin from '../mixins/singleActions'
- import ColumnsMixin from '../mixins/columns'
- import { cloudEnabled, cloudUnabledTip, commonEnabled, validateRescueMode } from '../utils'
- export default {
- name: 'VmInstanceList',
- mixins: [WindowsMixin, ListMixin, GlobalSearchMixin, ColumnsMixin, SingleActionsMixin, ResTemplateListMixin],
- props: {
- id: String,
- getParams: {
- type: Object,
- default: () => ({}),
- },
- cloudEnv: String,
- cloudEnvOptions: {
- type: Array,
- },
- hiddenFilterOptions: {
- type: Array,
- default: () => ([]),
- },
- hiddenActions: {
- type: Array,
- default: () => ([]),
- },
- },
- data () {
- const filter = {}
- if (!this.inBaseSidePage) {
- if (this.$route.query.id) {
- filter.id = [this.$route.query.id]
- }
- if (this.$route.query.status) {
- filter.status = this.$route.query.status
- }
- }
- const pci_model_types = this.$store.getters.capability?.pci_model_types || []
- let devTypes = pci_model_types.map(item => {
- return { key: item.dev_type, label: item.dev_type }
- })
- devTypes = _.unionWith(devTypes, _.isEqual)
- const filterOptions = {
- external_id: {
- label: this.$t('table.title.external_id'),
- },
- id: {
- label: this.$t('table.title.id'),
- },
- name: getNameFilter(),
- description: getDescriptionFilter(),
- brand: getBrandFilter('compute_engine_brands'),
- ip_addr: {
- label: 'IP',
- hiddenField: 'ips',
- },
- status: getStatusFilter('server'),
- power_states: getStatusFilter({ title: this.$t('compute.power_states'), statusModule: 'server', field: 'power_states' }),
- os_dist: {
- label: this.$t('table.title.os'),
- dropdown: true,
- multiple: true,
- distinctField: {
- type: 'extra_field',
- key: 'os_dist',
- },
- },
- projects: getTenantFilter(),
- project_domains: getDomainFilter(),
- billing_type: {
- label: this.$t('table.title.bill_type'),
- dropdown: true,
- items: [
- { label: this.$t('billingType.postpaid'), key: 'postpaid' },
- { label: this.$t('billingType.prepaid'), key: 'prepaid' },
- ],
- },
- cloudaccount: getAccountFilter(),
- manager: getCloudProviderFilter(),
- host: getHostFilter(),
- server_type: {
- label: this.$t('table.title.type'),
- dropdown: true,
- multiple: true,
- hiddenField: 'is_gpu',
- items: [
- { label: this.$t('compute.text_291', [this.$t('dictionary.server')]), key: 'normal' },
- { label: `USB${this.$t('dictionary.server')}`, key: 'usb' },
- { label: this.$t('compute.backup'), key: 'backup' },
- { label: this.$t('compute.trans_device_server'), key: 'gpu' },
- ...devTypes,
- ],
- },
- region: getRegionFilter(),
- zone_ids: getZoneFilter(),
- vpc: getVpcFilter(),
- os_arch: getOsArchFilter(),
- // vmem_size: {
- // label: this.$t('table.title.vmem_size'),
- // },
- vcpu_count: {
- label: 'CPU',
- },
- // disk: {
- // label: this.$t('table.title.disk'),
- // },
- created_at: getCreatedAtFilter(),
- }
- this.hiddenFilterOptions.forEach(key => {
- delete filterOptions[key]
- })
- let hasBastionService = false
- const { services = [] } = this.$store?.getters?.userInfo || {}
- const bastionService = services.find(val => val.type === 'bastionhost')
- if (bastionService && bastionService.status === true) {
- hasBastionService = true
- }
- const monitorManager = new this.$Manager('unifiedmonitors/resource-metrics', 'v1')
- return {
- monitorManager,
- list: this.$list.createList(this, {
- ctx: this,
- id: this.id,
- resource: 'servers',
- getParams: this.getParam,
- steadyStatus: {
- status: Object.values(expectStatus.server).flat(),
- checkBackup: (val) => {
- return val.metadata && (val.metadata.create_backup || val.metadata.switch_backup)
- },
- },
- filter,
- filterOptions,
- responseData: this.responseData,
- isTemplate: this.isTemplate,
- templateLimit: this.templateLimit,
- hiddenColumns: ['is_gpu', 'metadata', 'instance_type', 'os_type', 'vpc', 'host', 'account', 'created_at', 'macs', 'os_arch', 'vcpu_count', 'vmem_size', 'disk', 'power_states'],
- autoHiddenFilterKey: 'server_hidden_columns',
- fetchDataCb: async (response) => {
- if (response.data?.data?.length) {
- const list = response.data?.data || []
- const ids = list.map(item => item.id).filter(Boolean)
- if (ids.length) {
- const res = await monitorManager.create({
- data: {
- res_ids: ids,
- res_type: 'guest',
- },
- })
- const { resource_metrics = {} } = res.data || {}
- for (const key in resource_metrics) {
- const metrics = resource_metrics[key]
- list.find(item => item.id === key).alert_data = metrics
- }
- }
- response.data.data = list
- }
- return response
- },
- }),
- groupActions: [
- // 新建
- {
- label: this.$t('compute.perform_create'),
- permission: 'server_create',
- action: () => {
- this.$openNewWindowForMenuHook('vminstance_configured_callback_address.create_callback_address', () => {
- this.$router.push({
- path: '/vminstance/create',
- query: {
- type: this.cloudEnv === 'onpremise' ? 'idc' : this.cloudEnv || 'idc',
- },
- })
- })
- },
- meta: () => {
- return {
- buttonType: 'primary',
- validate: !this.cloudEnvEmpty,
- tooltip: this.cloudEnvEmpty ? this.$t('common.no_platform_available') : '',
- }
- },
- hidden: () => this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_create') || this.hiddenActions.includes('create'),
- },
- // 开机
- {
- label: this.$t('compute.text_272'),
- permission: 'server_perform_start',
- action: () => {
- this.createDialog('VmStartDialog', {
- data: this.list.selectedItems,
- columns: this.columns,
- onManager: this.onManager,
- })
- },
- meta: () => {
- let ret = {
- validate: true,
- tooltip: null,
- }
- ret.validate = this.list.selectedItems.length > 0
- if (!ret.validate) return ret
- // 某些云不支持
- const unenableCloudCheck = this.hasSomeCloud(this.list.selectedItems)
- if (!unenableCloudCheck.validate) {
- ret = unenableCloudCheck
- return ret
- }
- ret = this.$isValidateResourceLock(this.list.selectedItems, () => {
- ret.validate = this.list.selectedItems.every(item => item.status === 'ready')
- return ret
- })
- return ret
- },
- hidden: () => this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_start'),
- },
- // 批量关机
- {
- label: this.$t('compute.text_273'),
- permission: 'server_perform_stop',
- action: () => {
- this.createDialog('VmShutDownDialog', {
- data: this.list.selectedItems,
- columns: this.columns,
- onManager: this.onManager,
- })
- },
- meta: () => {
- let ret = {
- validate: true,
- tooltip: null,
- }
- ret.validate = this.list.selectedItems.length > 0
- if (!ret.validate) return ret
- // 某些云不支持
- const unenableCloudCheck = this.hasSomeCloud(this.list.selectedItems)
- if (!unenableCloudCheck.validate) {
- ret = unenableCloudCheck
- return ret
- }
- ret = this.$isValidateResourceLock(this.list.selectedItems, () => {
- ret.validate = this.list.selectedItems.every(item => item.status === 'running' || item.status === 'stop_fail')
- return ret
- })
- return ret
- },
- hidden: () => this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_stop'),
- },
- // 重启
- {
- label: this.$t('compute.text_274'),
- permission: 'server_perform_restart',
- action: () => {
- this.createDialog('VmRestartDialog', {
- data: this.list.selectedItems,
- columns: this.columns,
- onManager: this.onManager,
- })
- },
- meta: () => {
- let ret = {
- validate: true,
- tooltip: null,
- }
- ret.validate = this.list.selectedItems.length > 0
- if (!ret.validate) return ret
- // 某些云不支持
- const unenableCloudCheck = this.hasSomeCloud(this.list.selectedItems, [typeClouds.hypervisorMap.bingocloud.key, typeClouds.hypervisorMap.sangfor.key])
- if (!unenableCloudCheck.validate) {
- ret = unenableCloudCheck
- return ret
- }
- ret = this.$isValidateResourceLock(this.list.selectedItems, () => {
- ret.validate = this.list.selectedItems.every(item => ['running', 'stop_fail'].includes(item.status))
- return ret
- })
- return ret
- },
- hidden: () => this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_restart'),
- },
- // 同步状态
- {
- label: this.$t('compute.perform_sync_status'),
- permission: 'server_perform_syncstatus',
- action: () => {
- this.onManager('batchPerformAction', {
- steadyStatus: ['running', 'ready'],
- managerArgs: {
- action: 'syncstatus',
- },
- })
- },
- meta: () => {
- return {
- validate: this.list.selectedItems.length > 0,
- }
- },
- hidden: () => this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_syncstatus'),
- },
- /* 批量操作 */
- {
- label: this.$t('compute.text_275'),
- actions: () => {
- return [
- {
- // * 实例状态
- label: this.$t('compute.text_353'),
- submenus: [
- // 挂起
- {
- label: this.$t('compute.text_1128'),
- permission: 'server_perform_suspend',
- action: () => {
- this.createDialog('VmSuspendDialog', {
- data: this.list.selectedItems,
- columns: this.columns,
- onManager: this.onManager,
- })
- },
- meta: () => {
- const ret = {
- validate: true,
- tooltip: null,
- }
- const isAllSupportBrand = this.list.selectedItems.every(item => {
- return [
- BRAND_MAP.VMware.key,
- BRAND_MAP.OneCloud.key,
- ].includes(item.brand)
- })
- const isAllRunning = this.list.selectedItems.every(item => item.status === 'running')
- if (!isAllSupportBrand) {
- ret.validate = false
- ret.tooltip = this.$t('compute.text_1129')
- return ret
- }
- if (!isAllRunning) {
- ret.validate = false
- ret.tooltip = this.$t('compute.text_1130')
- return ret
- }
- ret.validate = true
- return ret
- },
- hidden: () => !hasSetupKey(['vmware']) || this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_suspend'),
- },
- // 恢复
- {
- label: this.$t('compute.text_478'),
- permission: 'server_perform_resume',
- action: () => {
- this.createDialog('VmResumeDialog', {
- data: this.list.selectedItems,
- columns: this.columns,
- onManager: this.onManager,
- })
- },
- meta: () => {
- const ret = {
- validate: true,
- tooltip: null,
- }
- const isAllVMware = this.list.selectedItems.every(item => item.brand === BRAND_MAP.VMware.key || item.brand === BRAND_MAP.OneCloud.key)
- const isAllSuspend = this.list.selectedItems.every(item => item.status === 'suspend')
- if (!isAllVMware) {
- ret.validate = false
- ret.tooltip = this.$t('compute.text_1129')
- return ret
- }
- if (!isAllSuspend) {
- ret.validate = false
- ret.tooltip = this.$t('compute.text_1131')
- return ret
- }
- ret.validate = true
- return ret
- },
- hidden: () => !hasSetupKey(['vmware']) || this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_resume'),
- },
- // 进入紧急模式
- {
- label: this.$t('compute.start_rescue'),
- permission: 'server_perform_start_rescue',
- action: () => {
- this.createDialog('VmStartRescueDialog', {
- data: this.list.selectedItems,
- columns: this.columns,
- onManager: this.onManager,
- refresh: this.refresh,
- })
- },
- meta: () => {
- const ret = { validate: true }
- let isAllKVM = true
- let isRescueMode = false
- this.list.selectedItems.forEach(item => {
- if (item.brand !== BRAND_MAP.OneCloud.key) {
- isAllKVM = false
- }
- if (item.rescue_mode === true) {
- isRescueMode = true
- }
- })
- if (!isAllKVM) {
- ret.validate = false
- ret.tooltip = this.$t('compute.text_1388')
- return ret
- }
- if (isRescueMode) {
- ret.validate = false
- ret.tooltip = this.$t('compute.start_rescue.validate_tooltip')
- return ret
- }
- return ret
- },
- hidden: () => !hasSetupKey(['onecloud']) || this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_start_rescue'),
- },
- // 退出紧急模式
- {
- label: this.$t('compute.stop_rescue'),
- permission: 'server_perform_stop_rescue',
- action: () => {
- this.createDialog('VmStopRescueDialog', {
- data: this.list.selectedItems,
- columns: this.columns,
- onManager: this.onManager,
- refresh: this.refresh,
- })
- },
- meta: () => {
- const ret = { validate: true }
- let isAllKVM = true
- let isRescueMode = true
- this.list.selectedItems.forEach(item => {
- if (item.brand !== BRAND_MAP.OneCloud.key) {
- isAllKVM = false
- }
- if (item.rescue_mode !== true) {
- isRescueMode = false
- }
- })
- if (!isAllKVM) {
- ret.validate = false
- ret.tooltip = this.$t('compute.text_1388')
- return ret
- }
- if (!isRescueMode) {
- ret.validate = false
- ret.tooltip = this.$t('compute.stop_rescue.validate_tooltip')
- return ret
- }
- return ret
- },
- hidden: () => !hasSetupKey(['onecloud']) || this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_stop_rescue'),
- },
- // 推送配置
- {
- label: this.$t('compute.sync_config'),
- permission: 'server_perform_sync_config',
- action: () => {
- this.createDialog('VmSyncConfigDialog', {
- data: this.list.selectedItems,
- columns: this.columns,
- onManager: this.onManager,
- })
- },
- meta: () => {
- const ret = {
- validate: true,
- tooltip: null,
- }
- const isAllKVM = this.list.selectedItems.every(item => item.brand === BRAND_MAP.OneCloud.key)
- const isAllRunningReady = this.list.selectedItems.every(item => (item.status === 'running' || item.status === 'ready'))
- if (!isAllKVM) {
- ret.validate = false
- ret.tooltip = this.$t('compute.text_1388')
- return ret
- }
- if (!isAllRunningReady) {
- ret.validate = false
- ret.tooltip = this.$t('compute.text_1126')
- return ret
- }
- ret.validate = true
- return ret
- },
- hidden: () => !hasSetupKey(['onecloud']) || this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_sync_config'),
- },
- ],
- },
- {
- // * 属性设置
- label: this.$t('compute.text_356'),
- submenus: [
- // 修改属性
- {
- label: this.$t('compute.text_247'),
- permission: 'server_update',
- action: () => {
- this.createDialog('VmUpdateDialog', {
- data: this.list.selectedItems,
- columns: this.columns,
- onManager: this.onManager,
- })
- },
- meta: (row) => {
- const rescueModeValid = validateRescueMode(this.list.selectedItems)
- if (!rescueModeValid.validate) return rescueModeValid
- const isOneCloud = this.list.selectedItems.every(item => item.brand === 'OneCloud')
- return {
- validate: isOneCloud,
- tooltip: !isOneCloud && this.$t('compute.text_355'),
- }
- },
- hidden: () => !hasSetupKey(['onecloud']) || this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_update'),
- },
- // 更改项目
- {
- label: this.$t('compute.perform_change_owner', [this.$t('dictionary.project')]),
- permission: 'server_perform_change_owner',
- action: () => {
- this.createDialog('ChangeOwenrDialog', {
- data: this.list.selectedItems,
- columns: this.columns,
- onManager: this.onManager,
- name: this.$t('dictionary.server'),
- resource: 'servers',
- })
- },
- meta: () => {
- let ret = {
- validate: true,
- tooltip: null,
- }
- const rescueModeValid = validateRescueMode(this.list.selectedItems)
- if (!rescueModeValid.validate) return rescueModeValid
- if (!this.isAdminMode && !this.isDomainMode) {
- ret.validate = false
- ret.tooltip = `仅系统或${this.$t('dictionary.domain')}管理员支持该操作`
- return ret
- }
- // 某些云不支持
- const unenableCloudCheck = this.hasSomeCloud(this.list.selectedItems, [typeClouds.hypervisorMap.zettakit.key, typeClouds.hypervisorMap.uis.key])
- if (!unenableCloudCheck.validate) {
- ret = unenableCloudCheck
- return ret
- }
- const domains = this.list.selectedItems.map(item => item.domain_id)
- if (R.uniq(domains).length !== 1) {
- ret.validate = false
- ret.tooltip = this.$t('compute.text_280', [this.$t('dictionary.domain')])
- return ret
- }
- return ret
- },
- hidden: () => this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_change_owner'),
- },
- // 到期释放
- {
- label: this.$t('compute.text_1132'),
- permission: 'server_perform_cancel_expire',
- action: () => {
- this.createDialog('SetDurationDialog', {
- data: this.list.selectedItems,
- columns: this.columns,
- onManager: this.onManager,
- refresh: this.refresh,
- alert: this.$t('compute.text_1391'),
- })
- },
- meta: () => {
- let ret = {
- validate: false,
- tooltip: null,
- }
- const rescueModeValid = validateRescueMode(this.list.selectedItems)
- if (!rescueModeValid.validate) return rescueModeValid
- // 包年包月机器,不支持此操作
- const isSomePrepaid = this.list.selectedItems.some((item) => {
- return item.billing_type === 'prepaid'
- })
- if (isSomePrepaid) {
- ret.tooltip = this.$t('compute.text_285')
- return ret
- }
- // 某些云不支持
- const unenableCloudCheck = this.hasSomeCloud(this.list.selectedItems, [typeClouds.hypervisorMap.bingocloud.key, typeClouds.hypervisorMap.sangfor.key, typeClouds.hypervisorMap.zettakit.key, typeClouds.hypervisorMap.uis.key])
- if (!unenableCloudCheck.validate) {
- ret = unenableCloudCheck
- return ret
- }
- // 暂只支持同时操作已设置到期或未设置到期释放的机器
- const isSomeExpired = this.list.selectedItems.some((item) => {
- return item.release_at
- })
- const isSomeNotExpired = this.list.selectedItems.some((item) => {
- return !item.release_at
- })
- if (isSomeExpired && isSomeNotExpired) {
- ret.tooltip = this.$t('compute.text_1133')
- return ret
- }
- ret.validate = true
- return ret
- },
- hidden: () => this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_cancel_expire'),
- },
- // 主机克隆
- {
- label: this.$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: this.list.selectedItems,
- columns: this.columns,
- onManager: this.onManager,
- refresh: this.refresh,
- })
- })
- },
- meta: () => {
- const ret = {
- validate: true,
- tooltip: null,
- }
- const rescueModeValid = validateRescueMode(this.list.selectedItems)
- if (!rescueModeValid.validate) return rescueModeValid
- for (const obj of this.list.selectedItems) {
- if (obj.brand !== BRAND_MAP.OneCloud.key) {
- ret.validate = false
- ret.tooltip = this.$t('compute.text_355')
- break
- }
- if (!['running', 'ready'].includes(obj.status)) {
- ret.validate = false
- ret.tooltip = this.$t('compute.text_1126')
- break
- }
- if (obj.backup_host_id) {
- ret.validate = false
- ret.tooltip = this.$t('compute.text_1283')
- break
- }
- }
- return ret
- },
- hidden: () => !hasSetupKey(['onecloud']) || this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_clone'),
- },
- // 续费
- {
- label: this.$t('compute.text_1117'),
- permission: 'server_perform_renew',
- action: () => {
- this.createDialog('VmResourceFeeDialog', {
- data: this.list.selectedItems,
- columns: this.columns,
- onManager: this.onManager,
- })
- },
- meta: () => {
- const ret = {
- validate: true,
- tooltip: null,
- }
- const rescueModeValid = validateRescueMode(this.list.selectedItems)
- if (!rescueModeValid.validate) return rescueModeValid
- const isAllPublic = this.list.selectedItems.every(item => findPlatform(item.hypervisor) === SERVER_TYPE.public)
- const isAllPrepaid = this.list.selectedItems.every(item => item.billing_type === 'prepaid')
- if (!isAllPublic) {
- ret.validate = false
- ret.tooltip = this.$t('compute.text_1118')
- }
- if (!isAllPrepaid) {
- ret.validate = false
- ret.tooltip = this.$t('compute.text_1119')
- }
- return ret
- },
- hidden: () => !hasSetupKey(['aliyun', 'qcloud', 'huawei', 'ucloud', 'ecloud', 'jdcloud', 'ctyun']) || this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_Renew'),
- },
- // 自动续费设置
- {
- label: this.$t('compute.text_1120'),
- permission: 'server_perform_aet_auto_renew',
- action: () => {
- this.createDialog('VmResourceRenewFeeDialog', {
- data: this.list.selectedItems,
- columns: this.columns,
- onManager: this.onManager,
- refresh: this.refresh,
- })
- },
- meta: () => {
- const ret = {
- validate: true,
- tooltip: null,
- }
- const rescueModeValid = validateRescueMode(this.list.selectedItems)
- if (!rescueModeValid.validate) return rescueModeValid
- const isAllPublic = this.list.selectedItems.every(item => findPlatform(item.hypervisor) === SERVER_TYPE.public)
- const isAllPrepaid = this.list.selectedItems.every(item => item.billing_type === 'prepaid')
- if (!isAllPublic) {
- ret.validate = false
- ret.tooltip = this.$t('compute.text_1118')
- }
- if (!isAllPrepaid) {
- ret.validate = false
- ret.tooltip = this.$t('compute.text_1119')
- }
- return ret
- },
- hidden: () => !(hasSetupKey(['aliyun', 'qcloud', 'huawei', 'ucloud', 'ecloud', 'jdcloud', 'ctyun'])) || this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_auto_renewal'),
- },
- // 更改计费模式
- {
- label: this.$t('compute.change_billing_type'),
- permission: 'server_perform_change_billing_type',
- action: () => {
- this.createDialog('VmChangeBillingTypeDialog', {
- steadyStatus: ['running', 'ready'],
- data: this.list.selectedItems,
- columns: this.columns,
- onManager: this.onManager,
- refresh: this.refresh,
- })
- },
- meta: () => {
- const ret = {
- validate: false,
- tooltip: null,
- }
- const rescueModeValid = validateRescueMode(this.list.selectedItems)
- if (!rescueModeValid.validate) return rescueModeValid
- this.list.selectedItems.map(obj => {
- if (obj.brand !== BRAND_MAP.Aliyun.key && obj.brand !== BRAND_MAP.Qcloud.key) {
- ret.tooltip = this.$t('compute.text_473', [PROVIDER_MAP[obj.provider].label])
- }
- })
- if (!ret.tooltip) {
- ret.validate = true
- }
- return ret
- },
- hidden: () => !(hasSetupKey(['aliyun', 'qcloud'])) || this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_change_billing_type'),
- },
- // 编辑标签
- {
- label: this.$t('compute.text_283'),
- permission: 'server_perform_set_user_metadata',
- action: () => {
- this.createDialog('SetTagDialog', {
- data: this.list.selectedItems,
- columns: this.columns,
- onManager: this.onManager,
- params: {
- resources: 'server',
- },
- mode: 'add',
- })
- },
- meta: () => {
- let ret = { validate: true }
- const rescueModeValid = validateRescueMode(this.list.selectedItems)
- if (!rescueModeValid.validate) return rescueModeValid
- // 某些云不支持
- const unenableCloudCheck = this.hasSomeCloud(this.list.selectedItems)
- if (!unenableCloudCheck.validate) {
- ret = unenableCloudCheck
- return ret
- }
- return ret
- },
- },
- ],
- },
- {
- // * 配置修改
- label: this.$t('compute.group_action.update_config'),
- submenus: [
- // 重装系统
- {
- label: this.$t('compute.text_357'),
- permission: 'server_perform_rebuild_root',
- action: () => {
- this.createDialog('VmRebuildRootDialog', {
- data: this.list.selectedItems,
- columns: this.columns,
- onManager: this.onManager,
- })
- },
- meta: () => {
- const ret = {
- validate: true,
- tooltip: null,
- }
- const rescueModeValid = validateRescueMode(this.list.selectedItems)
- if (!rescueModeValid.validate) return rescueModeValid
- const isSameStopCharging = this.list.selectedItems.some((item) => { return item.shutdown_mode === 'stop_charging' && item.status === 'ready' })
- if (isSameStopCharging) {
- ret.validate = false
- ret.tooltip = this.$t('compute.server.shutdown_mode.tooltip')
- return ret
- }
- // same cpu arch
- if (!this.isSameArch) {
- ret.validate = false
- ret.tooltip = this.$t('compute.vminstance.actions.adjust_config.cpu_arch.tips')
- return ret
- }
- if (this.isSameHyper) {
- ret.validate = cloudEnabled('rebuildRoot', this.list.selectedItems)
- ret.tooltip = cloudUnabledTip('rebuildRoot', this.list.selectedItems)
- return ret
- }
- return ret
- },
- hidden: () => this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_rebuild_root'),
- },
- // 调整配置
- {
- label: this.$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: this.list.selectedItems.map((item) => { return item.id }),
- },
- })
- })
- },
- meta: () => {
- const ret = {
- validate: true,
- tooltip: null,
- }
- const rescueModeValid = validateRescueMode(this.list.selectedItems)
- if (!rescueModeValid.validate) return rescueModeValid
- if (this.isSameHyper) {
- const isSomeBackupHost = this.list.selectedItems.some((item) => { return item.backup_host_id })
- if (isSomeBackupHost) {
- ret.validate = false
- ret.tooltip = this.$t('compute.text_1111')
- return ret
- }
- ret.validate = cloudEnabled('adjustConfig', this.list.selectedItems)
- ret.tooltip = cloudUnabledTip('adjustConfig', this.list.selectedItems)
- // const googleItems = this.list.selectedItems.filter(val => val.brand === typeClouds.brandMap.Google.key)
- // if (googleItems && googleItems.length) { // 谷歌云 windows 仅支持关机下操作,linux 支持 开关机
- // ret.validate = googleItems.every(val => {
- // const os = val.os_type.toLowerCase()
- // if (os.includes('windows')) {
- // return val.status === 'ready'
- // }
- // if (os.includes('linux')) {
- // return val.status === 'ready' || val.status === 'running'
- // }
- // return true
- // })
- // if (!ret.validate) {
- // ret.tooltip = '谷歌云Windows虚拟机仅支持关机下操作,Linux虚拟机支持开机和关机下操作'
- // }
- // }
- // same cpu arch
- if (!this.isSameArch) {
- ret.validate = false
- ret.tooltip = this.$t('compute.vminstance.actions.adjust_config.cpu_arch.tips')
- return ret
- }
- const isSameStopCharging = this.list.selectedItems.some((item) => { return item.shutdown_mode === 'stop_charging' && item.status === 'ready' })
- if (isSameStopCharging) {
- ret.validate = false
- ret.tooltip = this.$t('compute.server.shutdown_mode.tooltip')
- return ret
- }
- return ret
- }
- ret.validate = false
- ret.tooltip = this.$t('compute.text_278')
- return ret
- },
- hidden: () => this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_change_config'),
- },
- // 设置透传设备
- {
- label: this.$t('compute.text_1112'),
- permission: 'attach-isolated-device,server_perform_detach_isolated_device,server_perform_set_isolated_device',
- action: () => {
- this.createDialog('VmAttachGpuDialog', {
- data: this.list.selectedItems,
- columns: this.columns,
- onManager: this.onManager,
- })
- },
- meta: () => {
- let ret = {
- validate: true,
- tooltip: null,
- }
- const rescueModeValid = validateRescueMode(this.list.selectedItems)
- if (!rescueModeValid.validate) return rescueModeValid
- const isAllIdc = this.list.selectedItems.every((item) => {
- return findPlatform(item.hypervisor, 'hypervisor') === SERVER_TYPE.idc
- })
- const isOk = this.list.selectedItems.every((item) => { return ['running', 'ready'].includes(item.status) })
- if (!isOk) {
- ret.validate = false
- ret.tooltip = this.$t('compute.text_1126')
- return ret
- }
- // 某些云不支持
- const unenableCloudCheck = this.hasSomeCloud(this.list.selectedItems, [typeClouds.hypervisorMap.bingocloud.key, 'esxi', typeClouds.hypervisorMap.zettakit.key, typeClouds.hypervisorMap.uis.key])
- if (!isAllIdc) {
- ret.validate = false
- ret.tooltip = this.$t('compute.text_1115')
- return ret
- }
- if (!unenableCloudCheck.validate) {
- ret = unenableCloudCheck
- return ret
- }
- return ret
- },
- hidden: () => !hasSetupKey(['onecloud']) || this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_set_gpu'),
- },
- ],
- },
- {
- // * 密码密钥
- label: this.$t('compute.text_360'),
- submenus: [
- // 重置密码
- {
- label: this.$t('compute.text_276'),
- permission: 'server_perform_set_password',
- action: () => {
- this.createDialog('VmResetPasswordDialog', {
- data: this.list.selectedItems,
- columns: this.columns,
- onManager: this.onManager,
- })
- },
- meta: () => {
- const ret = {
- validate: true,
- tooltip: null,
- }
- const rescueModeValid = validateRescueMode(this.list.selectedItems)
- if (!rescueModeValid.validate) return rescueModeValid
- const isBindKeypair = this.list.selectedItems.some((item) => { return item.keypair_id && item.keypair_id.toLowerCase() !== 'none' })
- if (isBindKeypair) {
- ret.validate = false
- ret.tooltip = this.$t('compute.text_277')
- return ret
- }
- return {
- validate: cloudEnabled('resetPassword', this.list.selectedItems),
- tooltip: cloudUnabledTip('resetPassword', this.list.selectedItems),
- }
- },
- hidden: () => this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_deploy'),
- },
- // 设置免密登录
- {
- label: this.$t('compute.vminstance.actions.setup_ssh_authentication'),
- permission: 'server_perform_setup_ssh_proxy',
- action: () => {
- this.createDialog('SetupSSHDialog', {
- data: this.list.selectedItems,
- columns: this.columns,
- onManager: this.onManager,
- })
- },
- meta: () => {
- let ret = {
- validate: true,
- tooltip: null,
- }
- const rescueModeValid = validateRescueMode(this.list.selectedItems)
- if (!rescueModeValid.validate) return rescueModeValid
- // 某些云不支持
- const unenableCloudCheck = this.hasSomeCloud(this.list.selectedItems, [typeClouds.hypervisorMap.sangfor.key, typeClouds.hypervisorMap.zettakit.key, typeClouds.hypervisorMap.uis.key])
- if (!unenableCloudCheck.validate) {
- ret = unenableCloudCheck
- return ret
- }
- if (this.list.selectedItems) {
- const project = this.list.selectedItems[0].project || ''
- const isSame = this.list.selectedItems.every((item) => {
- return item.project === project
- })
- if (!isSame) {
- ret.validate = false
- ret.tooltip = this.$t('compute.vminstance.setup_ssh_authentication.group_action.project')
- return ret
- }
- const isLinux = this.list.selectedItems.every((item) => {
- return item.os_type && item.os_type.toLowerCase() === 'linux'
- })
- if (!isLinux) {
- ret.validate = false
- ret.tooltip = this.$t('compute.text_362')
- return ret
- }
- }
- for (const obj of this.list.selectedItems) {
- if (!commonEnabled(obj, ['running'])) {
- ret.validate = false
- ret.tooltip = this.$t('db.text_156')
- return ret
- }
- }
- return ret
- },
- hidden: () => this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_setup_ssh_proxy'),
- },
- // 探测免密登录
- {
- label: this.$t('compute.vminstance.actions.detect_ssh_authentication'),
- permission: 'server_perform_make_sshable',
- action: () => {
- this.createDialog('DetectSSHDialog', {
- data: this.list.selectedItems,
- columns: this.columns,
- onManager: this.onManager,
- })
- },
- meta: () => {
- let ret = {
- validate: true,
- tooltip: null,
- }
- const rescueModeValid = validateRescueMode(this.list.selectedItems)
- if (!rescueModeValid.validate) return rescueModeValid
- // 某些云不支持
- const unenableCloudCheck = this.hasSomeCloud(this.list.selectedItems, [typeClouds.hypervisorMap.sangfor.key, typeClouds.hypervisorMap.zettakit.key, typeClouds.hypervisorMap.uis.key])
- if (!unenableCloudCheck.validate) {
- ret = unenableCloudCheck
- return ret
- }
- for (const obj of this.list.selectedItems) {
- if (!commonEnabled(obj, ['running'])) {
- ret.validate = false
- ret.tooltip = this.$t('db.text_156')
- return ret
- }
- }
- return ret
- },
- hidden: () => this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_detect_ssh_proxy'),
- },
- ],
- },
- {
- // * 网络安全
- label: this.$t('compute.text_1290'),
- submenus: [
- // 关联安全组
- // {
- // label: this.$t('compute.text_1116'),
- // permission: 'server_perform_add_secgroup',
- // action: () => {
- // this.createDialog('VmSetSecgroupDialog', {
- // vm: this,
- // data: this.list.selectedItems,
- // columns: this.columns,
- // onManager: this.onManager,
- // })
- // },
- // meta: () => {
- // const ret = {
- // validate: cloudEnabled('assignSecgroup', this.list.selectedItems),
- // tooltip: cloudUnabledTip('assignSecgroup', this.list.selectedItems),
- // }
- // return ret
- // },
- // hidden: () => !(hasSetupKey(['onestack', 'onecloud', 'public', 'openstack', 'dstack', 'zstack', 'apsara', 'cloudpods', 'hcso', 'hcs'])) || this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_add_secgroup'),
- // },
- // 公网IP转EIP
- {
- label: this.$t('compute.text_1121'),
- permission: 'server_perform_publicip_to_eip',
- action: () => {
- this.createDialog('VmPublicIpToEipDialog', {
- data: this.list.selectedItems,
- columns: this.columns,
- onManager: this.onManager,
- })
- },
- meta: () => {
- const ret = {
- validate: false,
- tooltip: null,
- }
- const rescueModeValid = validateRescueMode(this.list.selectedItems)
- if (!rescueModeValid.validate) return rescueModeValid
- const isSomeBindEip = this.list.selectedItems.some((item) => { return item.eip && item.eip_mode === 'elastic_ip' })
- const isAllBindPublicIp = this.list.selectedItems.every((item) => { return item.eip_mode === 'public_ip' })
- if (isSomeBindEip) {
- ret.validate = false
- ret.tooltip = this.$t('compute.text_1122')
- return ret
- }
- if (!isAllBindPublicIp) {
- ret.validate = false
- ret.tooltip = this.$t('compute.text_1123')
- return ret
- }
- ret.validate = cloudEnabled('publicIpToEip', this.list.selectedItems)
- ret.tooltip = cloudUnabledTip('publicIpToEip', this.list.selectedItems)
- return ret
- },
- hidden: () => !(hasSetupKey(['aliyun', 'qcloud'])) || this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_public_ip_to_eip'),
- },
- // 设置源/目标检查
- {
- label: this.$t('compute.text_1124'),
- permission: 'server_perform_modify_src_check',
- action: () => {
- this.createDialog('VmSourceTargetCheckDialog', {
- data: this.list.selectedItems,
- columns: this.columns,
- onManager: this.onManager,
- refresh: this.refresh,
- })
- },
- meta: () => {
- const ret = { validate: true, tooltip: null }
- const rescueModeValid = validateRescueMode(this.list.selectedItems)
- if (!rescueModeValid.validate) return rescueModeValid
- const isAllOneCloud = this.list.selectedItems.every((item) => { return item.brand === BRAND_MAP.OneCloud.key })
- const isOk = this.list.selectedItems.every((item) => { return ['running', 'ready'].includes(item.status) })
- if (!isAllOneCloud) {
- ret.validate = false
- ret.tooltip = this.$t('compute.text_1125')
- return ret
- }
- if (!isOk) {
- ret.validate = false
- ret.tooltip = this.$t('compute.text_1126')
- return ret
- }
- return ret
- },
- hidden: () => !(hasSetupKey(['onecloud'])) || this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_set_source_check'),
- },
- // 添加到堡垒机
- {
- label: this.$t('compute.add_to_bastion'),
- permission: 'bastion_servers_create',
- action: () => {
- this.createDialog('VmAddToBastionDialog', {
- data: this.list.selectedItems,
- columns: this.columns,
- onManager: this.onManager,
- refresh: this.refresh,
- })
- },
- meta: () => {
- const ret = { validate: true }
- const isSomeBastionServer = this.list.selectedItems.some((item) => { return item.metadata?.bastion_server })
- if (isSomeBastionServer) {
- ret.validate = false
- ret.tooltip = this.$t('compute.already_in_bastion')
- return ret
- }
- const isEveryRunning = this.list.selectedItems.every((item) => { return item.status === 'running' })
- if (!isEveryRunning) {
- ret.validate = false
- ret.tooltip = this.$t('compute.text_1282')
- return ret
- }
- const rescueModeValid = validateRescueMode(this.list.selectedItems)
- return rescueModeValid
- },
- 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: this.$t('compute.remove_from_bastion'),
- permission: 'bastion_servers_delete',
- action: () => {
- this.createDialog('VmRemoveFromBastionDialog', {
- data: this.list.selectedItems,
- columns: this.columns,
- onManager: this.onManager,
- refresh: this.refresh,
- })
- },
- meta: () => {
- const ret = { validate: true }
- const isEveryBastionServer = this.list.selectedItems.every((item) => { return item.metadata?.bastion_server })
- if (!isEveryBastionServer) {
- ret.validate = false
- return ret
- }
- const isEveryRunning = this.list.selectedItems.every((item) => { return item.status === 'running' || item.status === 'ready' })
- if (!isEveryRunning) {
- ret.validate = false
- ret.tooltip = this.$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: this.$t('compute.text_1295'),
- submenus: [
- // 迁移
- {
- label: this.$t('compute.text_1127'),
- permission: 'server_perform_migrate,server_perform_live_migrate',
- action: () => {
- this.createDialog('VmTransferDialog', {
- data: this.list.selectedItems,
- columns: this.columns,
- onManager: this.onManager,
- })
- },
- meta: () => {
- const ret = { validate: true, tooltip: null }
- const rescueModeValid = validateRescueMode(this.list.selectedItems)
- if (!rescueModeValid.validate) return rescueModeValid
- // 运行中、关机、状态未知
- const statusSet = new Set()
- const brandSet = new Set()
- this.list.selectedItems.forEach(item => {
- statusSet.add(item.status)
- brandSet.add(item.brand)
- })
- if (!this.isAdminMode && !this.isDomainMode) {
- ret.validate = false
- ret.tooltip = this.$t('compute.tooltip.check_domain_permission')
- return ret
- }
- if (statusSet.size > 1) {
- ret.validate = false
- ret.tooltip = this.$t('compute.tooltip.check_some_status_transfer')
- return ret
- }
- const isStatusOk = [...statusSet].every((status) => {
- return ['running', 'ready'].includes(status)
- })
- if (!isStatusOk) {
- ret.tooltip = this.$t('compute.tooltip.check_status_transfer')
- ret.validate = false
- return ret
- }
- const isBackupHost = this.list.selectedItems.some((item) => item.backup_host_id)
- if (isBackupHost) {
- ret.tooltip = this.$t('compute.tooltip.check_backup_host_transfer')
- ret.validate = false
- return ret
- }
- const isGpu = this.list.selectedItems.some((item) => item.is_gpu)
- if (isGpu) {
- ret.tooltip = this.$t('compute.tooltip.check_gpu_transfer')
- ret.validate = false
- return ret
- }
- const isCdrom = this.list.selectedItems.some((item) => item.cdrom)
- if (isCdrom) {
- ret.tooltip = this.$t('compute.tooltip.check_cdrom_transfer')
- ret.validate = false
- return ret
- }
- if (brandSet.size > 1) {
- ret.validate = false
- ret.tooltip = this.$t('compute.v2vtransfer.same_brand')
- return ret
- }
- ret.validate = cloudEnabled('transfer', this.list.selectedItems)
- ret.tooltip = cloudUnabledTip('transfer', this.list.selectedItems)
- return ret
- },
- hidden: () => !(hasSetupKey(['onecloud', 'openstack', 'vmware'])) || this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_transfer'),
- },
- // V2V迁移
- {
- label: this.$t('compute.v2vtransfer.label'),
- permission: 'server_perform_migrate',
- action: () => {
- this.createDialog('VmV2vTransferDialog', {
- data: this.list.selectedItems,
- columns: this.columns,
- onManager: this.onManager,
- successCallback: this.refresh,
- })
- },
- meta: () => {
- const ret = { validate: true, tooltip: null }
- const rescueModeValid = validateRescueMode(this.list.selectedItems)
- if (!rescueModeValid.validate) return rescueModeValid
- const statusSet = new Set()
- const brandSet = new Set()
- const backupHostSet = new Set()
- let isIpEmpty = false
- if (!this.isAdminMode && !this.isDomainMode) {
- ret.validate = false
- ret.tooltip = this.$t('compute.tooltip.check_domain_permission')
- return ret
- }
- this.list.selectedItems.forEach((item) => {
- statusSet.add(item.status)
- brandSet.add(item.brand)
- if (item.backup_host_id) {
- backupHostSet.add(item.backup_host_id)
- }
- if (!item.ips) {
- isIpEmpty = true
- }
- })
- if (statusSet.size > 1 || !statusSet.has('ready')) {
- ret.tooltip = this.$t('compute.tooltip.check_ready_status_transfer')
- ret.validate = false
- return ret
- }
- if (brandSet.size > 1) {
- ret.tooltip = this.$t('compute.v2vtransfer.same_brand')
- ret.validate = false
- return ret
- } else {
- if (!brandSet.has(BRAND_MAP.Cloudpods.key) &&
- !brandSet.has(BRAND_MAP.VMware.key)) {
- ret.tooltip = this.$t('compute.brand_support', [`${BRAND_MAP.Cloudpods.label},${BRAND_MAP.VMware.label}`])
- ret.validate = false
- return ret
- }
- }
- if (backupHostSet.size > 0) {
- ret.tooltip = this.$t('compute.tooltip.check_backup_host_transfer')
- ret.validate = false
- return ret
- }
- if (isIpEmpty) {
- ret.tooltip = this.$t('compute.fill_ips_tooltip')
- ret.validate = false
- return ret
- }
- ret.validate = cloudEnabled('v2vTransfer', this.list.selectedItems)
- ret.tooltip = cloudUnabledTip('v2vTransfer', this.list.selectedItems)
- return ret
- },
- hidden: () => !(hasSetupKey(['vmware', 'cloudpods'])) || this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_transfer'),
- },
- // 快速恢复
- {
- label: this.$t('compute.server.quick.recovery'),
- action: () => {
- this.createDialog('VmQuickRecoveryDialog', {
- data: this.list.selectedItems,
- columns: this.columns,
- onManager: this.onManager,
- })
- },
- meta: () => {
- const ret = {
- validate: true,
- tooltip: '',
- }
- const rescueModeValid = validateRescueMode(this.list.selectedItems)
- if (!rescueModeValid.validate) return rescueModeValid
- const isAllOneCloud = this.list.selectedItems.every((item) => { return item.brand === BRAND_MAP.OneCloud.key })
- if (!isAllOneCloud) {
- ret.validate = false
- ret.tooltip = this.$t('compute.text_1125')
- return ret
- }
- const isAllHostOffline = this.list.selectedItems.every((item) => { return item.host_service_status === 'offline' })
- if (!isAllHostOffline) {
- ret.validate = false
- ret.tooltip = this.$t('compute.quick.recovery.validate.host_status_tooltip')
- return ret
- }
- const allStorages = R.flatten(this.list.selectedItems.map(item => item.disks_info || []))
- const isAllKVMShareStorages = allStorages.every(item => KVM_SHARE_STORAGES.includes(item.storage_type))
- if (!isAllKVMShareStorages) {
- ret.validate = false
- ret.tooltip = this.$t('compute.quick.recovery.validate.host_status_tooltip')
- return ret
- }
- return ret
- },
- hidden: () => !hasSetupKey(['onecloud']) || this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_migrate'),
- },
- ],
- },
- {
- // * 删除
- label: this.$t('compute.perform_delete'),
- submenus: [
- // 设置删除保护
- disableDeleteAction(Object.assign(this, {
- permission: 'server_update',
- }), {
- name: this.$t('dictionary.server'),
- meta: () => {
- // 某些云不支持
- const unenableCloudCheck = this.hasSomeCloud(this.list.selectedItems)
- return unenableCloudCheck
- },
- hidden: () => this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_set_delete_protection'),
- }),
- // 删除
- {
- label: this.$t('compute.perform_delete'),
- permission: 'server_delete',
- action: () => {
- this.$openNewWindowForMenuHook('vminstance_configured_callback_address.delete_callback_address', () => {
- this.createDialog('DeleteVmDialog', {
- vm: this,
- data: this.list.selectedItems,
- columns: this.columns,
- onManager: this.onManager,
- title: this.$t('compute.perform_delete'),
- })
- })
- },
- meta: () => {
- const unenableCloudCheck = this.hasSomeCloud(this.list.selectedItems)
- if (!unenableCloudCheck.validate) {
- return unenableCloudCheck
- }
- const isHasRunning = this.list.selectedItems.some((item) => item.status === 'running')
- const { server_delete_limit = false } = this.$store.getters.globalSetting.value || {}
- if (server_delete_limit && isHasRunning) {
- return {
- validate: false,
- tooltip: this.$t('compute.delete_limit'),
- }
- }
- return this.$getDeleteResult(this.list.selectedItems)
- },
- hidden: () => this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_delete'),
- },
- ],
- },
- ]
- },
- meta: () => {
- let ret = {
- validate: true,
- tooltip: null,
- }
- ret.validate = this.list.selectedItems.length > 0
- if (!ret.validate) return ret
- ret = this.$isValidateResourceLock(this.list.selectedItems)
- return ret
- },
- },
- ],
- execLoading: false,
- tagConfigParams: {
- title: this.$t('common.text00124'),
- resource: 'servers',
- queryTreeId: 'project-tag-value-tree',
- },
- }
- },
- computed: {
- ...mapGetters(['isAdminMode']),
- isSameHyper () {
- if (this.list.selectedItems.length > 0) {
- const arr = this.list.selectedItems.map(v => v.hypervisor)
- const noRepeatArr = Array.from(new Set(arr))
- return noRepeatArr.length === 1
- }
- return true
- },
- isSameArch () {
- if (this.list.selectedItems[0] && (this.list.selectedItems[0].hypervisor.toLowerCase() === 'hcso' || this.list.selectedItems[0].hypervisor.toLowerCase() === 'hcs')) {
- const instancetype = this.list.selectedItems[0].instance_type || ''
- const isArm = instancetype.startsWith('k')
- return this.list.selectedItems.every(item => item.instance_type && item.instance_type.startsWith('k') === isArm)
- }
- return true
- },
- showActions () {
- return !this.$isScopedPolicyMenuHidden('server_hidden_columns.perform_action')
- },
- exportDataOptions () {
- const ret = {
- isOpenExportUsernamePassword: false,
- downloadType: 'local',
- items: [
- { label: 'ID', key: 'id' },
- { label: this.$t('table.title.external_id'), key: 'external_id' },
- ],
- fixedItems: [
- { key: 'metadata.os_distribution', label: this.$t('table.title.os') },
- { key: 'disk', label: this.$t('table.title.disk') + '(M)' },
- { key: 'vmem_size', label: this.$t('table.title.vmem_size') + '(M)' },
- { key: 'eip', title: this.$t('common.eip') },
- { key: 'ips', title: 'IP' },
- { key: 'is_gpu', title: `${this.$t('table.title.type')}(${this.$t('compute.text_113')}${this.$t('dictionary.server')})` },
- ],
- hiddenFields: ['os_dist', 'elastic_ip', 'ip'],
- async beforeExport () {
- const checkOpenExportUsernamePassword = async () => {
- try {
- const configM = new Manager('services', 'v1')
- const servicesRes = await configM.list({ params: { type: 'compute_v2' } })
- const serviceId = servicesRes.data.data?.[0]?.id
- const configData = await configM.getSpecific({ id: serviceId, spec: 'config' })
- const { enable_export_username_password = false } = configData.data?.config?.default
- ret.isOpenExportUsernamePassword = enable_export_username_password
- return enable_export_username_password
- } catch (error) {
- console.log('fetch compute_v2 service config error!!!')
- }
- }
- const isOpenExportUsernamePassword = await checkOpenExportUsernamePassword()
- ret.isOpenExportUsernamePassword = isOpenExportUsernamePassword
- ret.items.forEach(item => {
- if (item.field === 'extra_user') {
- item.hidden = !isOpenExportUsernamePassword
- }
- if (item.field === 'extra_password') {
- item.hidden = !isOpenExportUsernamePassword
- }
- })
- },
- async callback (data, selectedExportKeys) {
- if (!ret.isOpenExportUsernamePassword) {
- return data
- }
- if (!selectedExportKeys.includes('extra_user') && !selectedExportKeys.includes('extra_password')) {
- return data
- }
- const manager = new Manager('servers')
- const allPromise = data.map(async item => {
- let username = ''
- let password = ''
- try {
- const { data } = await manager.objectRpc({
- methodname: 'GetLoginInfo',
- objId: item.id,
- })
- username = data.username
- password = data.password
- } catch (error) {
- console.log(`server: ${item.id}, login info fetch error!!!`)
- }
- return Promise.resolve({ id: item.id, username, password })
- })
- const results = Promise.all(allPromise).then(values => {
- const realData = data.map(item => {
- const curObj = values.find(v => v.id === item.id)
- return {
- ...item,
- extra_user: curObj.username,
- extra_password: curObj.password,
- }
- })
- return realData
- })
- return results
- },
- }
- this.columns.map(col => {
- if (col.field === 'ips') {
- ret.items.push(getIpsTableColumn({ field: 'elastic_ip', title: this.$t('common.eip'), vm: this, onlyElastic: true }))
- ret.items.push(getIpsTableColumn({ field: 'ip', title: 'IP', vm: this, noElastic: true }))
- } else if (!(col.hidden && col.hidden()) && col.field !== 'password') {
- const item = {
- field: col.field,
- title: col.title || col.label,
- formatter: col.formatter,
- }
- if (col.field === 'vmem_size') {
- item.title = `${item.title}(G)`
- item.formatter = ({ row }) => {
- if (row.vmem_size) {
- const config = (row.vmem_size / 1024)
- return config
- }
- return ''
- }
- }
- if (col.field === 'disk') {
- item.title = `${item.title}(G)`
- item.formatter = ({ row }) => {
- if (row.disk) {
- const size = sizeToDesignatedUnit(row.disk, 'M', 'G', 1024, false, 2)
- return size
- }
- return ''
- }
- }
- ret.items.push(item)
- } else if (col.field === 'password') {
- ret.items.push({ field: 'extra_user', title: this.$t('compute.text_566') })
- ret.items.push({ field: 'extra_password', title: this.$t('common_328') })
- }
- if (col.field === 'region') {
- ret.items.push({ field: 'zone', title: this.$t('compute.text_270') })
- }
- })
- ret.items.push({
- field: 'expired_at',
- title: this.$t('scope.text_791'),
- formatter: ({ row }) => {
- if (!row.expired_at) return '-'
- return this.$moment(row.expired_at).format()
- },
- })
- return ret
- },
- },
- watch: {
- cloudEnv (val) {
- this.$nextTick(() => {
- this.list.fetchData(0)
- })
- },
- },
- created () {
- this.initSidePageTab('vm-instance-detail')
- this.list.fetchData().then(() => {
- this.$nextTick(() => {
- if (this.$route.query.id && this.list.data[this.$route.query.id]) {
- this.handleOpenSidepage(this.list.data[this.$route.query.id].data)
- }
- })
- })
- this.$bus.$on('VMInstanceListSingleUpdate', args => {
- this.list.singleUpdate(...args)
- }, this)
- this.$bus.$on('VMInstanceListSingleRefresh', args => {
- this.list.singleRefresh(...args)
- }, this)
- // this.$bus.$on('VMInstanceListRefresh', args => {
- // this.list.resetRefresh()
- // }, this)
- },
- methods: {
- getParam () {
- const ret = {
- details: true,
- with_meta: true,
- filter: 'hypervisor.notin(baremetal,container,pod)',
- ...this.getParams,
- }
- if (this.cloudEnv) ret.cloud_env = this.cloudEnv
- return ret
- },
- handleOpenSidepage (row, tab) {
- this.sidePageTriggerHandle(this, 'VmInstanceSidePage', {
- id: row.id,
- resource: 'servers',
- getParams: this.getParam,
- steadyStatus: Object.values(expectStatus.server).flat(),
- }, {
- list: this.list,
- tab,
- })
- },
- beforeShowMenu () {
- return this.$store.dispatch('scopedPolicy/get', {
- category: ['vminstance_hidden_menus', 'vminstance_configured_callback_address'],
- })
- },
- defaultSearchKey (search) {
- if (regexp.isIPv4(search)) {
- return 'ip_addr'
- }
- },
- handleListRefresh () {
- this.list.refresh()
- // 新建按钮无法点击时,刷新云资源情况
- this.cloudEnvEmpty && this.$store.dispatch('auth/getCapabilities')
- },
- hasSomeCloud (selectItems, clouds = [typeClouds.hypervisorMap.bingocloud.key]) {
- const ret = { validate: true, tooltip: '' }
- const hasList = selectItems.filter(item => clouds.includes(item.hypervisor))
- if (hasList && hasList[0]) {
- ret.validate = false
- ret.tooltip = this.$t('compute.text_473', [typeClouds.hypervisorMap[hasList[0].hypervisor].label])
- }
- return ret
- },
- },
- }
- </script>
|