diff --git a/src/locales/en.json b/src/locales/en.json index 66b5f738..13334fc7 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -2375,6 +2375,7 @@ "The private key content format is: with \"-----BEGIN RSA PRIVATE KEY-----\" as the beginning,\"-----END RSA PRIVATE KEY-----\" as the end, 64 characters per line, the last line does not exceed 64 characters, and there cannot be blank lines.": "The private key content format is: with \"-----BEGIN RSA PRIVATE KEY-----\" as the beginning,\"-----END RSA PRIVATE KEY-----\" as the end, 64 characters per line, the last line does not exceed 64 characters, and there cannot be blank lines.", "The private key of the certificate, the extension of the private key is \"key\", you can directly enter the content of the private key file or upload a private key that conforms to the format document.": "The private key of the certificate, the extension of the private key is \"key\", you can directly enter the content of the private key file or upload a private key that conforms to the format document.", "The resource class of the scheduled node needs to correspond to the resource class name of the flavor used by the ironic instance (for example, the resource class name of the scheduling node is baremetal.with-GPU, and the custom resource class name of the flavor is CUSTOM_BAREMETAL_WITH_GPU=1).": "The resource class of the scheduled node needs to correspond to the resource class name of the flavor used by the ironic instance (for example, the resource class name of the scheduling node is baremetal.with-GPU, and the custom resource class name of the flavor is CUSTOM_BAREMETAL_WITH_GPU=1).", + "The resource has been deleted": "The resource has been deleted", "The root and os_admin are default users and cannot be created!": "The root and os_admin are default users and cannot be created!", "The security group is similar to the firewall function and is used to set up network access control. ": "The security group is similar to the firewall function and is used to set up network access control. ", "The security group is similar to the firewall function for setting up network access control, or you can go to the console and create a new security group. (Note: The security group you selected will work on all virtual LANS on the instances.)": "The security group is similar to the firewall function for setting up network access control, or you can go to the console and create a new security group. (Note: The security group you selected will work on all virtual LANS on the instances.)", diff --git a/src/locales/zh.json b/src/locales/zh.json index 2ed73845..5783dd19 100644 --- a/src/locales/zh.json +++ b/src/locales/zh.json @@ -2375,6 +2375,7 @@ "The private key content format is: with \"-----BEGIN RSA PRIVATE KEY-----\" as the beginning,\"-----END RSA PRIVATE KEY-----\" as the end, 64 characters per line, the last line does not exceed 64 characters, and there cannot be blank lines.": "私钥内容格式为:以“-----BEGIN RSA PRIVATE KEY-----”,以“-----END RSA PRIVATE KEY-----”作为结尾,每行64字符,最后一行不超过64字符,不能有空行。", "The private key of the certificate, the extension of the private key is \"key\", you can directly enter the content of the private key file or upload a private key that conforms to the format document.": "证书的私钥,私钥扩展名为”key”,您可直接输入私钥文件内容或上传符合格式的私钥文件。", "The resource class of the scheduled node needs to correspond to the resource class name of the flavor used by the ironic instance (for example, the resource class name of the scheduling node is baremetal.with-GPU, and the custom resource class name of the flavor is CUSTOM_BAREMETAL_WITH_GPU=1).": "被调度节点的资源类需要与裸机实例使用的云主机类型的资源类名称对应(比如:调度节点的资源类名称为 baremetal.with-GPU,云主机类型的资源类名称为CUSTOM_BAREMETAL_WITH_GPU=1 )。", + "The resource has been deleted": "该资源已被删除", "The root and os_admin are default users and cannot be created!": "root 和 os_admin 是默认用户,不能创建!", "The security group is similar to the firewall function and is used to set up network access control. ": "安全组类似防火墙功能,用于设置网络访问控制。", "The security group is similar to the firewall function for setting up network access control, or you can go to the console and create a new security group. (Note: The security group you selected will work on all virtual LANS on the instances.)": "安全组类似防火墙功能,用于设置网络访问控制,您也可以前往控制台新建安全组。(注:您所选的安全组将作用于云主机的全部虚拟网卡。)", diff --git a/src/pages/container-infra/containers/ClusterTemplates/Detail/BaseDetail.jsx b/src/pages/container-infra/containers/ClusterTemplates/Detail/BaseDetail.jsx index 3ec41a66..f1b19d45 100644 --- a/src/pages/container-infra/containers/ClusterTemplates/Detail/BaseDetail.jsx +++ b/src/pages/container-infra/containers/ClusterTemplates/Detail/BaseDetail.jsx @@ -70,13 +70,20 @@ export class BaseDetail extends Base { get networkCard() { const { external_network_id, + original_external_network_id, externalNetwork: { name: externalName } = {}, fixed_network, + original_fixed_network, fixedNetwork: { name: fixedName } = {}, fixed_subnet, + original_fixed_subnet, fixedSubnet: { name: subName } = {}, } = this.detailData || {}; - const externalNetworkUrl = external_network_id + const externalNetworkUrl = original_external_network_id + ? `${original_external_network_id} (${t( + 'The resource has been deleted' + )})` + : external_network_id ? this.getLinkRender( 'networkDetail', externalName || external_network_id, @@ -85,18 +92,21 @@ export class BaseDetail extends Base { } ) : '-'; - const fixedNetworkUrl = fixed_network + const fixedNetworkUrl = original_fixed_network + ? `${original_fixed_network} (${t('The resource has been deleted')})` + : fixed_network ? this.getLinkRender('networkDetail', fixedName || fixed_network, { id: fixed_network, }) : '-'; - const subnetUrl = - fixed_network && fixed_subnet - ? this.getLinkRender('subnetDetail', subName || fixed_subnet, { - networkId: fixed_network, - id: fixed_subnet, - }) - : '-'; + const subnetUrl = original_fixed_subnet + ? `${original_fixed_subnet} (${t('The resource has been deleted')})` + : fixed_network && fixed_subnet + ? this.getLinkRender('subnetDetail', subName || fixed_subnet, { + networkId: fixed_network, + id: fixed_subnet, + }) + : '-'; const options = [ { @@ -152,15 +162,20 @@ export class BaseDetail extends Base { get specCard() { const { image_id, + original_image_id, image: { name: imageName } = {}, keypair_id, flavor_id, + original_flavor_id, flavor: { name: flavorName } = {}, master_flavor_id, + original_master_flavor_id, masterFlavor: { name: masterFlavorName } = {}, selfKeypair, } = this.detailData; - const imageUrl = image_id + const imageUrl = original_image_id + ? `${original_image_id} (${t('The resource has been deleted')})` + : image_id ? this.getLinkRender('imageDetail', imageName || image_id, { id: image_id, }) @@ -173,13 +188,17 @@ export class BaseDetail extends Base { }) : keypair_id || '-'; - const flavorUrl = flavor_id + const flavorUrl = original_flavor_id + ? `${original_flavor_id} (${t('The resource has been deleted')})` + : flavor_id ? this.getLinkRender('flavorDetail', flavorName || flavor_id, { id: flavor_id, }) : '-'; - const masterFlavorUrl = master_flavor_id + const masterFlavorUrl = original_master_flavor_id + ? `${original_master_flavor_id} (${t('The resource has been deleted')})` + : master_flavor_id ? this.getLinkRender( 'flavorDetail', masterFlavorName || master_flavor_id, diff --git a/src/pages/container-infra/containers/ClusterTemplates/actions/StepCreate/StepNodeSpec/index.jsx b/src/pages/container-infra/containers/ClusterTemplates/actions/StepCreate/StepNodeSpec/index.jsx index 76b08078..c3288d14 100644 --- a/src/pages/container-infra/containers/ClusterTemplates/actions/StepCreate/StepNodeSpec/index.jsx +++ b/src/pages/container-infra/containers/ClusterTemplates/actions/StepCreate/StepNodeSpec/index.jsx @@ -21,6 +21,7 @@ import { FlavorStore } from 'src/stores/nova/flavor'; import { getImageColumns } from 'resources/glance/image'; import { getKeyPairHeader } from 'resources/nova/keypair'; import { getBaseSimpleFlavorColumns } from 'resources/magnum/template'; +import { allSettled } from 'utils'; export class StepNodeSpec extends Base { init() { @@ -48,7 +49,7 @@ export class StepNodeSpec extends Base { } async getAllInitFunctions() { - await Promise.all([ + await allSettled([ this.getImageList(), this.getKeypairs(), this.getFlavors(), diff --git a/src/pages/container-infra/containers/Clusters/Detail/BaseDetail.jsx b/src/pages/container-infra/containers/Clusters/Detail/BaseDetail.jsx index 9eaa36bd..01146008 100644 --- a/src/pages/container-infra/containers/Clusters/Detail/BaseDetail.jsx +++ b/src/pages/container-infra/containers/Clusters/Detail/BaseDetail.jsx @@ -61,22 +61,27 @@ export class BaseDetail extends Base { get networkCard() { const { fixed_network, + original_fixed_network, fixedNetwork: { name: fixedName } = {}, fixed_subnet, + original_fixed_subnet, fixedSubnet: { name: subName } = {}, } = this.detailData || {}; - const fixedNetworkUrl = fixed_network + const fixedNetworkUrl = original_fixed_network + ? `${original_fixed_network} (${t('The resource has been deleted')})` + : fixed_network ? this.getLinkRender('networkDetail', fixedName || fixed_network, { id: fixed_network, }) : '-'; - const subnetUrl = - fixed_network && fixed_subnet - ? this.getLinkRender('subnetDetail', subName || fixed_subnet, { - networkId: fixed_network, - id: fixed_subnet, - }) - : '-'; + const subnetUrl = original_fixed_subnet + ? `${original_fixed_subnet} (${t('The resource has been deleted')})` + : fixed_network && fixed_subnet + ? this.getLinkRender('subnetDetail', subName || fixed_subnet, { + networkId: fixed_network, + id: fixed_subnet, + }) + : '-'; const options = [ { @@ -151,12 +156,16 @@ export class BaseDetail extends Base { get nodesCard() { const { master_flavor_id, + original_master_flavor_id, masterFlavor: { name: masterFlavorName } = {}, flavor_id, + original_flavor_id, flavor: { name: flavorName } = {}, } = this.detailData; - const masterFlavorUrl = master_flavor_id + const masterFlavorUrl = original_master_flavor_id + ? `${original_master_flavor_id} (${t('The resource has been deleted')})` + : master_flavor_id ? this.getLinkRender( 'flavorDetail', masterFlavorName || master_flavor_id, @@ -166,7 +175,9 @@ export class BaseDetail extends Base { ) : '-'; - const flavorUrl = flavor_id + const flavorUrl = original_flavor_id + ? `${original_flavor_id} (${t('The resource has been deleted')})` + : flavor_id ? this.getLinkRender('flavorDetail', flavorName || flavor_id, { id: flavor_id, }) diff --git a/src/pages/container-infra/containers/Clusters/actions/StepCreate/StepNetworks/index.jsx b/src/pages/container-infra/containers/Clusters/actions/StepCreate/StepNetworks/index.jsx index 5ab60e99..4f75d8e3 100644 --- a/src/pages/container-infra/containers/Clusters/actions/StepCreate/StepNetworks/index.jsx +++ b/src/pages/container-infra/containers/Clusters/actions/StepCreate/StepNetworks/index.jsx @@ -19,11 +19,14 @@ import { inject, observer } from 'mobx-react'; import { defaultTip } from 'resources/magnum/cluster'; import { NetworkStore } from 'stores/neutron/network'; import { SubnetStore } from 'src/stores/neutron/subnet'; +import { ClusterTemplatesStore } from 'stores/magnum/clusterTemplates'; import { networkColumns, subnetColumns } from 'resources/neutron/network'; import { getLinkRender } from 'utils/route-map'; +import { allSettled } from 'utils'; export class StepNetworks extends Base { init() { + this.templateStore = new ClusterTemplatesStore(); this.networkStore = new NetworkStore(); this.subnetStore = new SubnetStore(); this.getAllInitFunctions(); @@ -40,21 +43,27 @@ export class StepNetworks extends Base { allowed = () => Promise.resolve(); async getAllInitFunctions() { - const { - context: { clusterTemplate = {} }, - } = this.props; - const { selectedRows = [] } = clusterTemplate; - const { fixed_network, fixed_subnet } = selectedRows[0] || {}; - await Promise.all([ + await allSettled([this.subnetStore.fetchList(), this.getTemplateDetail()]); + const { fixed_network, fixed_subnet } = this.templateDetail; + + await allSettled([ fixed_network ? this.networkStore.fetchDetail({ id: fixed_network }) : null, fixed_subnet ? this.subnetStore.fetchDetail({ id: fixed_subnet }) : null, - this.subnetStore.fetchList(), ]); this.updateDefaultValue(); } + getTemplateDetail() { + const { context: { clusterTemplate = {} } = {} } = this.props; + const { selectedRowKeys = [] } = clusterTemplate; + const templateId = selectedRowKeys[0]; + if (templateId) { + return this.templateStore.fetchDetail({ id: templateId }); + } + } + get network() { return toJS(this.networkStore.detail) || {}; } @@ -65,25 +74,23 @@ export class StepNetworks extends Base { get subnetList() { const { - context: { - clusterTemplate: { selectedRows: templateRows = [] } = {}, - fixedNetwork: { selectedRowKeys: contextKeys = [] } = {}, - }, + context: { fixedNetwork: { selectedRowKeys: contextKeys = [] } = {} }, } = this.props; - const { fixed_network } = templateRows[0] || {}; + const { fixed_network } = this.templateDetail; const key = contextKeys[0] || fixed_network; - return (this.subnetStore.list.data || []).filter( + return toJS(this.subnetStore.list.data || []).filter( (it) => key === it.network_id ); } + get templateDetail() { + return toJS(this.templateStore.detail) || {}; + } + get defaultValue() { - const { - context: { clusterTemplate = {}, fixedNetwork, fixedSubnet } = {}, - } = this.props; - const { selectedRows = [] } = clusterTemplate; - const { fixed_network, fixed_subnet } = selectedRows[0] || {}; + const { context: { fixedNetwork, fixedSubnet } = {} } = this.props; + const { fixed_network, fixed_subnet } = this.templateDetail; return { newNetwork: true, @@ -105,11 +112,8 @@ export class StepNetworks extends Base { get formItems() { const { newNetwork } = this.state; - const { - context: { clusterTemplate = {}, fixedNetwork, fixedSubnet } = {}, - } = this.props; - const { selectedRows = [] } = clusterTemplate; - const { fixed_network, fixed_subnet } = selectedRows[0] || {}; + const { context: { fixedNetwork, fixedSubnet } = {} } = this.props; + const { fixed_network, fixed_subnet } = this.templateDetail; const initFixedNetwork = fixedNetwork || { selectedRowKeys: fixed_network ? [fixed_network] : [], diff --git a/src/pages/container-infra/containers/Clusters/actions/StepCreate/StepNodeSpec/index.jsx b/src/pages/container-infra/containers/Clusters/actions/StepCreate/StepNodeSpec/index.jsx index 3036aeac..e0c8864e 100644 --- a/src/pages/container-infra/containers/Clusters/actions/StepCreate/StepNodeSpec/index.jsx +++ b/src/pages/container-infra/containers/Clusters/actions/StepCreate/StepNodeSpec/index.jsx @@ -17,15 +17,18 @@ import { toJS } from 'mobx'; import Base from 'components/Form'; import globalKeypairStore from 'stores/nova/keypair'; import { FlavorStore } from 'src/stores/nova/flavor'; +import { ClusterTemplatesStore } from 'stores/magnum/clusterTemplates'; import { defaultTip } from 'resources/magnum/cluster'; import { getKeyPairHeader } from 'resources/nova/keypair'; import { getBaseSimpleFlavorColumns } from 'resources/magnum/template'; +import { allSettled } from 'utils'; export class StepNodeSpec extends Base { init() { this.keyPairStore = globalKeypairStore; this.flavorStore = new FlavorStore(); this.masterFlavorStore = new FlavorStore(); + this.templateStore = new ClusterTemplatesStore(); this.getAllInitFunctions(); } @@ -40,10 +43,11 @@ export class StepNodeSpec extends Base { allowed = () => Promise.resolve(); async getAllInitFunctions() { - await Promise.all([ + await allSettled([ this.getKeypairs(), this.getFlavors(), this.getMasterFlavors(), + this.getTemplateDetail(), ]); this.updateDefaultValue(); } @@ -72,20 +76,25 @@ export class StepNodeSpec extends Base { return toJS(this.masterFlavorStore.list.data) || []; } + getTemplateDetail() { + const { context: { clusterTemplate = {} } = {} } = this.props; + const { selectedRowKeys = [] } = clusterTemplate; + const templateId = selectedRowKeys[0]; + if (templateId) { + return this.templateStore.fetchDetail({ id: templateId }); + } + } + + get templateDetail() { + return toJS(this.templateStore.detail) || {}; + } + get defaultValue() { const { - context: { - clusterTemplate = {}, - keypair, - masterFlavor, - flavor, - master_count, - node_count, - } = {}, + context: { keypair, masterFlavor, flavor, master_count, node_count } = {}, } = this.props; - const { selectedRows = [] } = clusterTemplate; const { master_flavor_id, flavor_id, keypair_id, selfKeypair } = - selectedRows[0] || {}; + this.templateDetail; return { master_count: master_count || 1, diff --git a/src/stores/magnum/clusterTemplates.js b/src/stores/magnum/clusterTemplates.js index 6a4b37e1..32e689bd 100644 --- a/src/stores/magnum/clusterTemplates.js +++ b/src/stores/magnum/clusterTemplates.js @@ -16,6 +16,7 @@ import Base from 'stores/base'; import client from 'client'; import { action } from 'mobx'; import { isBoolean } from 'lodash'; +import { allSettled } from 'utils'; export class ClusterTemplatesStore extends Base { get client() { @@ -100,7 +101,7 @@ export class ClusterTemplatesStore extends Base { async detailDidFetch(item) { const [kp = {}, fr = {}, mfr = {}, ext = {}, fx = {}, sub = {}, img] = - await Promise.all([ + await allSettled([ client.nova.keypairs.list(), item.flavor_id ? this.flavorClient.show(item.flavor_id) : {}, item.master_flavor_id @@ -113,34 +114,57 @@ export class ClusterTemplatesStore extends Base { item.fixed_subnet ? this.subnetClient.show(item.fixed_subnet) : {}, item.image_id ? this.imageClient.show(item.image_id) : {}, ]); - const { keypairs = [] } = kp; - const { flavor } = fr; - const { flavor: masterFlavor } = mfr; - const { network } = ext; - const { network: fixedNetwork } = fx; - const { subnet: fixedSubnet } = sub; - const keypair = keypairs.find((k) => k?.keypair?.name === item.keypair_id); - if (keypair) { - item.selfKeypair = true; + if (kp.status === 'fulfilled') { + const { keypairs = [] } = kp.value; + const keypair = keypairs.find( + (k) => k?.keypair?.name === item.keypair_id + ); + if (keypair) { + item.selfKeypair = true; // Don't need to reset keypair_id to null if not matched + } } - if (flavor) { + if (fr.status === 'fulfilled') { + const { flavor } = fr.value; item.flavor = flavor; + } else { + item.original_flavor_id = item.flavor_id; + item.flavor_id = null; } - if (masterFlavor) { + if (mfr.status === 'fulfilled') { + const { flavor: masterFlavor } = mfr.value; item.masterFlavor = masterFlavor; + } else { + item.original_master_flavor_id = item.master_flavor_id; + item.master_flavor_id = null; } - if (network) { + if (ext.status === 'fulfilled') { + const { network } = ext.value; item.externalNetwork = network; + } else { + item.original_external_network_id = item.external_network_id; + item.external_network_id = null; } - if (fixedNetwork) { + if (fx.status === 'fulfilled') { + const { network: fixedNetwork } = fx.value; item.fixedNetwork = fixedNetwork; + } else { + item.original_fixed_network = item.fixed_network; + item.fixed_network = null; } - if (fixedSubnet) { + if (sub.status === 'fulfilled') { + const { subnet: fixedSubnet } = sub.value; item.fixedSubnet = fixedSubnet; + } else { + item.original_fixed_subnet = item.fixed_subnet; + item.fixed_subnet = null; } - if (img) { - item.image = img; + if (img.status === 'fulfilled') { + item.image = img.value; + } else { + item.original_image_id = item.image_id; + item.image_id = null; } + return item; } } diff --git a/src/stores/magnum/clusters.js b/src/stores/magnum/clusters.js index 17db97fa..57a1513d 100644 --- a/src/stores/magnum/clusters.js +++ b/src/stores/magnum/clusters.js @@ -15,6 +15,7 @@ import Base from 'stores/base'; import client from 'client'; import { action } from 'mobx'; +import { allSettled } from 'utils'; export class ClustersStore extends Base { get client() { @@ -74,33 +75,48 @@ export class ClustersStore extends Base { const masterFlavorId = item.master_flavor_id || templateMasterFlavorId; const fixedNetworkId = item.fixed_network || templateFixedNetworkId; const fixedSubnetId = item.fixed_subnet || templateSubnetId; - const [fr = {}, mfr = {}, fx = {}, sub = {}, stack] = await Promise.all([ + const [fr = {}, mfr = {}, fx = {}, sub = {}, stack] = await allSettled([ flavorId ? this.flavorClient.show(flavorId) : {}, masterFlavorId ? this.flavorClient.show(masterFlavorId) : {}, fixedNetworkId ? this.networkClient.show(fixedNetworkId) : {}, fixedSubnetId ? this.subnetClient.show(fixedSubnetId) : {}, item.stack_id ? this.stackClient.list({ id: item.stack_id }) : {}, ]); - const { flavor } = fr; - const { flavor: masterFlavor } = mfr; - const { network: fixedNetwork } = fx; - const { subnet: fixedSubnet } = sub; - const { stacks = [] } = stack; - if (flavor) { + if (fr.status === 'fulfilled') { + const { flavor } = fr.value; item.flavor = flavor; + } else { + item.original_flavor_id = item.flavor_id; + item.flavor_id = null; } - if (masterFlavor) { + if (mfr.status === 'fulfilled') { + const { flavor: masterFlavor } = mfr.value; item.masterFlavor = masterFlavor; + } else { + item.original_master_flavor_id = item.master_flavor_id; + item.master_flavor_id = null; } - if (fixedNetwork) { + if (fx.status === 'fulfilled') { + const { network: fixedNetwork } = fx.value; item.fixedNetwork = fixedNetwork; + } else { + item.original_fixed_network = item.fixed_network; + item.fixed_network = null; } - if (fixedSubnet) { + if (sub.status === 'fulfilled') { + const { subnet: fixedSubnet } = sub.value; item.fixedSubnet = fixedSubnet; + } else { + item.original_fixed_subnet = item.fixed_subnet; + item.fixed_subnet = null; } - if (stacks[0]) { - item.stack = stacks[0]; + if (stack.status === 'fulfilled') { + const { stacks = [] } = stack.value; + if (stacks[0]) { + item.stack = stacks[0]; + } } + return item; }