actions.js 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518
  1. import { disableDeleteAction } from '@/utils/common/tableActions'
  2. import i18n from '@/locales'
  3. import { BRAND_MAP, PROVIDER_MAP } from '@/constants'
  4. import { typeClouds } from '@/utils/common/hypervisor'
  5. import { hasSetupKey } from '@/utils/auth'
  6. import { validateRescueMode, cloudEnabled, cloudUnabledTip, commonUnabled } from '../utils'
  7. // import { POLICY_RES_NAME_KEY_MAP } from '@/constants/policy'
  8. const getSingleActions = function () {
  9. return [
  10. // 终端
  11. {
  12. label: i18n.t('compute.repo.terminal'),
  13. actions: (obj) => {
  14. const containers = obj.containers || []
  15. return containers.map(item => {
  16. return {
  17. label: item.name,
  18. action: async () => {
  19. const connectRes = await this.fetchConnectUrl(item.id)
  20. this.openWebConsole(connectRes)
  21. },
  22. }
  23. })
  24. },
  25. meta: (obj) => {
  26. const ret = { validate: true }
  27. if (!obj.containers?.length) {
  28. ret.validate = false
  29. return ret
  30. }
  31. if (obj.status !== 'running' && obj.status !== 'probing') {
  32. ret.tooltip = this.$t('compute.repo.helper.terminal', [this.$t('compute.vminstance-container')])
  33. ret.validate = false
  34. }
  35. return ret
  36. },
  37. },
  38. {
  39. label: i18n.t('compute.text_352'),
  40. actions: (obj) => {
  41. return [
  42. {
  43. label: i18n.t('compute.text_353'),
  44. submenus: [
  45. // 同步状态
  46. {
  47. label: i18n.t('compute.perform_sync_status'),
  48. permission: 'server_perform_syncstatus',
  49. action: () => {
  50. this.onManager('performAction', {
  51. steadyStatus: ['running', 'ready'],
  52. id: obj.id,
  53. managerArgs: {
  54. action: 'syncstatus',
  55. },
  56. })
  57. },
  58. hidden: () => this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_syncstatus'),
  59. },
  60. // 开机
  61. {
  62. label: i18n.t('compute.text_272'),
  63. action: () => {
  64. this.onManager('performAction', {
  65. steadyStatus: 'running',
  66. id: obj.id,
  67. managerArgs: {
  68. action: 'start',
  69. },
  70. })
  71. },
  72. meta: () => {
  73. return {
  74. validate: obj.status === 'ready',
  75. }
  76. },
  77. },
  78. // 关机
  79. {
  80. label: i18n.t('compute.text_273'),
  81. action: () => {
  82. this.createDialog('VmShutDownDialog', {
  83. data: [obj],
  84. columns: this.columns,
  85. onManager: this.onManager,
  86. name: i18n.t('compute.vminstance-container'),
  87. })
  88. },
  89. meta: () => {
  90. return {
  91. validate: obj.status === 'running',
  92. }
  93. },
  94. },
  95. // 重启
  96. {
  97. label: i18n.t('compute.text_274'),
  98. action: () => {
  99. this.createDialog('VmContainerRestartDialog', {
  100. data: [obj],
  101. columns: this.columns,
  102. onManager: this.onManager,
  103. })
  104. },
  105. meta: () => {
  106. return {
  107. validate: obj.status === 'running',
  108. }
  109. },
  110. },
  111. // 重置
  112. {
  113. label: i18n.t('compute.text_354'),
  114. permission: 'server_perform_reset',
  115. action: () => {
  116. this.createDialog('VmContainerResetDialog', {
  117. data: [obj],
  118. columns: this.columns,
  119. onManager: this.onManager,
  120. })
  121. },
  122. meta: () => {
  123. const provider = obj.provider
  124. const ret = {
  125. validate: false,
  126. tooltip: null,
  127. }
  128. if (obj.brand !== BRAND_MAP.OneCloud.key) {
  129. ret.tooltip = i18n.t('compute.text_473', [PROVIDER_MAP[provider].label])
  130. return ret
  131. }
  132. return {
  133. validate: obj.status === 'running' || obj.status === 'stop_fail',
  134. }
  135. },
  136. },
  137. // 推送配置
  138. {
  139. label: i18n.t('compute.sync_config'),
  140. permission: 'server_perform_sync_config',
  141. action: () => {
  142. this.createDialog('VmSyncConfigDialog', {
  143. data: [obj],
  144. columns: this.columns,
  145. onManager: this.onManager,
  146. })
  147. },
  148. meta: () => {
  149. const ret = {
  150. validate: false,
  151. tooltip: null,
  152. }
  153. if (obj.status !== 'running' && obj.status !== 'ready') {
  154. ret.validate = false
  155. ret.tooltip = i18n.t('compute.text_1126')
  156. return ret
  157. }
  158. ret.validate = true
  159. return ret
  160. },
  161. hidden: () => this.$isScopedPolicyMenuHidden('vminstance_hidden_menus.server_perform_sync_config'),
  162. },
  163. ],
  164. },
  165. {
  166. label: i18n.t('compute.text_356'),
  167. submenus: [
  168. // 创建相同配置
  169. {
  170. label: i18n.t('compute.text_359'),
  171. permission: 'server_create',
  172. action: () => {
  173. this.$openNewWindowForMenuHook('vminstance_configured_callback_address.create_same_configuration_callback_address', () => {
  174. this.createDialog('VmContainerCloneDialog', {
  175. data: [obj],
  176. columns: this.columns,
  177. onManager: this.onManager,
  178. })
  179. })
  180. },
  181. meta: () => {
  182. const ret = {
  183. validate: false,
  184. tooltip: null,
  185. }
  186. const rescueModeValid = validateRescueMode(obj)
  187. if (!rescueModeValid.validate) return rescueModeValid
  188. if (obj.is_prepaid_recycle) {
  189. ret.tooltip = i18n.t('compute.text_285')
  190. return ret
  191. }
  192. if (obj.brand !== BRAND_MAP.OneCloud.key) {
  193. ret.tooltip = i18n.t('compute.text_473', [typeClouds.hypervisorMap[obj.hypervisor]?.label || ''])
  194. return ret
  195. }
  196. ret.validate = true
  197. return ret
  198. },
  199. },
  200. // 更改项目
  201. {
  202. label: this.$t('compute.perform_change_owner', [this.$t('dictionary.project')]),
  203. action: (obj) => {
  204. this.createDialog('ChangeOwenrDialog', {
  205. data: [obj],
  206. columns: this.columns,
  207. onManager: this.onManager,
  208. refresh: this.refresh,
  209. resource: 'servers',
  210. })
  211. },
  212. },
  213. // 到期释放
  214. {
  215. label: i18n.t('compute.text_1132'),
  216. action: () => {
  217. this.createDialog('SetDurationDialog', {
  218. data: [obj],
  219. columns: this.columns,
  220. onManager: this.onManager,
  221. name: i18n.t('compute.vminstance-container'),
  222. alert: i18n.t('compute.repo.helper.set_duration.alert'),
  223. refresh: this.refresh,
  224. })
  225. },
  226. meta: () => {
  227. const ret = { validate: true }
  228. if (obj.billing_type === 'prepaid') {
  229. ret.validate = false
  230. ret.tooltip = i18n.t('compute.text_285')
  231. return ret
  232. }
  233. return ret
  234. },
  235. },
  236. // 加入反亲和组
  237. {
  238. label: i18n.t('compute.text_1181', [i18n.t('dictionary.instancegroup')]),
  239. permission: 'server_perform_bind_groups,server_perform_unbind_groups',
  240. action: () => {
  241. this.createDialog('VmContainerBindInstanceGroupDialog', {
  242. data: [obj],
  243. columns: this.columns,
  244. onManager: this.onManager,
  245. refresh: this.refresh,
  246. name: i18n.t('dictionary.server_container'),
  247. })
  248. },
  249. meta: () => {
  250. const provider = obj.provider
  251. const ret = {
  252. validate: false,
  253. tooltip: null,
  254. }
  255. const rescueModeValid = validateRescueMode(obj)
  256. if (!rescueModeValid.validate) return rescueModeValid
  257. if (obj.brand !== BRAND_MAP.OneCloud.key) {
  258. ret.tooltip = i18n.t('compute.text_473', [PROVIDER_MAP[provider].label])
  259. return ret
  260. }
  261. if (!['running', 'ready'].includes(obj.status)) {
  262. ret.tooltip = i18n.t('compute.text_1126')
  263. return ret
  264. }
  265. if (obj.backup_host_id) {
  266. ret.tooltip = i18n.t('compute.text_1283')
  267. return ret
  268. }
  269. ret.validate = true
  270. return ret
  271. },
  272. },
  273. ],
  274. },
  275. {
  276. label: i18n.t('compute.group_action.update_config'),
  277. submenus: [
  278. // 调整配置
  279. {
  280. label: i18n.t('compute.text_1100'),
  281. action: (obj) => {
  282. this.$router.push({
  283. name: 'VMContainerInstanceAdjustConfig',
  284. query: {
  285. id: obj.id,
  286. },
  287. })
  288. },
  289. meta: (obj) => {
  290. const ret = {
  291. validate: true,
  292. tooltip: null,
  293. }
  294. if (obj.status !== 'ready') {
  295. ret.tooltip = this.$t('compute.repo.helper.change_config')
  296. ret.validate = false
  297. }
  298. return ret
  299. },
  300. },
  301. // 设置GPU卡
  302. {
  303. label: i18n.t('compute.text_1112'),
  304. permission: 'server_perform_set_isolated_device,attach-isolated-device,server_perform_detach_isolated_device',
  305. action: () => {
  306. this.createDialog('VmContainerAttachGpuDialog', {
  307. data: [obj],
  308. columns: this.columns,
  309. onManager: this.onManager,
  310. })
  311. },
  312. // meta: () => {
  313. // const provider = obj.provider
  314. // const ret = {
  315. // validate: false,
  316. // tooltip: null,
  317. // }
  318. // const rescueModeValid = validateRescueMode(obj)
  319. // if (!rescueModeValid.validate) return rescueModeValid
  320. // if (!this.isAdminMode && !this.isDomainMode) {
  321. // ret.tooltip = i18n.t('compute.text_1279', [i18n.t('dictionary.domain')])
  322. // return ret
  323. // }
  324. // if (obj.brand !== BRAND_MAP.OneCloud.key) {
  325. // ret.tooltip = i18n.t('compute.text_473', [PROVIDER_MAP[provider].label])
  326. // return ret
  327. // }
  328. // ret.validate = cloudEnabled('acttachGpu', obj)
  329. // ret.tooltip = cloudUnabledTip('acttachGpu', obj)
  330. // return ret
  331. // },
  332. },
  333. ],
  334. },
  335. {
  336. label: i18n.t('compute.text_1290'),
  337. submenus: [
  338. // 关联安全组
  339. {
  340. label: i18n.t('compute.text_1116'),
  341. permissionLabels: [i18n.t('compute.text_1116'), i18n.t('compute.revoke_secgroup'), i18n.t('compute.set_secgroup')],
  342. permission: 'server_perform_add_secgroup,server_perform_revoke_secgroup,server_perform_set_secgroup',
  343. action: () => {
  344. this.createDialog('VmSetSecgroupDialog', {
  345. vm: this,
  346. data: [obj],
  347. columns: this.columns,
  348. onManager: this.onManager,
  349. refresh: this.refresh,
  350. })
  351. },
  352. meta: () => {
  353. const rescueModeValid = validateRescueMode(obj)
  354. if (!rescueModeValid.validate) return rescueModeValid
  355. const ret = {
  356. validate: cloudEnabled('assignSecgroup', obj),
  357. tooltip: cloudUnabledTip('assignSecgroup', obj),
  358. }
  359. return ret
  360. },
  361. },
  362. // 设置源/目标检查
  363. {
  364. label: i18n.t('compute.text_1124'),
  365. permission: 'server_perform_modify_src_check',
  366. action: () => {
  367. this.createDialog('VmContainerSourceTargetCheckDialog', {
  368. data: [obj],
  369. columns: this.columns,
  370. onManager: this.onManager,
  371. refresh: this.refresh,
  372. })
  373. },
  374. meta: () => {
  375. const provider = obj.provider
  376. const ret = { validate: true, tooltip: null }
  377. const rescueModeValid = validateRescueMode(obj)
  378. if (!rescueModeValid.validate) return rescueModeValid
  379. if (obj.brand !== BRAND_MAP.OneCloud.key) {
  380. ret.validate = false
  381. ret.tooltip = i18n.t('compute.text_473', [PROVIDER_MAP[provider].label])
  382. return ret
  383. }
  384. if (!['running', 'ready'].includes(obj.status)) {
  385. ret.validate = false
  386. ret.tooltip = i18n.t('compute.text_1126')
  387. return ret
  388. }
  389. return ret
  390. },
  391. },
  392. // 绑定eip
  393. {
  394. label: i18n.t('compute.text_1179'),
  395. permission: 'server_perform_create_eip',
  396. action: () => {
  397. this.createDialog('VmBindEipDialog', {
  398. data: [obj],
  399. columns: this.columns,
  400. refresh: this.refresh,
  401. onManager: this.onManager,
  402. })
  403. },
  404. meta: () => {
  405. const ret = {
  406. validate: false,
  407. tooltip: null,
  408. }
  409. const rescueModeValid = validateRescueMode(obj)
  410. if (!rescueModeValid.validate) return rescueModeValid
  411. if (commonUnabled(obj)) return ret
  412. if (obj.eip_mode === 'public_ip' && obj.hypervisor !== 'aws') {
  413. ret.tooltip = i18n.t('compute.public_ip_tooltip')
  414. return ret
  415. }
  416. if (obj.eip_mode !== 'public_ip' && obj.eip) {
  417. ret.tooltip = i18n.t('compute.text_1291')
  418. return ret
  419. }
  420. if (obj.brand === 'OneCloud' && obj.vpc_id === 'default') {
  421. ret.tooltip = i18n.t('compute.text_1292')
  422. return ret
  423. }
  424. if (obj.vpc_external_access_mode === 'none') {
  425. ret.tooltip = i18n.t('compute.disable_bind_eip')
  426. return ret
  427. }
  428. ret.validate = cloudEnabled('bindEip', obj)
  429. ret.tooltip = cloudUnabledTip('bindEip', obj)
  430. return ret
  431. },
  432. hidden: () => !(hasSetupKey(['onecloud', 'cloudpods'])),
  433. },
  434. // 解绑eip
  435. {
  436. label: i18n.t('compute.text_1264'),
  437. permission: 'server_perform_dissociate_eip',
  438. action: () => {
  439. this.createDialog('VmUnbindEipDialog', {
  440. data: [obj],
  441. columns: this.columns,
  442. onManager: this.onManager,
  443. refresh: this.refresh,
  444. })
  445. },
  446. meta: () => {
  447. const ret = {
  448. validate: false,
  449. tooltip: null,
  450. }
  451. const rescueModeValid = validateRescueMode(obj)
  452. if (!rescueModeValid.validate) return rescueModeValid
  453. if (commonUnabled(obj)) return ret
  454. if (obj.eip_mode !== 'elastic_ip') {
  455. ret.tooltip = i18n.t('compute.text_1293')
  456. return ret
  457. }
  458. if (obj.eip_mode === 'public_ip') {
  459. ret.tooltip = i18n.t('compute.text_1294')
  460. return ret
  461. }
  462. ret.validate = cloudEnabled('unbindEip', obj)
  463. ret.tooltip = cloudUnabledTip('unbindEip', obj)
  464. return ret
  465. },
  466. hidden: () => !(hasSetupKey(['onecloud', 'cloudpods'])),
  467. },
  468. ],
  469. },
  470. {
  471. label: i18n.t('compute.perform_delete'),
  472. submenus: [
  473. // 设置删除保护
  474. disableDeleteAction(Object.assign(this, {}), {
  475. name: i18n.t('compute.vminstance-container'),
  476. meta: () => {
  477. const ret = { validate: true }
  478. return ret
  479. },
  480. }),
  481. // 删除
  482. {
  483. label: i18n.t('compute.perform_delete'),
  484. action: () => {
  485. this.createDialog('DeleteVmContainerDialog', {
  486. vm: this,
  487. data: [obj],
  488. columns: this.columns,
  489. onManager: this.onManager,
  490. title: i18n.t('compute.perform_delete'),
  491. success: () => {
  492. this.destroySidePages()
  493. },
  494. })
  495. },
  496. meta: () => {
  497. return this.$getDeleteResult(obj)
  498. },
  499. },
  500. ],
  501. },
  502. ]
  503. },
  504. meta: (obj) => {
  505. let ret = {
  506. validate: true,
  507. tooltip: null,
  508. }
  509. ret = this.$isValidateResourceLock(obj)
  510. return ret
  511. },
  512. },
  513. ]
  514. }
  515. export default {
  516. // name: POLICY_RES_NAME_KEY_MAP.vminstance.key,
  517. getSingleActions,
  518. }