feat: Support manila share network
1. Add console share network page 2. Add console create share network 3. Add console edit share network 4. Add console delete share netowrk 5. Add console share network detail page 6. Add administrator share network page 7. Add administrator share network detail page 8. Add administrator delete share network 9. Add popover network component Change-Id: Iade53429f2e432897cd60d1b7d3b6ee91ebcd95c
This commit is contained in:
parent
b4e81a76db
commit
d472f41913
@ -30,16 +30,13 @@ class ManilaClient extends Base {
|
||||
|
||||
get resources() {
|
||||
return [
|
||||
{
|
||||
name: 'azones',
|
||||
key: 'availability-zones',
|
||||
},
|
||||
{
|
||||
key: 'shares',
|
||||
responseKey: 'share',
|
||||
extendOperations: [
|
||||
{
|
||||
key: 'detail',
|
||||
method: 'get',
|
||||
isDetail: false,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 'types',
|
||||
@ -108,6 +105,23 @@ class ManilaClient extends Base {
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'shareNetworks',
|
||||
key: 'share-networks',
|
||||
responseKey: 'share_network',
|
||||
extendOperations: [
|
||||
{
|
||||
key: 'action',
|
||||
method: 'post',
|
||||
},
|
||||
],
|
||||
subResources: [
|
||||
{
|
||||
key: 'subnets',
|
||||
responseKey: 'subnet',
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -16,6 +16,16 @@ import React, { useEffect, useState } from 'react';
|
||||
import { Popover, Spin, Table } from 'antd';
|
||||
import { FileTextOutlined } from '@ant-design/icons';
|
||||
import PropTypes from 'prop-types';
|
||||
import { getRender } from 'utils/table';
|
||||
|
||||
const getColumn = (column) => {
|
||||
const { valueRender, render, ...rest } = column;
|
||||
const newRender = render || getRender(valueRender);
|
||||
return {
|
||||
...rest,
|
||||
render: newRender,
|
||||
};
|
||||
};
|
||||
|
||||
function PopupResources({ getRequests, columns }) {
|
||||
const [data, setData] = useState([]);
|
||||
@ -32,7 +42,10 @@ function PopupResources({ getRequests, columns }) {
|
||||
if (isLoading) {
|
||||
return <Spin />;
|
||||
}
|
||||
return <Table columns={columns} dataSource={data} pagination={false} />;
|
||||
const currentColumns = columns.map((c) => getColumn(c));
|
||||
return (
|
||||
<Table columns={currentColumns} dataSource={data} pagination={false} />
|
||||
);
|
||||
}
|
||||
|
||||
const IPopoverProps = {
|
||||
|
50
src/components/Popover/PopoverNetworks.jsx
Normal file
50
src/components/Popover/PopoverNetworks.jsx
Normal file
@ -0,0 +1,50 @@
|
||||
// Copyright 2021 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.
|
||||
|
||||
import React from 'react';
|
||||
import { NetworkStore } from 'stores/neutron/network';
|
||||
import { networkStatus } from 'resources/network';
|
||||
import IPopover from './Popover';
|
||||
|
||||
export default function PopoverNetworks(props) {
|
||||
const { networkIds = [] } = props;
|
||||
if (!networkIds.length) {
|
||||
return null;
|
||||
}
|
||||
const getRequests = () => {
|
||||
return networkIds.map((i) => new NetworkStore().fetchDetail({ id: i }));
|
||||
};
|
||||
const columns = [
|
||||
{
|
||||
dataIndex: 'name',
|
||||
title: t('Name'),
|
||||
},
|
||||
{
|
||||
title: t('External'),
|
||||
dataIndex: 'router:external',
|
||||
valueRender: 'yesNo',
|
||||
},
|
||||
{
|
||||
title: t('Shared'),
|
||||
dataIndex: 'shared',
|
||||
valueRender: 'yesNo',
|
||||
},
|
||||
{
|
||||
title: t('Status'),
|
||||
dataIndex: 'status',
|
||||
render: (value) => networkStatus[value] || '-',
|
||||
},
|
||||
];
|
||||
return <IPopover columns={columns} getRequests={getRequests} />;
|
||||
}
|
@ -16,7 +16,7 @@ import React from 'react';
|
||||
import { SubnetStore } from 'stores/neutron/subnet';
|
||||
import IPopover from './Popover';
|
||||
|
||||
export default function PopOverSubnets(props) {
|
||||
export default function PopoverSubnets(props) {
|
||||
const { subnetIds = [] } = props;
|
||||
if (!subnetIds.length) {
|
||||
return null;
|
||||
|
@ -437,6 +437,22 @@ const renderMenu = (t) => {
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '/share/share-network-admin',
|
||||
name: t('Share Network'),
|
||||
key: 'shareNetworkAdmin',
|
||||
level: 1,
|
||||
endpoints: 'manilav2',
|
||||
children: [
|
||||
{
|
||||
path: /^\/share\/share-network-admin\/detail\/.[^/]+$/,
|
||||
name: t('Share Network Detail'),
|
||||
key: 'shareNetworkDetailAdmin',
|
||||
level: 2,
|
||||
routePath: '/share/share-network-admin/detail/:id',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '/share/share-instance-admin',
|
||||
name: t('Share Instance'),
|
||||
|
@ -21,6 +21,7 @@ import {
|
||||
HomeOutlined,
|
||||
DatabaseFilled,
|
||||
AppstoreOutlined,
|
||||
SwitcherOutlined,
|
||||
} from '@ant-design/icons';
|
||||
|
||||
const renderMenu = (t) => {
|
||||
@ -377,6 +378,30 @@ const renderMenu = (t) => {
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '/share',
|
||||
name: t('Share File Storage'),
|
||||
key: 'fileStorage',
|
||||
icon: <SwitcherOutlined />,
|
||||
children: [
|
||||
{
|
||||
path: '/share/share-network',
|
||||
name: t('Share Network'),
|
||||
key: 'shareNetwork',
|
||||
level: 1,
|
||||
endpoints: 'manilav2',
|
||||
children: [
|
||||
{
|
||||
path: /^\/share\/share-network\/detail\/.[^/]+$/,
|
||||
name: t('Share Network Detail'),
|
||||
key: 'shareNetworkDetail',
|
||||
level: 2,
|
||||
routePath: '/share/share-network/detail/:id',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
// {
|
||||
// path: '/management',
|
||||
// name: t('Maintenance'),
|
||||
|
@ -415,6 +415,7 @@
|
||||
"Create Security Group": "Create Security Group",
|
||||
"Create Server Group": "Create Server Group",
|
||||
"Create Share Group Type": "Create Share Group Type",
|
||||
"Create Share Network": "Create Share Network",
|
||||
"Create Share Type": "Create Share Type",
|
||||
"Create Snapshot": "Create Snapshot",
|
||||
"Create Stack": "Create Stack",
|
||||
@ -559,6 +560,7 @@
|
||||
"Delete Security Group": "Delete Security Group",
|
||||
"Delete Server Group": "Delete Server Group",
|
||||
"Delete Share Group Type": "Delete Share Group Type",
|
||||
"Delete Share Network": "Delete Share Network",
|
||||
"Delete Share Type": "Delete Share Type",
|
||||
"Delete Snapshot": "Delete Snapshot",
|
||||
"Delete Static Route": "Delete Static Route",
|
||||
@ -835,6 +837,7 @@
|
||||
"GRE": "GRE",
|
||||
"Gabon": "Gabon",
|
||||
"Gambia": "Gambia",
|
||||
"Gateway": "Gateway",
|
||||
"Gateway IP": "Gateway IP",
|
||||
"Gateway Time-out (code: 504) ": "Gateway Time-out (code: 504) ",
|
||||
"Gateway ip {gateway_ip} conflicts with allocation pool {pool}": "Gateway ip {gateway_ip} conflicts with allocation pool {pool}",
|
||||
@ -1298,6 +1301,7 @@
|
||||
"Network Name": "Network Name",
|
||||
"Network Service": "Network Service",
|
||||
"Network Traffic": "Network Traffic",
|
||||
"Network Type": "Network Type",
|
||||
"Network topology page": "Network topology page",
|
||||
"Networking": "Networking",
|
||||
"Networking *": "Networking *",
|
||||
@ -1305,7 +1309,9 @@
|
||||
"Networks": "Networks",
|
||||
"Neutron Agent Detail": "Neutron Agent Detail",
|
||||
"Neutron Agents": "Neutron Agents",
|
||||
"Neutron Net": "Neutron Net",
|
||||
"Neutron Service": "Neutron Service",
|
||||
"Neutron Subnet": "Neutron Subnet",
|
||||
"New": "New",
|
||||
"New Availability Zone": "New Availability Zone",
|
||||
"New Caledonia": "New Caledonia",
|
||||
@ -1740,6 +1746,7 @@
|
||||
"Security Groups": "Security Groups",
|
||||
"Security Info": "Security Info",
|
||||
"Segmentation ID": "Segmentation ID",
|
||||
"Segmentation Id": "Segmentation Id",
|
||||
"Select File": "Select File",
|
||||
"Select Project": "Select Project",
|
||||
"Select Project Role": "Select Project Role",
|
||||
@ -1775,6 +1782,9 @@
|
||||
"Share Instance": "Share Instance",
|
||||
"Share Instance Detail": "Share Instance Detail",
|
||||
"Share Network": "Share Network",
|
||||
"Share Network Detail": "Share Network Detail",
|
||||
"Share Network Subnet": "Share Network Subnet",
|
||||
"Share Network Subnets": "Share Network Subnets",
|
||||
"Share Server": "Share Server",
|
||||
"Share Type": "Share Type",
|
||||
"Share Type Detail": "Share Type Detail",
|
||||
@ -2286,6 +2296,7 @@
|
||||
"create network": "create network",
|
||||
"create router": "create router",
|
||||
"create share group type": "create share group type",
|
||||
"create share network": "create share network",
|
||||
"create share type": "create share type",
|
||||
"create snapshot": "create snapshot",
|
||||
"create stack": "create stack",
|
||||
@ -2438,6 +2449,7 @@
|
||||
"share group type": "share group type",
|
||||
"share instance": "share instance",
|
||||
"share instances": "share instances",
|
||||
"share network": "share network",
|
||||
"share type": "share type",
|
||||
"share types": "share types",
|
||||
"shelve instance": "shelve instance",
|
||||
|
@ -415,6 +415,7 @@
|
||||
"Create Security Group": "创建安全组",
|
||||
"Create Server Group": "创建云主机组",
|
||||
"Create Share Group Type": "创建共享组类型",
|
||||
"Create Share Network": "创建共享网络",
|
||||
"Create Share Type": "创建共享类型",
|
||||
"Create Snapshot": "创建快照",
|
||||
"Create Stack": "创建堆栈",
|
||||
@ -559,6 +560,7 @@
|
||||
"Delete Security Group": "删除安全组",
|
||||
"Delete Server Group": "删除云主机组",
|
||||
"Delete Share Group Type": "删除共享组类型",
|
||||
"Delete Share Network": "删除共享网络",
|
||||
"Delete Share Type": "删除共享类型",
|
||||
"Delete Snapshot": "删除快照",
|
||||
"Delete Static Route": "删除静态路由",
|
||||
@ -835,6 +837,7 @@
|
||||
"GRE": "",
|
||||
"Gabon": "加蓬",
|
||||
"Gambia": "冈比亚",
|
||||
"Gateway": "网关",
|
||||
"Gateway IP": "网关IP",
|
||||
"Gateway Time-out (code: 504) ": "网关超时(错误码:504 )",
|
||||
"Gateway ip {gateway_ip} conflicts with allocation pool {pool}": "网关地址 {gateway_ip} 和分配地址池 {pool} 冲突",
|
||||
@ -1298,6 +1301,7 @@
|
||||
"Network Name": "网络名称",
|
||||
"Network Service": "网络服务",
|
||||
"Network Traffic": "网络流量",
|
||||
"Network Type": "网络类型",
|
||||
"Network topology page": "网络拓扑页面",
|
||||
"Networking": "创建网络中",
|
||||
"Networking *": "网络 *",
|
||||
@ -1305,7 +1309,9 @@
|
||||
"Networks": "网络",
|
||||
"Neutron Agent Detail": "网络服务详情",
|
||||
"Neutron Agents": "网络服务",
|
||||
"Neutron Net": "Neutron网络",
|
||||
"Neutron Service": "网络服务",
|
||||
"Neutron Subnet": "Neutron子网",
|
||||
"New": "新建",
|
||||
"New Availability Zone": "新可用域",
|
||||
"New Caledonia": "新喀里多尼亚",
|
||||
@ -1740,6 +1746,7 @@
|
||||
"Security Groups": "安全组",
|
||||
"Security Info": "安全信息",
|
||||
"Segmentation ID": "段ID",
|
||||
"Segmentation Id": "分段ID",
|
||||
"Select File": "选择文件",
|
||||
"Select Project": "选择项目",
|
||||
"Select Project Role": "选择项目角色",
|
||||
@ -1775,6 +1782,9 @@
|
||||
"Share Instance": "共享实例",
|
||||
"Share Instance Detail": "共享实例详情",
|
||||
"Share Network": "共享网络",
|
||||
"Share Network Detail": "共享网络详情",
|
||||
"Share Network Subnet": "共享网络子网",
|
||||
"Share Network Subnets": "共享网络子网",
|
||||
"Share Server": "共享服务器",
|
||||
"Share Type": "共享类型",
|
||||
"Share Type Detail": "共享类型详情",
|
||||
@ -2286,6 +2296,7 @@
|
||||
"create network": "创建网络",
|
||||
"create router": "创建路由",
|
||||
"create share group type": "创建共享组类型",
|
||||
"create share network": "创建共享网络",
|
||||
"create share type": "创建共享类型",
|
||||
"create snapshot": "创建快照",
|
||||
"create stack": "创建堆栈",
|
||||
@ -2438,6 +2449,7 @@
|
||||
"share group type": "共享组类型",
|
||||
"share instance": "共享实例",
|
||||
"share instances": "共享实例",
|
||||
"share network": "共享网络",
|
||||
"share type": "共享类型",
|
||||
"share types": "共享类型",
|
||||
"shelve instance": "归档云主机",
|
||||
|
119
src/pages/share/containers/ShareNetwork/Detail/BaseDetail.jsx
Normal file
119
src/pages/share/containers/ShareNetwork/Detail/BaseDetail.jsx
Normal file
@ -0,0 +1,119 @@
|
||||
// Copyright 2021 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.
|
||||
|
||||
import React from 'react';
|
||||
import { inject, observer } from 'mobx-react';
|
||||
import Base from 'containers/BaseDetail';
|
||||
|
||||
export class BaseDetail extends Base {
|
||||
get leftCards() {
|
||||
return [this.baseInfoCard];
|
||||
}
|
||||
|
||||
get rightCards() {
|
||||
return [this.subnetInfos];
|
||||
}
|
||||
|
||||
get baseInfoCard() {
|
||||
const options = [
|
||||
{
|
||||
label: t('Project ID'),
|
||||
dataIndex: 'project_id',
|
||||
},
|
||||
];
|
||||
|
||||
return {
|
||||
title: t('Base Info'),
|
||||
options,
|
||||
};
|
||||
}
|
||||
|
||||
get subnetInfos() {
|
||||
const {
|
||||
share_network_subnets = [],
|
||||
networks = [],
|
||||
subnets = [],
|
||||
} = this.detailData || {};
|
||||
const options = share_network_subnets.map((shareSubnet, index) => {
|
||||
return {
|
||||
label: `${t('Share Network Subnet')} ${index + 1}`,
|
||||
dataIndex: 'subnet',
|
||||
render: () => {
|
||||
const subnet = subnets[index] || {};
|
||||
const network = networks[index] || {};
|
||||
const infos = [
|
||||
{
|
||||
label: t('ID'),
|
||||
value: shareSubnet.id,
|
||||
},
|
||||
{
|
||||
label: t('Neutron Net'),
|
||||
value: this.getLinkRender('networkDetail', network.name, {
|
||||
id: network.id,
|
||||
}),
|
||||
},
|
||||
{
|
||||
label: t('Neutron Subnet'),
|
||||
value: subnet.name,
|
||||
},
|
||||
{
|
||||
label: t('IP Version'),
|
||||
value: shareSubnet.ip_vesion || '-',
|
||||
},
|
||||
{
|
||||
label: t('Network Type'),
|
||||
value: shareSubnet.network_type || '-',
|
||||
},
|
||||
{
|
||||
label: t('Segmentation Id'),
|
||||
value: shareSubnet.segmentation_id || '-',
|
||||
},
|
||||
{
|
||||
label: t('Availability Zone'),
|
||||
value: shareSubnet.availability_zone || '-',
|
||||
},
|
||||
{
|
||||
label: t('Cidr'),
|
||||
value: shareSubnet.cidr || '-',
|
||||
},
|
||||
{
|
||||
label: t('Gateway'),
|
||||
value: shareSubnet.gateway || '-',
|
||||
},
|
||||
{
|
||||
label: t('MTU'),
|
||||
value: shareSubnet.mtu || '-',
|
||||
},
|
||||
];
|
||||
const items = infos.map((it) => {
|
||||
return (
|
||||
<div key={it.label}>
|
||||
<span style={{ fontWeight: 'bold' }}>{it.label}: </span>
|
||||
<span>{it.value}</span>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
return <div key={shareSubnet.id}>{items}</div>;
|
||||
},
|
||||
};
|
||||
});
|
||||
return {
|
||||
title: t('Share Network Subnets'),
|
||||
options,
|
||||
labelCol: 4,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export default inject('rootStore')(observer(BaseDetail));
|
78
src/pages/share/containers/ShareNetwork/Detail/index.jsx
Normal file
78
src/pages/share/containers/ShareNetwork/Detail/index.jsx
Normal file
@ -0,0 +1,78 @@
|
||||
// Copyright 2021 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.
|
||||
|
||||
import { inject, observer } from 'mobx-react';
|
||||
import { ShareNetworkStore } from 'stores/manila/share-network';
|
||||
import Base from 'containers/TabDetail';
|
||||
import BaseDetail from './BaseDetail';
|
||||
import actionConfigs from '../actions';
|
||||
|
||||
export class Detail extends Base {
|
||||
get name() {
|
||||
return t('share network');
|
||||
}
|
||||
|
||||
get policy() {
|
||||
return 'manila:share_network:show';
|
||||
}
|
||||
|
||||
get listUrl() {
|
||||
return this.getRoutePath('shareNetwork');
|
||||
}
|
||||
|
||||
get actionConfigs() {
|
||||
return this.isAdminPage
|
||||
? actionConfigs.actionConfigsAdmin
|
||||
: actionConfigs.actionConfigs;
|
||||
}
|
||||
|
||||
get detailInfos() {
|
||||
return [
|
||||
{
|
||||
title: t('Name'),
|
||||
dataIndex: 'name',
|
||||
},
|
||||
{
|
||||
title: t('Description'),
|
||||
dataIndex: 'description',
|
||||
},
|
||||
{
|
||||
title: t('Created At'),
|
||||
dataIndex: 'created_at',
|
||||
valueRender: 'toLocalTime',
|
||||
},
|
||||
{
|
||||
title: t('Updated'),
|
||||
dataIndex: 'updated_at',
|
||||
valueRender: 'toLocalTime',
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
get tabs() {
|
||||
return [
|
||||
{
|
||||
title: t('Base Info'),
|
||||
key: 'baseInfo',
|
||||
component: BaseDetail,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
init() {
|
||||
this.store = new ShareNetworkStore();
|
||||
}
|
||||
}
|
||||
|
||||
export default inject('rootStore')(observer(Detail));
|
157
src/pages/share/containers/ShareNetwork/actions/Create.jsx
Normal file
157
src/pages/share/containers/ShareNetwork/actions/Create.jsx
Normal file
@ -0,0 +1,157 @@
|
||||
// Copyright 2021 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.
|
||||
|
||||
import { inject, observer } from 'mobx-react';
|
||||
import { ModalAction } from 'containers/Action';
|
||||
import globalShareNetworkStore from 'stores/manila/share-network';
|
||||
import { NetworkStore } from 'stores/neutron/network';
|
||||
import { SubnetStore } from 'stores/neutron/subnet';
|
||||
|
||||
export class Create extends ModalAction {
|
||||
static id = 'create';
|
||||
|
||||
static title = t('Create Share Network');
|
||||
|
||||
get name() {
|
||||
return t('create share network');
|
||||
}
|
||||
|
||||
init() {
|
||||
this.store = globalShareNetworkStore;
|
||||
this.networkStore = new NetworkStore();
|
||||
this.subnetStore = new SubnetStore();
|
||||
}
|
||||
|
||||
static policy = 'manila:share_network:create';
|
||||
|
||||
static allowed = () => Promise.resolve(true);
|
||||
|
||||
static get modalSize() {
|
||||
return 'large';
|
||||
}
|
||||
|
||||
getModalSize() {
|
||||
return 'large';
|
||||
}
|
||||
|
||||
get subnets() {
|
||||
const { networkId } = this.state;
|
||||
if (!networkId) {
|
||||
return [];
|
||||
}
|
||||
return this.subnetStore.list.data || [];
|
||||
}
|
||||
|
||||
getSubnets() {
|
||||
const { networkId } = this.state;
|
||||
if (!networkId) {
|
||||
return;
|
||||
}
|
||||
this.subnetStore.fetchList({ network_id: networkId });
|
||||
}
|
||||
|
||||
onNetworkChange = (value) => {
|
||||
const { selectedRowKeys = [] } = value;
|
||||
if (selectedRowKeys.length === 0) {
|
||||
return;
|
||||
}
|
||||
this.setState(
|
||||
{
|
||||
networkId: selectedRowKeys[0],
|
||||
},
|
||||
() => {
|
||||
this.getSubnets();
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
get nameForStateUpdate() {
|
||||
return ['network'];
|
||||
}
|
||||
|
||||
get formItems() {
|
||||
const { networkId } = this.state;
|
||||
return [
|
||||
{
|
||||
name: 'name',
|
||||
label: t('Name'),
|
||||
type: 'input-name',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: 'description',
|
||||
label: t('Description'),
|
||||
type: 'textarea',
|
||||
},
|
||||
{
|
||||
name: 'network',
|
||||
label: t('Network'),
|
||||
type: 'network-select-table',
|
||||
required: true,
|
||||
onChange: this.onNetworkChange,
|
||||
},
|
||||
{
|
||||
name: 'subnet',
|
||||
label: t('Subnet'),
|
||||
type: 'select-table',
|
||||
data: this.subnets,
|
||||
isLoading: networkId && this.subnetStore.list.isLoading,
|
||||
required: true,
|
||||
filterParams: [
|
||||
{
|
||||
label: t('Name'),
|
||||
name: 'name',
|
||||
},
|
||||
],
|
||||
columns: [
|
||||
{
|
||||
title: t('Name'),
|
||||
dataIndex: 'name',
|
||||
},
|
||||
{
|
||||
title: t('Cidr'),
|
||||
dataIndex: 'cidr',
|
||||
},
|
||||
{
|
||||
title: t('Allocation Pools'),
|
||||
dataIndex: 'allocation_pools',
|
||||
render: (value) => {
|
||||
if (!value || value.length === 0) {
|
||||
return '-';
|
||||
}
|
||||
return `${value[0].start} -- ${value[0].end}`;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: t('Created At'),
|
||||
dataIndex: 'created_at',
|
||||
valueRender: 'sinceTime',
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
onSubmit = (values) => {
|
||||
const { network, subnet, ...rest } = values;
|
||||
const body = {
|
||||
neutron_net_id: network.selectedRowKeys[0],
|
||||
neutron_subnet_id: subnet.selectedRowKeys[0],
|
||||
...rest,
|
||||
};
|
||||
return this.store.create(body);
|
||||
};
|
||||
}
|
||||
|
||||
export default inject('rootStore')(observer(Create));
|
42
src/pages/share/containers/ShareNetwork/actions/Delete.jsx
Normal file
42
src/pages/share/containers/ShareNetwork/actions/Delete.jsx
Normal file
@ -0,0 +1,42 @@
|
||||
// Copyright 2021 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.
|
||||
|
||||
import { ConfirmAction } from 'containers/Action';
|
||||
import globalShareNetworkStore from 'stores/manila/share-network';
|
||||
|
||||
export default class Delete extends ConfirmAction {
|
||||
get id() {
|
||||
return 'delete';
|
||||
}
|
||||
|
||||
get title() {
|
||||
return t('Delete Share Network');
|
||||
}
|
||||
|
||||
get buttonType() {
|
||||
return 'danger';
|
||||
}
|
||||
|
||||
get buttonText() {
|
||||
return t('Delete');
|
||||
}
|
||||
|
||||
get actionName() {
|
||||
return t('Delete Share Network');
|
||||
}
|
||||
|
||||
policy = 'manila:share_network:delete';
|
||||
|
||||
onSubmit = (data) => globalShareNetworkStore.delete(data);
|
||||
}
|
63
src/pages/share/containers/ShareNetwork/actions/Edit.jsx
Normal file
63
src/pages/share/containers/ShareNetwork/actions/Edit.jsx
Normal file
@ -0,0 +1,63 @@
|
||||
// Copyright 2021 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.
|
||||
|
||||
import { inject, observer } from 'mobx-react';
|
||||
import { ModalAction } from 'containers/Action';
|
||||
import globalShareNetworkStore from 'stores/manila/share-network';
|
||||
|
||||
export class Edit extends ModalAction {
|
||||
static id = 'edit';
|
||||
|
||||
static title = t('Edit');
|
||||
|
||||
get defaultValue() {
|
||||
const { name, description } = this.item;
|
||||
const value = {
|
||||
name,
|
||||
description,
|
||||
};
|
||||
return value;
|
||||
}
|
||||
|
||||
static policy = 'manila:share_network:update';
|
||||
|
||||
static allowed = () => Promise.resolve(true);
|
||||
|
||||
get formItems() {
|
||||
return [
|
||||
{
|
||||
name: 'name',
|
||||
label: t('Name'),
|
||||
type: 'input-name',
|
||||
required: true,
|
||||
},
|
||||
{
|
||||
name: 'description',
|
||||
label: t('Description'),
|
||||
type: 'textarea',
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
init() {
|
||||
this.store = globalShareNetworkStore;
|
||||
}
|
||||
|
||||
onSubmit = (values) => {
|
||||
const { id } = this.item;
|
||||
return this.store.update(id, values);
|
||||
};
|
||||
}
|
||||
|
||||
export default inject('rootStore')(observer(Edit));
|
41
src/pages/share/containers/ShareNetwork/actions/index.jsx
Normal file
41
src/pages/share/containers/ShareNetwork/actions/index.jsx
Normal file
@ -0,0 +1,41 @@
|
||||
// Copyright 2021 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.
|
||||
|
||||
import Create from './Create';
|
||||
import Delete from './Delete';
|
||||
import Edit from './Edit';
|
||||
|
||||
const actionConfigs = {
|
||||
rowActions: {
|
||||
firstAction: Edit,
|
||||
moreActions: [
|
||||
{
|
||||
action: Delete,
|
||||
},
|
||||
],
|
||||
},
|
||||
primaryActions: [Create],
|
||||
batchActions: [Delete],
|
||||
};
|
||||
|
||||
const actionConfigsAdmin = {
|
||||
rowActions: {
|
||||
firstAction: Delete,
|
||||
moreActions: [],
|
||||
},
|
||||
primaryActions: [],
|
||||
batchActions: [],
|
||||
};
|
||||
|
||||
export default { actionConfigs, actionConfigsAdmin };
|
110
src/pages/share/containers/ShareNetwork/index.jsx
Normal file
110
src/pages/share/containers/ShareNetwork/index.jsx
Normal file
@ -0,0 +1,110 @@
|
||||
// Copyright 2021 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.
|
||||
|
||||
import React from 'react';
|
||||
import { observer, inject } from 'mobx-react';
|
||||
import Base from 'containers/List';
|
||||
import globalShareNetworkStore from 'stores/manila/share-network';
|
||||
import PopoverSubnets from 'components/Popover/PopoverSubnets';
|
||||
import PopoverNetworks from 'components/Popover/PopoverNetworks';
|
||||
import actionConfigs from './actions';
|
||||
|
||||
export class ShareNetwork extends Base {
|
||||
init() {
|
||||
this.store = globalShareNetworkStore;
|
||||
}
|
||||
|
||||
get policy() {
|
||||
return 'manila:share_network:detail';
|
||||
}
|
||||
|
||||
get name() {
|
||||
return t('share types');
|
||||
}
|
||||
|
||||
get actionConfigs() {
|
||||
return this.isAdminPage
|
||||
? actionConfigs.actionConfigsAdmin
|
||||
: actionConfigs.actionConfigs;
|
||||
}
|
||||
|
||||
getColumns = () => [
|
||||
{
|
||||
title: t('ID/Name'),
|
||||
dataIndex: 'name',
|
||||
routeName: this.getRouteName('shareNetworkDetail'),
|
||||
},
|
||||
{
|
||||
title: t('Project ID/Name'),
|
||||
dataIndex: 'project_name',
|
||||
isHideable: true,
|
||||
hidden: !this.isAdminPage,
|
||||
},
|
||||
{
|
||||
title: t('Description'),
|
||||
dataIndex: 'description',
|
||||
},
|
||||
{
|
||||
title: t('Neutron Net'),
|
||||
dataIndex: 'networks',
|
||||
render: (_, record) => {
|
||||
const { share_network_subnets: subnets = [] } = record;
|
||||
const links = subnets.map((it) => {
|
||||
const { neutron_net_id: id } = it;
|
||||
const link = this.getLinkRender('networkDetail', id, { id });
|
||||
return <div key={it.id}>{link}</div>;
|
||||
});
|
||||
const networkIds = subnets.map((it) => it.neutron_net_id);
|
||||
return (
|
||||
<>
|
||||
{links} <PopoverNetworks networkIds={networkIds} />
|
||||
</>
|
||||
);
|
||||
},
|
||||
stringify: (_, record) => {
|
||||
const { share_network_subnets: subnets = [] } = record;
|
||||
return (subnets || []).map((it) => it.neutron_net_id).join(', ');
|
||||
},
|
||||
},
|
||||
{
|
||||
title: t('Neutron Subnet'),
|
||||
dataIndex: 'share_network_subnets',
|
||||
render: (_, record) => {
|
||||
const { share_network_subnets: subnets = [] } = record;
|
||||
const idItems = subnets.map((it) => {
|
||||
const { neutron_subnet_id } = it;
|
||||
return <div key={it.id}>{neutron_subnet_id}</div>;
|
||||
});
|
||||
const ids = subnets.map((it) => it.neutron_subnet_id);
|
||||
return (
|
||||
<>
|
||||
{idItems} <PopoverSubnets subnetIds={ids} />
|
||||
</>
|
||||
);
|
||||
},
|
||||
stringify: (_, record) => {
|
||||
const { share_network_subnets: subnets = [] } = record;
|
||||
return (subnets || []).map((it) => it.neutron_subnet_id).join(', ');
|
||||
},
|
||||
},
|
||||
{
|
||||
title: t('Created At'),
|
||||
dataIndex: 'created_at',
|
||||
isHideable: true,
|
||||
valueRender: 'sinceTime',
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
export default inject('rootStore')(observer(ShareNetwork));
|
@ -20,6 +20,8 @@ import ShareGroupType from '../containers/ShareGroupType';
|
||||
import ShareGroupTypeDetail from '../containers/ShareGroupType/Detail';
|
||||
import ShareInstance from '../containers/ShareInstance';
|
||||
import ShareInstanceDetail from '../containers/ShareInstance/Detail';
|
||||
import ShareNetwork from '../containers/ShareNetwork';
|
||||
import ShareNetworkDetail from '../containers/ShareNetwork/Detail';
|
||||
|
||||
const PATH = '/share';
|
||||
export default [
|
||||
@ -53,6 +55,26 @@ export default [
|
||||
component: ShareInstanceDetail,
|
||||
exact: true,
|
||||
},
|
||||
{
|
||||
path: `${PATH}/share-network`,
|
||||
component: ShareNetwork,
|
||||
exact: true,
|
||||
},
|
||||
{
|
||||
path: `${PATH}/share-network/detail/:id`,
|
||||
component: ShareNetworkDetail,
|
||||
exact: true,
|
||||
},
|
||||
{
|
||||
path: `${PATH}/share-network-admin`,
|
||||
component: ShareNetwork,
|
||||
exact: true,
|
||||
},
|
||||
{
|
||||
path: `${PATH}/share-network-admin/detail/:id`,
|
||||
component: ShareNetworkDetail,
|
||||
exact: true,
|
||||
},
|
||||
{ path: '*', component: E404 },
|
||||
],
|
||||
},
|
||||
|
84
src/stores/manila/share-network.js
Normal file
84
src/stores/manila/share-network.js
Normal file
@ -0,0 +1,84 @@
|
||||
// Copyright 2021 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.
|
||||
|
||||
import { action } from 'mobx';
|
||||
import client from 'client';
|
||||
import Base from 'stores/base';
|
||||
|
||||
export class ShareNetworkStore extends Base {
|
||||
get client() {
|
||||
return client.manila.shareNetworks;
|
||||
}
|
||||
|
||||
get networkClient() {
|
||||
return client.neutron.networks;
|
||||
}
|
||||
|
||||
get subnetClient() {
|
||||
return client.neutron.subnets;
|
||||
}
|
||||
|
||||
get listWithDetail() {
|
||||
return true;
|
||||
}
|
||||
|
||||
get paramsFunc() {
|
||||
return (params) => {
|
||||
const { all_projects, ...rest } = params;
|
||||
return {
|
||||
...rest,
|
||||
all_tenants: all_projects ? 1 : 0,
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
async detailDidFetch(item) {
|
||||
const { share_network_subnets: subnets = [] } = item;
|
||||
const subnetIds = subnets.map((it) => it.neutron_subnet_id);
|
||||
const networkIds = subnets.map((it) => it.neutron_net_id);
|
||||
const subnetReqs = Array.from(new Set(subnetIds)).map((it) => {
|
||||
return this.subnetClient.show(it);
|
||||
});
|
||||
const netReqs = Array.from(new Set(networkIds)).map((it) => {
|
||||
return this.networkClient.show(it);
|
||||
});
|
||||
const subnetResults = await Promise.all(subnetReqs);
|
||||
const netResults = await Promise.all(netReqs);
|
||||
return {
|
||||
...item,
|
||||
subnets: subnets
|
||||
.map((it) => {
|
||||
return subnetResults.find(
|
||||
(s) => s.subnet.id === it.neutron_subnet_id
|
||||
);
|
||||
})
|
||||
.map((it) => it.subnet),
|
||||
networks: subnets
|
||||
.map((it) => {
|
||||
return netResults.find((net) => net.network.id === it.neutron_net_id);
|
||||
})
|
||||
.map((it) => it.network),
|
||||
};
|
||||
}
|
||||
|
||||
@action
|
||||
update(id, data) {
|
||||
const body = {};
|
||||
body[this.responseKey] = data;
|
||||
return this.submitting(this.client.update(id, body));
|
||||
}
|
||||
}
|
||||
|
||||
const globalShareNetworkStore = new ShareNetworkStore();
|
||||
export default globalShareNetworkStore;
|
Loading…
Reference in New Issue
Block a user