fix: fix cluster template

1. Fix the params when create or update cluster template
2. Show search for all select items
3. Fix the route path for update cluster template

Change-Id: Ic3435abb340f6e129815fde368b5b12bcabcdcb5
This commit is contained in:
xusongfu 2022-06-23 17:15:40 +08:00
parent bf6c765fb1
commit ec4bcb3c93
20 changed files with 423 additions and 315 deletions

View File

@ -74,6 +74,11 @@ export default class BaseForm extends React.Component {
this.unMountActions && this.unMountActions();
}
get path() {
const { location: { pathname = '' } = {} } = this.props;
return pathname || '';
}
get disableSubmit() {
return false;
}

View File

@ -62,6 +62,7 @@ export default class index extends Component {
checkOptions,
checkBoxInfo,
allowClear = true,
showSearch = true,
...rest
} = this.props;
if (isUndefined(value) || isNull(value)) {
@ -69,6 +70,7 @@ export default class index extends Component {
<Select
{...rest}
allowClear={allowClear}
showSearch={showSearch}
placeholder={placeholder}
onChange={this.onChange}
/>
@ -88,6 +90,7 @@ export default class index extends Component {
<Select
{...rest}
allowClear={allowClear}
showSearch={showSearch}
placeholder={placeholder}
onChange={this.onChange}
value={this.getValue()}
@ -104,6 +107,7 @@ export default class index extends Component {
<Select
{...rest}
allowClear={allowClear}
showSearch={showSearch}
placeholder={placeholder}
onChange={this.onChange}
value={this.getValue()}

View File

@ -58,6 +58,11 @@ export default class BaseStepForm extends React.Component {
this.unMountActions && this.unMountActions();
}
get path() {
const { location: { pathname = '' } = {} } = this.props;
return pathname || '';
}
get hasConfirmStep() {
return false;
}

View File

@ -672,7 +672,7 @@ const renderMenu = (t) => {
level: 2,
},
{
path: /^\/container-infra\/cluster-template\/update\/.[^/]+\/.[^/]+$/,
path: /^\/container-infra\/cluster-template\/update\/.[^/]+$/,
name: t('Update Cluster Template'),
key: 'containerInfraUpdateClusterTemplate',
level: 2,

View File

@ -322,9 +322,9 @@
"Checksum": "Checksum",
"Chile": "Chile",
"China": "China",
"Choose a External Network ID": "Choose a External Network ID",
"Choose a External Network": "Choose a External Network",
"Choose a Network Driver": "Choose a Network Driver",
"Choose a Private Network ID": "Choose a Private Network ID",
"Choose a Private Network": "Choose a Private Network",
"Choose a Private Network at first": "Choose a Private Network at first",
"Choose a host to live migrate instance to. If not selected, the scheduler will auto select target host.": "Choose a host to live migrate instance to. If not selected, the scheduler will auto select target host.",
"Choose a host to migrate instance to. If not selected, the scheduler will auto select target host.": "Choose a host to migrate instance to. If not selected, the scheduler will auto select target host.",
@ -542,7 +542,6 @@
"Current Flavor": "Current Flavor",
"Current Host": "Current Host",
"Current Interface": "Current Interface",
"Current Master Flavor": "Current Master Flavor",
"Current Password": "Current Password",
"Current Path: ": "Current Path: ",
"Current Project": "Current Project",
@ -911,7 +910,9 @@
"Fixed IP Address": "Fixed IP Address",
"Fixed IPs": "Fixed IPs",
"Fixed Network": "Fixed Network",
"Fixed Network ID": "Fixed Network ID",
"Fixed Subnet": "Fixed Subnet",
"Fixed Subnet ID": "Fixed Subnet ID",
"Flavor": "Flavor",
"Flavor Detail": "Flavor Detail",
"Flavor ID": "Flavor ID",

View File

@ -322,9 +322,9 @@
"Checksum": "校验和",
"Chile": "智利",
"China": "中国大陆",
"Choose a External Network ID": "选择外部网络 ID",
"Choose a External Network": "选择外部网络",
"Choose a Network Driver": "选择网络驱动程序",
"Choose a Private Network ID": "选择专用网络 ID",
"Choose a Private Network": "选择专用网络",
"Choose a Private Network at first": "首先选择一个专用网络",
"Choose a host to live migrate instance to. If not selected, the scheduler will auto select target host.": "选择计算节点来热迁移云主机,如果没有选择,调度器会自动选择目标计算节点。",
"Choose a host to migrate instance to. If not selected, the scheduler will auto select target host.": "选择计算节点来迁移云主机,如果没有选择,调度器会自动选择目标计算节点。",
@ -542,7 +542,6 @@
"Current Flavor": "当前配置",
"Current Host": "当前主机",
"Current Interface": "当前接口",
"Current Master Flavor": "当前主类型",
"Current Password": "原密码",
"Current Path: ": "当前路径:",
"Current Project": "当前项目",
@ -911,7 +910,9 @@
"Fixed IP Address": "内网IP地址",
"Fixed IPs": "内网IP",
"Fixed Network": "内网",
"Fixed Network ID": "内网ID",
"Fixed Subnet": "内网子网",
"Fixed Subnet ID": "内网子网ID",
"Flavor": "云主机类型",
"Flavor Detail": "云主机类型详情",
"Flavor ID": "云主机类型ID",

View File

@ -10,9 +10,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import Base from 'containers/BaseDetail';
import React from 'react';
import { Link } from 'react-router-dom';
import Base from 'containers/BaseDetail';
import { inject, observer } from 'mobx-react';
export class BaseDetail extends Base {
@ -28,82 +27,94 @@ export class BaseDetail extends Base {
const options = [
{
label: t('COE'),
dataIndex: 'coe'
dataIndex: 'coe',
},
{
label: t('Cluster Distro'),
dataIndex: 'cluster_distro'
dataIndex: 'cluster_distro',
},
{
label: t('Server Type'),
dataIndex: 'server_type'
dataIndex: 'server_type',
},
{
label: t('Public'),
dataIndex: 'public',
valueRender: 'yesNo'
valueRender: 'yesNo',
},
{
label: t('Registry Enabled'),
dataIndex: 'registry_enabled',
valueRender: 'yesNo'
valueRender: 'yesNo',
},
{
label: t('TLS Disabled'),
dataIndex: 'tls_disabled',
valueRender: 'yesNo'
valueRender: 'yesNo',
},
];
return {
title: t('Cluster Type'),
options
options,
};
}
get networkCard() {
const { external_network_id, fixed_network } = this.detailData || {};
const externalNetworkUrl = external_network_id
? this.getLinkRender('networkDetail', external_network_id, {
id: external_network_id,
})
: '-';
const fixedNetworkUrl = fixed_network
? this.getLinkRender('networkDetail', fixed_network, {
id: fixed_network,
})
: '-';
const options = [
{
label: t('Network Driver'),
dataIndex: 'network_driver'
dataIndex: 'network_driver',
},
{
label: t('HTTP Proxy'),
dataIndex: 'http_proxy'
dataIndex: 'http_proxy',
},
{
label: t('HTTPS Proxy'),
dataIndex: 'https_proxy'
dataIndex: 'https_proxy',
},
{
label: t('No Proxy'),
dataIndex: 'no_proxy'
dataIndex: 'no_proxy',
},
{
label: t('External Network ID'),
dataIndex: 'external_network_id'
content: externalNetworkUrl,
},
{
label: t('Fixed Network'),
dataIndex: 'fixed_network'
label: t('Fixed Network ID'),
content: fixedNetworkUrl,
},
{
label: t('Fixed Subnet'),
dataIndex: 'fixed_subnet'
label: t('Fixed Subnet ID'),
dataIndex: 'fixed_subnet',
},
{
label: t('DNS'),
dataIndex: 'dns_nameserver'
dataIndex: 'dns_nameserver',
},
{
label: t('Master LB Enabled'),
dataIndex: 'master_lb_enabled',
valueRender: 'yesNo'
valueRender: 'yesNo',
},
{
label: t('Floating IP Enabled'),
dataIndex: 'floating_ip_enabled',
valueRender: 'yesNo'
valueRender: 'yesNo',
},
];
@ -114,44 +125,64 @@ export class BaseDetail extends Base {
}
get specCard() {
const image = this.detailData.image_id;
const imageUrl = this.getRoutePath('imageDetail', { id: image });
const { image_id, keypair_id, flavor_id, master_flavor_id } =
this.detailData;
const imageUrl = image_id
? this.getLinkRender('imageDetail', image_id, {
id: image_id,
})
: '-';
const keypair = this.detailData.keypair_id;
const keypairUrl = this.getRoutePath('keypairDetail', { id: keypair });
const keypairUrl = keypair_id
? this.getLinkRender('keypairDetail', keypair_id, {
id: keypair_id,
})
: '-';
const flavorUrl = flavor_id
? this.getLinkRender('flavorDetail', flavor_id, {
id: flavor_id,
})
: '-';
const masterFlavorUrl = master_flavor_id
? this.getLinkRender('flavorDetail', master_flavor_id, {
id: master_flavor_id,
})
: '-';
const options = [
{
label: t('Image ID'),
content: <Link to={imageUrl}>{image}</Link>
content: imageUrl,
},
{
label: t('Keypair'),
content: <Link to={keypairUrl}>{keypair}</Link>
content: keypairUrl,
},
{
label: t('Flavor ID'),
dataIndex: 'flavor_id'
content: flavorUrl,
},
{
label: t('Master Flavor ID'),
dataIndex: 'master_flavor_id'
content: masterFlavorUrl,
},
{
label: t('Volume Driver'),
dataIndex: 'volume_driver'
dataIndex: 'volume_driver',
},
{
label: t('Docker Storage Driver'),
dataIndex: 'docker_storage_driver'
dataIndex: 'docker_storage_driver',
},
{
label: t('Docker Volume Size'),
dataIndex: 'docker_volume_size'
dataIndex: 'docker_volume_size',
},
{
label: t('Insecure Registry'),
dataIndex: 'insecure_registry'
dataIndex: 'insecure_registry',
},
];
@ -166,9 +197,20 @@ export class BaseDetail extends Base {
{
label: t('labels'),
dataIndex: 'labels',
render: (value) => value ? Object.entries(value).map(([key, val]) => {
return <div key={key}><ul><li>{key} : {val}</li></ul></div>
}) : '-'
render: (value) =>
value
? Object.entries(value).map(([key, val]) => {
return (
<div key={key}>
<ul>
<li>
{key} : {val}
</li>
</ul>
</div>
);
})
: '-',
},
];
@ -180,4 +222,4 @@ export class BaseDetail extends Base {
}
}
export default inject("rootStore")(observer(BaseDetail))
export default inject('rootStore')(observer(BaseDetail));

View File

@ -12,8 +12,9 @@
import { inject, observer } from 'mobx-react';
import Base from 'containers/TabDetail';
import BaseDetail from './BaseDetail';
import globalClusterTemplateStore from 'src/stores/magnum/clusterTemplates';
import BaseDetail from './BaseDetail';
import actionConfigs from '../actions';
export class ClusterTemplateDetail extends Base {
init() {
@ -32,6 +33,10 @@ export class ClusterTemplateDetail extends Base {
return 'container-infra:clustertemplate:detail';
}
get actionConfigs() {
return actionConfigs;
}
get detailInfos() {
return [
{
@ -41,12 +46,12 @@ export class ClusterTemplateDetail extends Base {
{
title: t('Created'),
dataIndex: 'created_at',
valueRender: 'toLocalTime'
valueRender: 'toLocalTime',
},
{
title: t('Updated'),
dataIndex: 'updated_at',
valueRender: 'toLocalTime'
valueRender: 'toLocalTime',
},
];
}
@ -62,4 +67,4 @@ export class ClusterTemplateDetail extends Base {
}
}
export default inject("rootStore")(observer(ClusterTemplateDetail))
export default inject('rootStore')(observer(ClusterTemplateDetail));

View File

@ -13,7 +13,7 @@
import { ConfirmAction } from 'containers/Action';
import globalClusterTemplateStore from 'stores/magnum/clusterTemplates';
export default class DeleteClusterTemplates extends ConfirmAction {
export default class Delete extends ConfirmAction {
get id() {
return 'delete';
}

View File

@ -14,11 +14,9 @@
import { inject, observer } from 'mobx-react';
import { getPath } from 'src/utils/route-map';
import StepCreate from './StepCreate';
import { StepCreate as Base } from './StepCreate';
@inject('rootStore')
@observer
export default class Edit extends StepCreate {
export class Edit extends Base {
static id = 'update-cluster-template';
static title = t('Update Cluster Template');
@ -42,4 +40,6 @@ export default class Edit extends StepCreate {
static allowed() {
return Promise.resolve(true);
}
}
}
export default inject('rootStore')(observer(Edit));

View File

@ -12,16 +12,16 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import Base from "components/Form";
import { inject, observer } from "mobx-react";
import Base from 'components/Form';
import { inject, observer } from 'mobx-react';
export class StepInfo extends Base {
get title() {
return t("Info")
return t('Info');
}
get name() {
return t("Info")
return t('Info');
}
get isEdit() {
@ -32,22 +32,28 @@ export class StepInfo extends Base {
return true;
}
onCOEChange = (value) => {
this.updateContext({
coeSelectRows: value,
});
}
get defaultValue() {
const values = {};
let values = {};
if (this.isEdit) {
values.clusterTemplateName = this.props.extra.name;
values.coe = this.props.extra.coe;
values.cluster_template_public = this.props.extra.public;
values.cluster_template_hidden = this.props.extra.hidden;
values.docker_registry_enabled = this.props.extra.registry_enabled;
values.tls_disabled = this.props.extra.tls_disabled;
const {
extra: {
name,
coe,
public: publics,
hidden,
registry_enabled,
tls_disabled,
} = {},
} = this.props;
values = {
name,
coe,
public: publics,
hidden,
registry_enabled,
tls_disabled,
};
}
return values;
}
@ -55,64 +61,62 @@ export class StepInfo extends Base {
get formItems() {
return [
{
name: "clusterTemplateName",
label: t("Cluster Template Name"),
type: "input",
placeholder: t("Cluster Template Name"),
required: true
name: 'name',
label: t('Cluster Template Name'),
type: 'input',
placeholder: t('Cluster Template Name'),
required: true,
},
{
name: "coe",
label: t("Container Orchestration Engine"),
type: "select",
name: 'coe',
label: t('Container Orchestration Engine'),
type: 'select',
options: [
{
label: t("Kubernetes"),
value: "kubernetes"
label: t('Kubernetes'),
value: 'kubernetes',
},
{
label: t("Docker Swarm"),
value: "swarm"
label: t('Docker Swarm'),
value: 'swarm',
},
{
label: t("Docker Swarm Mode"),
value: "swarm-mode"
label: t('Docker Swarm Mode'),
value: 'swarm-mode',
},
{
label: t("Mesos"),
value: "mesos"
label: t('Mesos'),
value: 'mesos',
},
{
label: t("DC/OS"),
value: "dcos"
label: t('DC/OS'),
value: 'dcos',
},
],
onChange: this.onCOEChange,
allowClear: true,
showSearch: true
required: true,
},
{
name: "cluster_template_public",
label: t("Public"),
type: "check"
name: 'public',
label: t('Public'),
type: 'check',
},
{
name: "cluster_template_hidden",
label: t("Hidden"),
type: "check"
name: 'hidden',
label: t('Hidden'),
type: 'check',
},
{
name: "docker_registry_enabled",
label: t("Enable Registry"),
type: "check"
name: 'registry_enabled',
label: t('Enable Registry'),
type: 'check',
},
{
name: "tls_disabled",
label: t("Disable TLS"),
type: "check"
}
]
name: 'tls_disabled',
label: t('Disable TLS'),
type: 'check',
},
];
}
}
export default inject("rootStore")(observer(StepInfo))
export default inject('rootStore')(observer(StepInfo));

View File

@ -10,8 +10,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import Base from "components/Form";
import { inject, observer } from "mobx-react";
import Base from 'components/Form';
import { inject, observer } from 'mobx-react';
import KeyValueInput from 'components/FormItem/KeyValueInput';
export class StepLabel extends Base {
@ -23,6 +23,30 @@ export class StepLabel extends Base {
return t('Labels');
}
get isStep() {
return true;
}
get isEdit() {
return !!this.props.extra;
}
get defaultValue() {
const values = {};
if (this.isEdit) {
const {
extra: { labels },
} = this.props;
values.additionalLabels = Object.keys(labels || {}).map((key) => ({
value: {
key,
value: labels[key],
},
}));
}
return values;
}
get formItems() {
return [
{
@ -32,8 +56,8 @@ export class StepLabel extends Base {
itemComponent: KeyValueInput,
addText: t('Add Label'),
},
]
];
}
}
export default inject("rootStore")(observer(StepLabel))
export default inject('rootStore')(observer(StepLabel));

View File

@ -18,10 +18,11 @@ import globalNetworkStore from 'src/stores/neutron/network';
import globalSubnetStore from 'src/stores/neutron/subnet';
export class StepNetwork extends Base {
init() {
async init() {
const { extra: { fixed_network } = {} } = this.props;
this.state.selectedSubnetId = fixed_network || '';
this.getFloatingIps();
this.getSubnets();
this.state = { selectedSubnetId: '' };
}
get title() {
@ -46,7 +47,11 @@ export class StepNetwork extends Base {
get getFloatingIpList() {
return (globalNetworkStore.list.data || [])
.filter((it) => it['router:external'] === true && it.project_id === this.currentProjectId)
.filter(
(it) =>
it['router:external'] === true &&
it.project_id === this.currentProjectId
)
.map((it) => ({
value: it.id,
label: it.name,
@ -55,7 +60,11 @@ export class StepNetwork extends Base {
get getPrivateFloatingIpList() {
return (globalNetworkStore.list.data || [])
.filter((it) => it['router:external'] === false && it.project_id === this.currentProjectId)
.filter(
(it) =>
it['router:external'] === false &&
it.project_id === this.currentProjectId
)
.map((it) => ({
value: it.id,
label: it.name,
@ -80,49 +89,71 @@ export class StepNetwork extends Base {
this.setState({
selectedSubnetId: value,
});
this.resetFormValue(['fixedSubnet']);
this.resetFormValue(['fixed_subnet']);
}
get getNetworkDriver() {
const { context = {} } = this.props;
const {
coeSelectRows = "",
coe = ""
} = context;
let networkDriver = [];
const { coeSelectRows = '', coe = '' } = context;
const networkDriver = [];
if (!coeSelectRows || !coe) {
networkDriver.push({ val: "docker", name: "Docker" }, { val: "flannel", name: "Flannel" }, { val: "calico", name: "Calico" })
networkDriver.push(
{ val: 'docker', name: 'Docker' },
{ val: 'flannel', name: 'Flannel' },
{ val: 'calico', name: 'Calico' }
);
}
if (coeSelectRows === "swarm" || coeSelectRows === "swarm-mode") {
networkDriver.push({ val: "docker", name: "Docker" }, { val: "flannel", name: "Flannel" })
if (coeSelectRows === 'swarm' || coeSelectRows === 'swarm-mode') {
networkDriver.push(
{ val: 'docker', name: 'Docker' },
{ val: 'flannel', name: 'Flannel' }
);
}
if (coeSelectRows === "kubernetes") {
networkDriver.push({ val: "calico", name: "Calico" }, { val: "flannel", name: "Flannel" })
if (coeSelectRows === 'kubernetes') {
networkDriver.push(
{ val: 'calico', name: 'Calico' },
{ val: 'flannel', name: 'Flannel' }
);
}
if (coeSelectRows === "mesos" || coeSelectRows === "dcos") {
networkDriver.push({ val: "docker", name: "Docker" })
if (coeSelectRows === 'mesos' || coeSelectRows === 'dcos') {
networkDriver.push({ val: 'docker', name: 'Docker' });
}
return (networkDriver || [])
.map((it) => ({
value: it.val,
label: it.name,
}));
return (networkDriver || []).map((it) => ({
value: it.val,
label: it.name,
}));
}
get defaultValue() {
const values = {};
let values = {};
if (this.isEdit) {
values.networkDriver = this.props.extra.network_driver;
values.HTTPProxy = this.props.extra.http_proxy;
values.HTTPSProxy = this.props.extra.https_proxy;
values.noProxy = this.props.extra.no_proxy;
values.externalNetworkID = this.props.extra.external_network_id;
values.fixedNetwork = this.props.extra.fixed_network;
values.fixedSubnet = this.props.extra.fixed_subnet;
values.DNS = this.props.extra.dns_nameserver;
values.masterLB = this.props.extra.master_lb_enabled;
values.floatingIP = this.props.extra.floating_ip_enabled;
const {
extra: {
network_driver,
http_proxy,
https_proxy,
no_proxy,
external_network_id,
fixed_network,
fixed_subnet,
dns_nameserver,
master_lb_enabled,
floating_ip_enabled,
} = {},
} = this.props;
values = {
network_driver,
http_proxy,
https_proxy,
no_proxy,
external_network_id,
fixed_network,
fixed_subnet,
dns_nameserver,
master_lb_enabled,
floating_ip_enabled,
};
}
return values;
}
@ -130,78 +161,70 @@ export class StepNetwork extends Base {
get formItems() {
return [
{
name: "networkDriver",
label: t("Network Driver"),
placeholder: t("Choose a Network Driver"),
type: "select",
name: 'network_driver',
label: t('Network Driver'),
placeholder: t('Choose a Network Driver'),
type: 'select',
options: this.getNetworkDriver,
allowClear: true,
showSearch: true
},
{
name: "HTTPProxy",
label: t("HTTP Proxy"),
placeholder: t("The http_proxy address to use for nodes in cluster"),
type: "input"
name: 'http_proxy',
label: t('HTTP Proxy'),
placeholder: t('The http_proxy address to use for nodes in cluster'),
type: 'input',
},
{
name: "HTTPSProxy",
label: t("HTTPS Proxy"),
placeholder: t("The https_proxy address to use for nodes in cluster"),
type: "input"
name: 'https_proxy',
label: t('HTTPS Proxy'),
placeholder: t('The https_proxy address to use for nodes in cluster'),
type: 'input',
},
{
name: "noProxy",
label: t("No Proxy"),
placeholder: t("The no_proxy address to use for nodes in cluster"),
type: "input"
name: 'no_proxy',
label: t('No Proxy'),
placeholder: t('The no_proxy address to use for nodes in cluster'),
type: 'input',
},
{
name: "externalNetworkID",
label: t("External Network ID"),
placeholder: t("Choose a External Network ID"),
type: "select",
name: 'external_network_id',
label: t('External Network'),
placeholder: t('Choose a External Network'),
type: 'select',
options: this.getFloatingIpList,
allowClear: true,
showSearch: true
},
{
name: "fixedNetwork",
label: t("Fixed Network"),
placeholder: t("Choose a Private Network ID"),
type: "select",
name: 'fixed_network',
label: t('Fixed Network'),
placeholder: t('Choose a Private Network'),
type: 'select',
options: this.getPrivateFloatingIpList,
onChange: (val) => this.onSelectChangeFixedNetwork(val),
allowClear: true,
showSearch: true
},
{
name: "fixedSubnet",
label: t("Fixed Subnet"),
placeholder: t("Choose a Private Network at first"),
type: "select",
name: 'fixed_subnet',
label: t('Fixed Subnet'),
placeholder: t('Choose a Private Network at first'),
type: 'select',
options: this.getSubnetList,
allowClear: true,
showSearch: true
},
{
name: "DNS",
label: t("DNS"),
placeholder: t("The DNS nameserver to use for this cluster template"),
type: "input"
name: 'dns_nameserver',
label: t('DNS'),
placeholder: t('The DNS nameserver to use for this cluster template'),
type: 'input',
},
{
name: "masterLB",
label: t("Master LB"),
type: "check"
name: 'master_lb_enabled',
label: t('Master LB'),
type: 'check',
},
{
name: "floatingIP",
label: t("Floating IP"),
type: "check"
}
]
name: 'floating_ip_enabled',
label: t('Floating IP'),
type: 'check',
},
];
}
}
export default inject("rootStore")(observer(StepNetwork))
export default inject('rootStore')(observer(StepNetwork));

View File

@ -94,18 +94,33 @@ export class StepNodeSpec extends Base {
};
get defaultValue() {
const values = {};
let values = {};
if (this.isEdit) {
values.image = this.props.extra.image_id;
values.keypair = this.props.extra.keypair_id;
values.flavorCurrent = this.props.extra.flavor_id;
values.flavor = this.props.extra.flavor_id;
values.masterFlavor = this.props.extra.master_flavor_id;
values.masterFlavorCurrent = this.props.extra.master_flavor_id;
values.volumeDriver = this.props.extra.volume_driver;
values.dockerStorageDriver = this.props.extra.docker_storage_driver;
values.dockerVolumeSize = this.props.extra.docker_volume_size;
const {
extra: {
image_id,
keypair_id,
flavor_id,
master_flavor_id,
volume_driver,
docker_storage_driver,
docker_volume_size,
} = {},
} = this.props;
values = {
image_id,
keypair_id,
volume_driver,
docker_storage_driver,
docker_volume_size,
};
if (flavor_id) {
values.flavor = { selectedRowKeys: [flavor_id] };
}
if (master_flavor_id) {
values.masterFlavor = { selectedRowKeys: [master_flavor_id] };
}
}
return values;
}
@ -113,26 +128,17 @@ export class StepNodeSpec extends Base {
get formItems() {
return [
{
name: 'image',
name: 'image_id',
label: t('Image'),
type: 'select',
options: this.getImageOsDistroList,
allowClear: true,
showSearch: true,
required: true,
},
{
name: 'keypair',
name: 'keypair_id',
label: t('Keypair'),
type: 'select',
options: this.getKeypairList,
allowClear: true,
showSearch: true,
},
{
name: 'flavorCurrent',
label: t('Current Flavor'),
type: 'label',
iconType: 'flavor',
},
{
name: 'flavor',
@ -140,12 +146,6 @@ export class StepNodeSpec extends Base {
type: 'select-table',
component: <FlavorSelectTable onChange={this.onFlavorChange} />,
},
{
name: 'masterFlavorCurrent',
label: t('Current Master Flavor'),
type: 'label',
iconType: 'flavor',
},
{
name: 'masterFlavor',
label: t('Master Flavor'),
@ -153,15 +153,13 @@ export class StepNodeSpec extends Base {
component: <FlavorSelectTable onChange={this.onFlavorChange} />,
},
{
name: 'volumeDriver',
name: 'volume_driver',
label: t('Volume Driver'),
type: 'select',
options: this.getVolumeDriver,
allowClear: true,
showSearch: true,
},
{
name: 'dockerStorageDriver',
name: 'docker_storage_driver',
label: t('Docker Storage Driver'),
type: 'select',
options: [
@ -174,15 +172,13 @@ export class StepNodeSpec extends Base {
value: 'overlay2',
},
],
allowClear: true,
showSearch: true,
},
{
name: 'dockerVolumeSize',
name: 'docker_volume_size',
label: t('Docker Volume Size (GiB)'),
type: 'input-number',
min: '1',
placeholder: 'Spec',
type: 'input-int',
min: 1,
placeholder: t('Spec'),
},
];
}

View File

@ -10,14 +10,15 @@
// See the License for the specific language governing permissions and
// limitations under the License.
import StepInfo from "./StepInfo";
import StepNodeSpec from "./StepNodeSpec";
import StepNetwork from "./StepNetwork";
import StepLabel from "./StepLabel";
import { inject, observer } from "mobx-react";
import { StepAction } from "src/containers/Action";
import globalClusterTemplateStore from "src/stores/magnum/clusterTemplates";
import { toJS } from "mobx";
import { inject, observer } from 'mobx-react';
import { StepAction } from 'src/containers/Action';
import globalClusterTemplateStore from 'src/stores/magnum/clusterTemplates';
import { toJS } from 'mobx';
import { admission_control_list } from 'resources/magnum/template';
import StepInfo from './StepInfo';
import StepNodeSpec from './StepNodeSpec';
import StepNetwork from './StepNetwork';
import StepLabel from './StepLabel';
export class StepCreate extends StepAction {
init() {
@ -25,29 +26,28 @@ export class StepCreate extends StepAction {
this.getDetail();
}
static id = "create-cluster-template";
static id = 'create-cluster-template';
static title = t("Create Cluster Template");
static title = t('Create Cluster Template');
static path = "/container-infra/cluster-template/create";
static path = '/container-infra/cluster-template/create';
static policy = "container-infra:clustertemplate:create";
static policy = 'container-infra:clustertemplate:create';
static allowed() {
return Promise.resolve(true);
}
get name() {
return t("Create Cluster Template");
return t('Create Cluster Template');
}
get listUrl() {
return this.getRoutePath("clusterTemplate");
return this.getRoutePath('clusterTemplate');
}
get isEdit() {
const { pathname } = this.props.location;
return pathname.indexOf('update') >= 0;
return this.path.includes('update');
}
get hasExtraProps() {
@ -75,73 +75,53 @@ export class StepCreate extends StepAction {
get steps() {
return [
{
title: t("Info *"),
component: StepInfo
title: t('Info *'),
component: StepInfo,
},
{
title: t("Node Spec *"),
component: StepNodeSpec
title: t('Node Spec *'),
component: StepNodeSpec,
},
{
title: t("Network"),
component: StepNetwork
title: t('Network'),
component: StepNetwork,
},
{
title: t("Labels"),
component: StepLabel
}
]
title: t('Labels'),
component: StepLabel,
},
];
}
onSubmit = (values) => {
const { flavor, masterFlavor, additionalLabels, ...rest } = values;
const requestLabels = {};
const { additionalLabels } = values;
if (additionalLabels) {
additionalLabels.forEach(item => {
additionalLabels.forEach((item) => {
const labelKey = item.value.key.toLowerCase().trim();
const labelValue = item.value.value.toLowerCase().trim();
requestLabels[labelKey] = labelValue;
})
});
}
const body = {
labels: {
...requestLabels,
admission_control_list: 'NodeRestriction,NamespaceLifecycle,LimitRanger,ServiceAccount,ResourceQuota,TaintNodesByCondition,Priority,DefaultTolerationSeconds,DefaultStorageClass,StorageObjectInUseProtection,PersistentVolumeClaimResize,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,RuntimeClass'
admission_control_list,
},
fixed_subnet: values.fixedSubnet,
master_flavor_id: values.masterFlavor,
http_proxy: values.HTTPProxy != null ? values.HTTPProxy : null,
https_proxy: values.HTTPSProxy != null ? values.HTTPSProxy : null,
no_proxy: values.noProxy != null ? values.noProxy : null,
keypair_id: values.keypair,
docker_volume_size: values.dockerVolumeSize,
external_network_id: values.externalNetworkID,
image_id: values.image,
volume_driver: values.volumeDriver,
public: values.cluster_template_public,
hidden: values.cluster_template_hidden,
tls_disabled: values.tls_disabled,
registry_enabled: values.docker_registry_enabled,
master_lb_enabled: values.masterLB,
floating_ip_enabled: values.floatingIP,
docker_storage_driver: values.dockerStorageDriver,
name: values.clusterTemplateName,
network_driver: values.networkDriver,
fixed_network: values.fixedNetwork,
coe: values.coe,
flavor_id: values.flavor,
dns_nameserver: values.DNS,
...rest,
};
if (flavor) {
body.flavor_id = flavor.selectedRowKeys[0];
}
if (masterFlavor) {
body.master_flavor_id = masterFlavor.selectedRowKeys[0];
}
if (this.isEdit) {
return this.store.update({ id: this.params.id }, body);
} else {
return this.store.create(body);
}
}
return this.store.create(body);
};
}
export default inject("rootStore")(observer(StepCreate))
export default inject('rootStore')(observer(StepCreate));

View File

@ -9,19 +9,17 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
import StepCreate from './StepCreate';
import DeleteClusterTemplates from './Delete';
import EditClusterTemplateStep from './EditStep';
import Create from './StepCreate';
import Delete from './Delete';
import Edit from './Edit';
const actionConfigs = {
rowActions: {
firstAction: DeleteClusterTemplates,
moreActions: [
{ action: EditClusterTemplateStep },
],
firstAction: Delete,
moreActions: [{ action: Edit }],
},
batchActions: [DeleteClusterTemplates],
primaryActions: [StepCreate],
batchActions: [Delete],
primaryActions: [Create],
};
export default actionConfigs;

View File

@ -38,7 +38,9 @@ export class ClusterTemplates extends Base {
title: t('ID'),
dataIndex: 'uuid',
render: (data) => {
return this.getLinkRender("containerInfraClusterTemplateDetail", data, { id: data })
return this.getLinkRender('containerInfraClusterTemplateDetail', data, {
id: data,
});
},
},
{
@ -56,10 +58,10 @@ export class ClusterTemplates extends Base {
isHideable: true,
dataIndex: 'keypair_id',
render: (value) => {
return this.getLinkRender("keypairDetail", value, { id: value })
}
return this.getLinkRender('keypairDetail', value, { id: value });
},
},
];
}
export default inject("rootStore")(observer(ClusterTemplates))
export default inject('rootStore')(observer(ClusterTemplates));

View File

@ -20,7 +20,7 @@ import ClusterTemplates from '../containers/ClusterTemplates';
import ClusterTemplateDetail from '../containers/ClusterTemplates/Detail';
import ClustersCreate from '../containers/Clusters/actions/StepCreate';
import ClustersTemplateCreate from '../containers/ClusterTemplates/actions/StepCreate';
import StepUpdateClusterTemplate from '../containers/ClusterTemplates/actions/EditStep';
import StepUpdateClusterTemplate from '../containers/ClusterTemplates/actions/Edit';
const PATH = '/container-infra';
export default [

View File

@ -0,0 +1,16 @@
// Copyright 2022 99cloud
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
export const admission_control_list =
'NodeRestriction,NamespaceLifecycle,LimitRanger,ServiceAccount,ResourceQuota,TaintNodesByCondition,Priority,DefaultTolerationSeconds,DefaultStorageClass,StorageObjectInUseProtection,PersistentVolumeClaimResize,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,RuntimeClass';

View File

@ -32,18 +32,20 @@ export class ClusterTemplatesStore extends Base {
}
@action
async get(data) {
return this.client.get(data);
async update({ id }, body) {
const newBody = Object.keys(body).map((key) => ({
path: `/${key}`,
value: key === 'labels' ? JSON.stringify(body[key] || {}) : body[key],
op: [null, undefined, ''].includes(body[key]) ? 'remove' : 'replace',
}));
return this.submitting(this.client.patch(id, newBody));
}
@action
async update({ id }, newbody) {
return this.client.update(id, newbody);
}
async listDidFetch(items) {
if (!items.length) return items
return items.map(it => ({ ...it, id: it.uuid }));
get mapper() {
return (data) => ({
...data,
id: data.uuid,
});
}
}