singleActions.js 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618
  1. import { mapGetters } from 'vuex'
  2. import { diskResizeConfig, diskCreateSnapshotConfig } from '@Compute/views/disk/utils'
  3. import i18n from '@/locales'
  4. import { BRAND_MAP, PROVIDER_MAP, HYPERVISORS_MAP } from '@/constants'
  5. import { getDisabledProvidersActionMeta } from '@/utils/common/hypervisor'
  6. import { hasSetupKey } from '@/utils/auth'
  7. import { STORAGE_TYPES } from '@Compute/constants'
  8. const supportShpolcyBrand = ['OneCloud', 'Qcloud', 'Aliyun']
  9. export default {
  10. computed: {
  11. ...mapGetters(['isAdminMode']),
  12. },
  13. created () {
  14. this.singleActions = [
  15. {
  16. label: i18n.t('compute.disk_perform_resize'),
  17. permission: 'disks_perform_resize',
  18. action: obj => {
  19. this.createDialog('DiskCapacityUpdateDialog', {
  20. data: [obj],
  21. columns: this.columns,
  22. refresh: this.refresh,
  23. })
  24. },
  25. meta: obj => {
  26. const provider = obj.provider?.toLowerCase()
  27. if (diskResizeConfig[provider]) {
  28. return {
  29. validate: diskResizeConfig[provider](obj).validate,
  30. tooltip: diskResizeConfig[provider](obj).tooltip,
  31. }
  32. }
  33. if (obj.status === 'migrating') {
  34. return {
  35. validate: false,
  36. tooltip: i18n.t('compute.disk_migrating_tip'),
  37. }
  38. }
  39. return {
  40. validate: true,
  41. }
  42. },
  43. extraMeta: obj => {
  44. return getDisabledProvidersActionMeta({
  45. row: obj,
  46. disabledProviders: ['BingoCloud', 'SangFor'],
  47. })
  48. },
  49. hidden: () => this.$isScopedPolicyMenuHidden('disk_hidden_menus.disk_perform_resize'),
  50. },
  51. {
  52. label: i18n.t('compute.text_352'),
  53. actions: obj => {
  54. return [
  55. {
  56. label: i18n.t('compute.disk_perform_attach'),
  57. permission: 'disks_perform_attachdisk',
  58. action: () => {
  59. this.createDialog('DiskMountUpdateDialog', {
  60. data: [obj],
  61. columns: this.columns,
  62. refresh: this.refresh,
  63. })
  64. },
  65. meta: () => {
  66. const ret = {
  67. validate: false,
  68. tooltip: '',
  69. }
  70. if (obj.cloud_env === 'onpremise' || obj.cloud_env === 'private' || obj.cloud_env === 'public') {
  71. // if (obj.storage_type === 'local') {
  72. // ret.tooltip = i18n.t('compute.text_442')
  73. // return ret
  74. // }
  75. ret.validate = !obj.guest && obj.status === 'ready'
  76. if (obj.guest) {
  77. ret.tooltip = i18n.t('compute.text_443')
  78. } else {
  79. if (obj.status === 'ready') {
  80. ret.tooltip = ''
  81. } else {
  82. ret.tooltip = i18n.t('compute.text_444')
  83. }
  84. }
  85. return ret
  86. }
  87. ret.validate = true
  88. return ret
  89. },
  90. extraMeta: obj => {
  91. return getDisabledProvidersActionMeta({
  92. row: obj,
  93. disabledProviders: ['BingoCloud', 'SangFor'],
  94. })
  95. },
  96. hidden: () => this.$isScopedPolicyMenuHidden('disk_hidden_menus.disk_perform_attach'),
  97. },
  98. {
  99. label: i18n.t('compute.disk_perform_detach'),
  100. permission: 'disks_perform_detachdisk',
  101. action: () => {
  102. this.createDialog('DiskUnMountUpdateDialog', {
  103. data: [obj],
  104. columns: this.columns,
  105. list: this.list,
  106. refresh: this.refresh,
  107. })
  108. },
  109. meta: () => {
  110. if (obj.status === 'unknown') {
  111. return {
  112. validate: true,
  113. tooltip: '',
  114. }
  115. }
  116. if (obj.status === 'migrating') {
  117. return {
  118. validate: false,
  119. tooltip: i18n.t('compute.disk_migrating_tip'),
  120. }
  121. }
  122. // if (obj.brand) {
  123. // const brand = obj.brand.toLowerCase()
  124. // if (brand === 'vmware' && obj.disk_type === 'data') {
  125. // return {
  126. // validate: false,
  127. // tooltip: i18n.t('compute.text_1287', [BRAND_MAP[obj.brand].label]),
  128. // }
  129. // }
  130. // }
  131. if (!obj.guest) {
  132. return {
  133. validate: !!obj.guest,
  134. tooltip: i18n.t('compute.text_445'),
  135. }
  136. }
  137. // if (obj.cloud_env === 'onpremise' && obj.storage_type === 'local') {
  138. // return {
  139. // validate: false,
  140. // tooltip: i18n.t('compute.text_446'),
  141. // }
  142. // }
  143. if (obj.guests && obj.guests.length > 1) {
  144. return {
  145. validate: false,
  146. tooltip: i18n.t('compute.disk_mount_mulitple_guest'),
  147. }
  148. }
  149. // if (obj.guests && obj.guests.length === 1 && obj.guests[0].index === 0 && obj.guests[0].hyppervisor === '') {
  150. if (obj.disk_type === 'sys') {
  151. // system disk
  152. return {
  153. validate: false,
  154. tooltip: i18n.t('compute.text_447'),
  155. }
  156. }
  157. if (obj.portable && obj.portable === false) {
  158. return {
  159. validate: false,
  160. tooltip: i18n.t('compute.text_448'),
  161. }
  162. }
  163. return {
  164. validate: true,
  165. tooltip: '',
  166. }
  167. },
  168. extraMeta: obj => {
  169. return getDisabledProvidersActionMeta({
  170. row: obj,
  171. disabledProviders: ['BingoCloud', 'SangFor'],
  172. })
  173. },
  174. hidden: () => this.$isScopedPolicyMenuHidden('disk_hidden_menus.disk_perform_detach'),
  175. },
  176. {
  177. label: i18n.t('compute.disk_perform_create_snapshot'),
  178. permission: 'snapshots_create',
  179. action: () => {
  180. this.createDialog('DiskCreateSnapshotDialog', {
  181. data: [obj],
  182. columns: this.columns,
  183. refresh: this.refresh,
  184. })
  185. },
  186. meta: () => {
  187. const ret = { validate: true }
  188. const provider = obj.provider?.toLowerCase()
  189. if (provider) {
  190. const { validate, tooltip } = diskCreateSnapshotConfig[provider](obj)
  191. ret.validate = validate
  192. ret.tooltip = tooltip
  193. }
  194. if (obj.status === 'migrating') {
  195. ret.validate = false
  196. ret.tooltip = i18n.t('compute.disk_migrating_tip')
  197. return ret
  198. }
  199. return ret
  200. },
  201. extraMeta: obj => {
  202. return getDisabledProvidersActionMeta({
  203. row: obj,
  204. disabledProviders: ['BingoCloud', 'SangFor'],
  205. })
  206. },
  207. hidden: () => this.$isScopedPolicyMenuHidden('disk_hidden_menus.disk_perform_create_snapshot'),
  208. },
  209. {
  210. label: i18n.t('compute.vminstance.change_disk_storage'),
  211. action: () => {
  212. this.createDialog('DiskChangeBlockStorageDialog', {
  213. data: [obj],
  214. columns: this.columns,
  215. onManager: this.onManager,
  216. refresh: this.refresh,
  217. })
  218. },
  219. meta: () => {
  220. const guestStatus = ['running', 'ready']
  221. const ret = {
  222. validate: true,
  223. }
  224. if (obj.brand !== BRAND_MAP.OneCloud.key) {
  225. ret.validate = false
  226. ret.tooltip = i18n.t('compute.text_1287', [BRAND_MAP[obj.brand]?.label])
  227. }
  228. if (this.isProjectMode) {
  229. ret.tooltip = this.$t('compute.text_1279', [this.$t('dictionary.domain')])
  230. ret.validate = false
  231. }
  232. if (!obj.guest) {
  233. ret.validate = false
  234. } else {
  235. if (!guestStatus.includes(obj.guest_status)) {
  236. ret.validate = false
  237. }
  238. }
  239. return ret
  240. },
  241. hidden: () => this.$isScopedPolicyMenuHidden('disk_hidden_menus.disk_perform_change_disk_storage'),
  242. },
  243. {
  244. label: i18n.t('compute.vminstance.change_storage_type'),
  245. action: () => {
  246. this.createDialog('DiskChangeStorageTypeDialog', {
  247. data: [obj],
  248. columns: this.columns,
  249. onManager: this.onManager,
  250. refresh: this.refresh,
  251. })
  252. },
  253. meta: () => {
  254. const ret = {
  255. validate: true,
  256. }
  257. if (obj.brand !== BRAND_MAP.Aliyun.key) {
  258. ret.validate = false
  259. ret.tooltip = i18n.t('compute.text_1287', [BRAND_MAP[obj.brand]?.label])
  260. return ret
  261. }
  262. if (!STORAGE_TYPES.aliyun[obj.storage_type] || !STORAGE_TYPES.aliyun[obj.storage_type].supportChangeStorageType) {
  263. ret.validate = false
  264. ret.tooltip = i18n.t('compute.disk_storage_type_disable_tip')
  265. return ret
  266. }
  267. if (obj.disk_type === 'sys' && !obj.guest_count) {
  268. ret.validate = false
  269. ret.tooltip = i18n.t('compute.disk_change_storage_type.sys_disk_tip')
  270. return ret
  271. }
  272. if (obj.disk_type === 'data') {
  273. if (!obj.guest_count && obj.status !== 'ready') {
  274. ret.validate = false
  275. ret.tooltip = i18n.t('compute.disk_change_storage_type.data_disk_tip')
  276. return ret
  277. }
  278. }
  279. return ret
  280. },
  281. hidden: () => this.$isScopedPolicyMenuHidden('disk_hidden_menus.disk_perform_change_storage_type'),
  282. },
  283. {
  284. label: i18n.t('compute.create_disk_backup'),
  285. action: () => {
  286. this.createDialog('DiskCreateBackupDialog', {
  287. data: [obj],
  288. columns: this.columns,
  289. refresh: this.refresh,
  290. })
  291. },
  292. meta: () => {
  293. const guestStatus = ['running', 'ready']
  294. if (obj.cloud_env === 'public') {
  295. return {
  296. validate: false,
  297. }
  298. }
  299. if (obj.guest && !guestStatus.includes(obj.guest_status)) {
  300. return {
  301. validate: false,
  302. }
  303. }
  304. if (!obj.guest && obj.storage_type === 'local') {
  305. return {
  306. validate: false,
  307. tooltip: '',
  308. }
  309. }
  310. return {
  311. validate: true,
  312. tooltip: '',
  313. }
  314. },
  315. extraMeta: obj => {
  316. return getDisabledProvidersActionMeta({
  317. row: obj,
  318. disabledProviders: ['BingoCloud', 'VolcEngine', 'SangFor', 'ZettaKit', 'UIS'],
  319. })
  320. },
  321. hidden: () => this.$isScopedPolicyMenuHidden('disk_hidden_menus.disk_perform_create_backup'),
  322. },
  323. {
  324. label: i18n.t('compute.disk_perform_setup_snapshot_policy'),
  325. permission: 'snapshotpolicy_delete',
  326. action: () => {
  327. this.createDialog('DiskSetSnapshotDialog', {
  328. vm: this,
  329. data: [obj],
  330. columns: this.columns,
  331. refresh: this.refresh,
  332. onManager: this.onManager,
  333. })
  334. },
  335. meta: () => {
  336. if (obj.status !== 'ready') {
  337. return {
  338. validate: false,
  339. tooltip: i18n.t('compute.text_449'),
  340. }
  341. }
  342. if (obj.brand) {
  343. const brand = obj.brand.toLowerCase()
  344. if (brand === 'vmware') {
  345. return {
  346. validate: false,
  347. tooltip: i18n.t('compute.text_450'),
  348. }
  349. }
  350. if (brand === 'ctyun') {
  351. return {
  352. validate: false,
  353. tooltip: i18n.t('compute.text_451'),
  354. }
  355. }
  356. if (brand === 'openstack') {
  357. if (obj.storage_type !== 'local' && obj.storage_type !== 'iscsi') {
  358. return {
  359. validate: false,
  360. tooltip: i18n.t('compute.text_452'),
  361. }
  362. }
  363. } else {
  364. if (!obj.guest_count) {
  365. return {
  366. validate: false,
  367. tooltip: i18n.t('compute.text_453'),
  368. }
  369. }
  370. }
  371. if (brand === 'ucloud') {
  372. if (obj.storage_type !== 'CLOUD_NORMAL') {
  373. return {
  374. validate: false,
  375. tooltip: i18n.t('compute.text_454'),
  376. }
  377. }
  378. }
  379. }
  380. if (obj.guest_status !== 'running' && obj.guest_status !== 'ready') {
  381. return {
  382. validate: false,
  383. tooltip: i18n.t('compute.text_455'),
  384. }
  385. }
  386. if (!supportShpolcyBrand.includes(obj.brand)) {
  387. const newSupportShpolcyBrand = supportShpolcyBrand.map(v => {
  388. if (v === 'OneCloud') {
  389. return i18n.t('brand')
  390. }
  391. return v
  392. })
  393. return {
  394. validate: false,
  395. tooltip: i18n.t('compute.text_456', [newSupportShpolcyBrand.join('、')]),
  396. }
  397. }
  398. if (obj.snapshotpolicy_status === 'deleting' || obj.snapshotpolicy_status === 'init') {
  399. return {
  400. validate: false,
  401. tooltip: i18n.t('compute.text_457'),
  402. }
  403. }
  404. return {
  405. validate: true,
  406. }
  407. },
  408. extraMeta: obj => {
  409. return getDisabledProvidersActionMeta({
  410. row: obj,
  411. disabledProviders: ['BingoCloud', 'SangFor', 'ZettaKit', 'UIS'],
  412. })
  413. },
  414. hidden: () => this.$isScopedPolicyMenuHidden('disk_hidden_menus.disk_perform_setup_snapshot_policy'),
  415. },
  416. {
  417. label: i18n.t('compute.disk_set_auto_reset'),
  418. permission: 'disks_perform_bind_snapshotpolicy,disks_perform_unbind_snapshotpolicy',
  419. action: () => {
  420. this.createDialog('DiskSetAutoResetDialog', {
  421. vm: this,
  422. data: [obj],
  423. onManager: this.onManager,
  424. columns: this.columns,
  425. refresh: this.refresh,
  426. })
  427. },
  428. meta: (obj) => {
  429. const ret = {
  430. validate: false,
  431. tooltip: this.$t('cloudenv.brand_action_deny'),
  432. }
  433. if (obj.guest_status !== 'ready') {
  434. ret.tooltip = i18n.t('compute.text_1308')
  435. }
  436. if (obj.provider === HYPERVISORS_MAP.kvm.brand && obj.guest_status === 'ready') {
  437. ret.validate = true
  438. ret.tooltip = ''
  439. }
  440. return ret
  441. },
  442. hidden: () => this.$isScopedPolicyMenuHidden('disk_hidden_menus.disk_perform_auto_reset'),
  443. },
  444. {
  445. label: i18n.t('compute.driver.update'),
  446. permission: 'disks_update',
  447. action: () => {
  448. this.createDialog('DiskDriverUpdateDialog', {
  449. data: [obj],
  450. columns: this.columns,
  451. onManager: this.onManager,
  452. resource: 'disks',
  453. name: i18n.t('compute.text_100'),
  454. })
  455. },
  456. meta: () => {
  457. const ret = {
  458. validate: true,
  459. }
  460. if (!(obj.brand === HYPERVISORS_MAP.kvm.brand)) {
  461. ret.validate = false
  462. ret.tooltip = i18n.t('compute.text_1388')
  463. }
  464. if (!obj.guest) {
  465. ret.validate = false
  466. ret.tooltip = i18n.t('compute.disk_update_driver_prompt')
  467. }
  468. return ret
  469. },
  470. extraMeta: obj => {
  471. return getDisabledProvidersActionMeta({
  472. row: obj,
  473. disabledProviders: ['BingoCloud', 'SangFor', 'ZettaKit', 'UIS'],
  474. })
  475. },
  476. hidden: () => !this.isAdminMode,
  477. },
  478. {
  479. label: this.$t('compute.perform_change_owner', [this.$t('dictionary.project')]),
  480. permission: 'disks_perform_public',
  481. action: () => {
  482. this.createDialog('ChangeOwenrDialog', {
  483. data: [obj],
  484. columns: this.columns,
  485. onManager: this.onManager,
  486. refresh: this.refresh,
  487. resource: 'disks',
  488. })
  489. },
  490. meta: () => {
  491. const ret = {
  492. validate: false,
  493. tooltip: '',
  494. }
  495. if (this.isProjectMode) {
  496. ret.tooltip = this.$t('compute.text_1279', [this.$t('dictionary.domain')])
  497. return ret
  498. }
  499. return {
  500. validate: obj.guest_count < 1,
  501. tooltip: obj.guest ? i18n.t('compute.text_458', [i18n.t('dictionary.project')]) : '',
  502. }
  503. },
  504. extraMeta: obj => {
  505. return getDisabledProvidersActionMeta({
  506. row: obj,
  507. disabledProviders: ['BingoCloud', 'SangFor', 'ZettaKit', 'UIS'],
  508. })
  509. },
  510. hidden: () => this.$isScopedPolicyMenuHidden('disk_hidden_menus.disk_perform_change_project'),
  511. },
  512. {
  513. label: i18n.t('compute.perform_sync_status'),
  514. permission: 'disks_perform_syncstatus',
  515. action: () => {
  516. this.onManager('performAction', {
  517. steadyStatus: ['running', 'ready'],
  518. id: obj.id,
  519. managerArgs: {
  520. action: 'syncstatus',
  521. },
  522. })
  523. },
  524. meta: () => {
  525. var ret = {
  526. validate: true,
  527. tooltip: '',
  528. }
  529. if (obj.provider === PROVIDER_MAP.VMware.key) {
  530. ret.validate = false
  531. ret.tooltip = i18n.t('compute.text_473', [PROVIDER_MAP[obj.provider].label])
  532. return ret
  533. }
  534. if (obj.provider === PROVIDER_MAP.SangFor.key) {
  535. ret.validate = false
  536. ret.tooltip = i18n.t('compute.text_473', [PROVIDER_MAP[obj.provider].label])
  537. return ret
  538. }
  539. return ret
  540. },
  541. hidden: () => this.$isScopedPolicyMenuHidden('disk_hidden_menus.disk_perform_syncstatus'),
  542. },
  543. {
  544. label: i18n.t('compute.change_billing_type'),
  545. permission: 'disk_perform_change_billing_type',
  546. action: () => {
  547. this.createDialog('DiskChangeBillingTypeDialog', {
  548. steadyStatus: ['running', 'ready'],
  549. data: [obj],
  550. columns: this.columns,
  551. onManager: this.onManager,
  552. refresh: this.refresh,
  553. })
  554. },
  555. meta: () => {
  556. const ret = {
  557. validate: false,
  558. tooltip: null,
  559. }
  560. if (obj.brand !== BRAND_MAP.Aliyun.key) {
  561. ret.tooltip = i18n.t('compute.text_473', [PROVIDER_MAP[obj.provider].label])
  562. return ret
  563. }
  564. if (obj.status !== 'ready') {
  565. ret.validate = false
  566. ret.tooltip = i18n.t('compute.text_1048')
  567. return ret
  568. }
  569. if (!obj.guest_count) {
  570. ret.validate = false
  571. ret.tooltip = i18n.t('compute.text_453')
  572. return ret
  573. }
  574. if (obj.disk_type === 'sys') {
  575. ret.validate = false
  576. ret.tooltip = i18n.t('compute.sys_disk_disable_action')
  577. return ret
  578. }
  579. if (obj.billing_type === 'postpaid' && obj.guest_billing_type === 'postpaid') {
  580. ret.validate = false
  581. ret.tooltip = i18n.t('compute.postpaid_disk_change_billing_type_tip')
  582. return ret
  583. }
  584. ret.validate = true
  585. return ret
  586. },
  587. hidden: () => !(hasSetupKey(['aliyun'])) || this.$isScopedPolicyMenuHidden('disk_hidden_menus.disk_perform_change_billing_type'),
  588. },
  589. {
  590. label: i18n.t('compute.perform_delete'),
  591. permission: 'disks_delete',
  592. action: () => {
  593. this.createDialog('DiskDeleteDialog', {
  594. data: [obj],
  595. columns: this.columns,
  596. title: i18n.t('compute.perform_delete'),
  597. onManager: this.onManager,
  598. success: () => {
  599. this.destroySidePage(this.windowId)
  600. },
  601. })
  602. },
  603. meta: () => this.$getDeleteResult(obj),
  604. extraMeta: obj => {
  605. return getDisabledProvidersActionMeta({
  606. row: obj,
  607. disabledProviders: ['BingoCloud', 'SangFor'],
  608. })
  609. },
  610. hidden: () => this.$isScopedPolicyMenuHidden('disk_hidden_menus.disk_delete'),
  611. },
  612. ]
  613. },
  614. },
  615. ]
  616. },
  617. }