feat: support create key pair when create instance

1. Support create key pair in the third step of instance creating
2. Auto select the new key pair after creating

Change-Id: Ib9f0745a7b04b764e1ab7582716d1c82a5bcc1f9
This commit is contained in:
Jingwei.Zhang 2022-07-06 15:40:51 +08:00
parent 494409a93b
commit 28cded2a29
5 changed files with 87 additions and 6 deletions

View File

@ -2023,7 +2023,6 @@
"Share Type ID": "Share Type ID",
"Share Type Name": "Share Type Name",
"Share Types": "Share Types",
"Share group": "Share group",
"Shared": "Shared",
"Shared Image": "Shared Image",
"Shared Network": "Shared Network",
@ -2232,6 +2231,7 @@
"The instances in the anti-affinity group are strictly allocated to different physical machines. When there are no more physical machines to allocate, the allocation fails.": "The instances in the anti-affinity group are strictly allocated to different physical machines. When there are no more physical machines to allocate, the allocation fails.",
"The ip is not within the allocated pool!": "The ip is not within the allocated pool!",
"The ip of external members can be any, including the public network ip.": "The ip of external members can be any, including the public network ip.",
"The key pair allows you to SSH into your newly created instance. You can select an existing key pair, import a key pair, or generate a new key pair.": "The key pair allows you to SSH into your newly created instance. You can select an existing key pair, import a key pair, or generate a new key pair.",
"The kill signal to send": "The kill signal to send",
"The maximum transmission unit (MTU) value to address fragmentation. Minimum value is 68 for IPv4, and 1280 for IPv6.": "The maximum transmission unit (MTU) value to address fragmentation. Minimum value is 68 for IPv4, and 1280 for IPv6.",
"The min size is {size} GiB": "The min size is {size} GiB",

View File

@ -2023,7 +2023,6 @@
"Share Type ID": "共享类型ID",
"Share Type Name": "共享类型名称",
"Share Types": "共享类型",
"Share group": "",
"Shared": "共享",
"Shared Image": "共享镜像",
"Shared Network": "共享网络",
@ -2232,6 +2231,7 @@
"The instances in the anti-affinity group are strictly allocated to different physical machines. When there are no more physical machines to allocate, the allocation fails.": "将反亲和组内的云主机严格分配到不同物理机上,当没有更多物理机可分配时,则分配失败。",
"The ip is not within the allocated pool!": "该ip不在分配的资源池范围内",
"The ip of external members can be any, including the public network ip.": "外部成员的IP可以是任何IP包括公网IP。",
"The key pair allows you to SSH into your newly created instance. You can select an existing key pair, import a key pair, or generate a new key pair.": "密钥对允许您SSH到您新创建的实例。 您可以选择一个已存在的密钥对、导入一个密钥对或生成一个新的密钥对。",
"The kill signal to send": "要发送的终止信号",
"The maximum transmission unit (MTU) value to address fragmentation. Minimum value is 68 for IPv4, and 1280 for IPv6.": "地址片段的最大传输单位。IPv4最小68IPv6最小1280。",
"The min size is {size} GiB": "最小内存为 {size} GiB",

View File

@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import React from 'react';
import { inject, observer } from 'mobx-react';
import globalKeyPairStore from 'stores/nova/keypair';
import globalServerStore from 'stores/nova/instance';
@ -26,6 +27,9 @@ import {
} from 'resources/nova/hypervisor';
import { physicalNodeTypes } from 'resources/nova/instance';
import { getOptions } from 'utils';
import CreateKeyPair from 'pages/compute/containers/Keypair/actions/Create';
import ItemActionButtons from 'components/Tables/Base/ItemActionButtons';
import styles from '../index.less';
export class SystemStep extends Base {
init() {
@ -151,6 +155,13 @@ export class SystemStep extends Base {
selectedRows: this.serverGroups.filter((it) => it.id === servergroup),
};
}
const { initKeyPair, name } = this.state;
if (initKeyPair) {
data.keypair = initKeyPair;
}
if (name) {
data.name = name;
}
return data;
}
@ -170,8 +181,8 @@ export class SystemStep extends Base {
allowed = () => Promise.resolve();
getKeypairs() {
this.keyPairStore.fetchList();
async getKeypairs() {
return this.keyPairStore.fetchList();
}
getHypervisors() {
@ -185,6 +196,7 @@ export class SystemStep extends Base {
get nameForStateUpdate() {
return [
'name',
'loginType',
'password',
'confirmPassword',
@ -197,17 +209,60 @@ export class SystemStep extends Base {
return this.sourceInfo && this.sourceInfo.os_admin_user;
}
onFinishCreateKeyPair = async () => {
const { createdItem } = this.keyPairStore;
const result = await this.getKeypairs();
const newItem = result.find((it) => it.name === (createdItem || {}).name);
if (newItem) {
const initKeyPair = {
selectedRowKeys: [newItem.id],
selectedRows: [newItem],
};
this.setState(
{
initKeyPair,
},
() => {
this.updateDefaultValue();
}
);
}
};
getKeyPairHeader() {
const { isLoading } = this.keyPairStore.list || {};
if (isLoading) {
return null;
}
return (
<div style={{ marginBottom: 10 }}>
<span>
{t(
'The key pair allows you to SSH into your newly created instance. You can select an existing key pair, import a key pair, or generate a new key pair.'
)}
</span>
<span className={styles['action-wrapper']}>
<ItemActionButtons
actions={{ moreActions: [{ action: CreateKeyPair }] }}
onFinishAction={this.onFinishCreateKeyPair}
/>
</span>
</div>
);
}
get formItems() {
const { loginType, more = false, physicalNodeType } = this.state;
const isPassword = loginType === this.loginTypes[1].value;
const isManually = physicalNodeType === physicalNodeTypes[1].value;
const { initKeyPair } = this.state;
return [
{
name: 'name',
label: t('Name'),
type: 'input-name',
placeholder: t('Please input name'),
required: true,
isInstance: true,
},
@ -237,9 +292,10 @@ export class SystemStep extends Base {
type: 'select-table',
data: this.keypairs,
isLoading: this.keyPairStore.list.isLoading,
isMulti: false,
required: !isPassword,
hidden: isPassword,
header: this.getKeyPairHeader(),
initValue: initKeyPair,
tip: t(
'The SSH key is a way to remotely log in to the instance. The cloud platform only helps to keep the public key. Please keep your private key properly.'
),

View File

@ -1,3 +1,5 @@
@import '~styles/variables';
.input {
margin-right: 32px;
margin-left: 16px;
@ -6,3 +8,14 @@
.number-input {
min-width: 165px;
}
.action-wrapper {
margin-left: 8px;
:global {
.ant-btn-link {
padding: 5.6px 15px !important;
border-color: @primary-color;
}
}
}

View File

@ -12,10 +12,14 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import { action, observable } from 'mobx';
import client from 'client';
import Base from 'stores/base';
export class KeypairStore extends Base {
@observable
createdItem = null;
get client() {
return client.nova.keypairs;
}
@ -36,6 +40,14 @@ export class KeypairStore extends Base {
return item;
};
}
@action
async create(data) {
const body = {};
body[this.responseKey] = data;
this.createdItem = data;
return this.submitting(this.client.create(body));
}
}
const globalKeypairStore = new KeypairStore();