fix: Fix securityGroup Rule creating
1. Change protocol list 2. Add creating button in securityGroup list 3. Add link for remote group id Change-Id: I76f10ffbd513d4e40f658ec8acb61e3311cfedf1
This commit is contained in:
parent
74d8165834
commit
ad94bb6345
@ -14,7 +14,7 @@
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import TableButton from 'components/TableButton';
|
||||
import { columns } from 'resources/security-group-rule';
|
||||
import { getSelfColumns } from 'resources/security-group-rule';
|
||||
|
||||
export default class RuleButton extends Component {
|
||||
render() {
|
||||
@ -24,7 +24,7 @@ export default class RuleButton extends Component {
|
||||
title: t('Security Group Rules'),
|
||||
buttonText: t('View Rules'),
|
||||
modalSize: 'middle',
|
||||
columns,
|
||||
columns: getSelfColumns(this),
|
||||
datas,
|
||||
};
|
||||
return <TableButton {...configs} style={{ paddingLeft: 0 }} />;
|
||||
|
@ -85,6 +85,8 @@ export default class BaseTable extends React.Component {
|
||||
hideTotal: PropTypes.bool,
|
||||
hideDownload: PropTypes.bool,
|
||||
primaryActionsExtra: PropTypes.any,
|
||||
isAdminPage: PropTypes.bool,
|
||||
containerProps: PropTypes.any,
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
|
@ -77,6 +77,7 @@
|
||||
"All Image": "All Image",
|
||||
"All Network": "All Network",
|
||||
"All Port": "All Port",
|
||||
"All Proto": "All Proto",
|
||||
"All QoS Policy": "All QoS Policy",
|
||||
"All TCP": "All TCP",
|
||||
"All UDP": "All UDP",
|
||||
|
@ -77,6 +77,7 @@
|
||||
"All Image": "全部镜像",
|
||||
"All Network": "所有网络",
|
||||
"All Port": "所有端口",
|
||||
"All Proto": "所有协议",
|
||||
"All QoS Policy": "所有QoS策略",
|
||||
"All TCP": "所有TCP协议",
|
||||
"All UDP": "所有UDP协议",
|
||||
|
@ -168,13 +168,15 @@ export default class BaseDetail extends Base {
|
||||
label: t('Name'),
|
||||
dataIndex: 'security_groups',
|
||||
render: () =>
|
||||
(items || []).map((it) => (
|
||||
items && items.length
|
||||
? items.map((it) => (
|
||||
<div key={it}>
|
||||
<Link to={`${url}?tab=securityGroup`} key={it}>
|
||||
{it}
|
||||
</Link>
|
||||
</div>
|
||||
)),
|
||||
))
|
||||
: '-',
|
||||
},
|
||||
];
|
||||
return {
|
||||
|
@ -32,7 +32,7 @@ import classnames from 'classnames';
|
||||
import interfaceImg from '@/asset/image/interface.png';
|
||||
import { CaretRightOutlined } from '@ant-design/icons';
|
||||
import ItemActionButtons from 'components/Tables/Base/ItemActionButtons';
|
||||
import { columns } from 'resources/security-group-rule';
|
||||
import { getSelfColumns } from 'resources/security-group-rule';
|
||||
import { isAdminPage } from 'utils/index';
|
||||
import styles from './index.less';
|
||||
import Detach from './action/Detach';
|
||||
@ -40,7 +40,6 @@ import ManageSecurityGroup from './action/ManageSecurityGroup';
|
||||
|
||||
const { Panel } = Collapse;
|
||||
const { TabPane } = Tabs;
|
||||
const tableColumns = columns.filter((it) => it.dataIndex !== 'direction');
|
||||
|
||||
@inject('rootStore')
|
||||
@observer
|
||||
@ -53,6 +52,9 @@ export default class SecurityGroup extends React.Component {
|
||||
filterData: [],
|
||||
};
|
||||
this.store = globalServerStore;
|
||||
this.tableColumns = getSelfColumns(this).filter(
|
||||
(it) => it.dataIndex !== 'direction'
|
||||
);
|
||||
}
|
||||
|
||||
componentDidMount = async () => {
|
||||
@ -64,6 +66,10 @@ export default class SecurityGroup extends React.Component {
|
||||
return isAdminPage(pathname);
|
||||
}
|
||||
|
||||
getUrl(path, adminStr) {
|
||||
return this.isAdminPage ? `${path}${adminStr || '-admin'}` : path;
|
||||
}
|
||||
|
||||
actionCallback = async (first) => {
|
||||
const {
|
||||
match: {
|
||||
@ -84,7 +90,7 @@ export default class SecurityGroup extends React.Component {
|
||||
(it) => item.security_groups.indexOf(it.id) !== -1
|
||||
);
|
||||
this.setState({
|
||||
activeInterfaceId: item.id,
|
||||
activeInterfaceId: item && item.id,
|
||||
activeInterface: item,
|
||||
filterData,
|
||||
});
|
||||
@ -141,7 +147,7 @@ export default class SecurityGroup extends React.Component {
|
||||
pagination={false}
|
||||
bordered={false}
|
||||
{...this.state}
|
||||
columns={tableColumns}
|
||||
columns={this.tableColumns}
|
||||
dataSource={egressData}
|
||||
/>
|
||||
</TabPane>
|
||||
@ -151,7 +157,7 @@ export default class SecurityGroup extends React.Component {
|
||||
pagination={false}
|
||||
bordered={false}
|
||||
{...this.state}
|
||||
columns={tableColumns}
|
||||
columns={this.tableColumns}
|
||||
dataSource={IngressData}
|
||||
/>
|
||||
</TabPane>
|
||||
@ -191,6 +197,7 @@ export default class SecurityGroup extends React.Component {
|
||||
const { filterData, activeInterfaceId } = this.state;
|
||||
return (
|
||||
<div className={classnames(styles.wrapper, this.className)}>
|
||||
{interfaces && interfaces.length ? (
|
||||
<Spin spinning={isLoading}>
|
||||
<Radio.Group
|
||||
defaultValue={0}
|
||||
@ -199,13 +206,12 @@ export default class SecurityGroup extends React.Component {
|
||||
onChange={this.onChange}
|
||||
className={styles['radio-button']}
|
||||
>
|
||||
{interfaces
|
||||
? toJS(interfaces).map((item, index) =>
|
||||
{toJS(interfaces).map((item, index) =>
|
||||
this.renderRadio(item, index)
|
||||
)
|
||||
: null}
|
||||
)}
|
||||
</Radio.Group>
|
||||
</Spin>
|
||||
) : null}
|
||||
{!this.isAdminPage && (
|
||||
<div style={{ marginBottom: 20, marginTop: 20 }}>
|
||||
<PrimaryActionButtons
|
||||
@ -221,6 +227,7 @@ export default class SecurityGroup extends React.Component {
|
||||
{/* <Button type="primary" shape="circle" size={5} onClick={this.refresh}>{t('Attach Security Group')}</Button> */}
|
||||
</div>
|
||||
)}
|
||||
{filterData && filterData.length ? (
|
||||
<Spin spinning={isLoading}>
|
||||
<Collapse
|
||||
className={styles.collapse}
|
||||
@ -230,11 +237,10 @@ export default class SecurityGroup extends React.Component {
|
||||
<CaretRightOutlined rotate={isActive ? 90 : 0} />
|
||||
)}
|
||||
>
|
||||
{filterData
|
||||
? filterData.map((item, index) => this.renderPanel(item, index))
|
||||
: null}
|
||||
{filterData.map((item, index) => this.renderPanel(item, index))}
|
||||
</Collapse>
|
||||
</Spin>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -78,8 +78,9 @@ export default class Create extends ModalAction {
|
||||
name: t('Custom ICMP Rule'),
|
||||
ip_protocol: 'icmp',
|
||||
},
|
||||
custom_protocol: {
|
||||
name: t('Other Protocol'),
|
||||
all_proto: {
|
||||
name: t('All Proto'),
|
||||
ip_protocol: null,
|
||||
},
|
||||
all_tcp: {
|
||||
name: t('All TCP'),
|
||||
@ -97,90 +98,8 @@ export default class Create extends ModalAction {
|
||||
name: t('All ICMP'),
|
||||
ip_protocol: 'icmp',
|
||||
},
|
||||
// settingRules
|
||||
ssh: {
|
||||
name: 'SSH',
|
||||
ip_protocol: 'tcp',
|
||||
from_port: '22',
|
||||
to_port: '22',
|
||||
},
|
||||
smtp: {
|
||||
name: 'SMTP',
|
||||
ip_protocol: 'tcp',
|
||||
from_port: '25',
|
||||
to_port: '25',
|
||||
},
|
||||
dns: {
|
||||
name: 'DNS',
|
||||
ip_protocol: 'tcp',
|
||||
from_port: '53',
|
||||
to_port: '53',
|
||||
},
|
||||
http: {
|
||||
name: 'HTTP',
|
||||
ip_protocol: 'tcp',
|
||||
from_port: '80',
|
||||
to_port: '80',
|
||||
},
|
||||
pop3: {
|
||||
name: 'POP3',
|
||||
ip_protocol: 'tcp',
|
||||
from_port: '110',
|
||||
to_port: '110',
|
||||
},
|
||||
imap: {
|
||||
name: 'IMAP',
|
||||
ip_protocol: 'tcp',
|
||||
from_port: '143',
|
||||
to_port: '143',
|
||||
},
|
||||
ldap: {
|
||||
name: 'LDAP',
|
||||
ip_protocol: 'tcp',
|
||||
from_port: '389',
|
||||
to_port: '389',
|
||||
},
|
||||
https: {
|
||||
name: 'HTTPS',
|
||||
ip_protocol: 'tcp',
|
||||
from_port: '443',
|
||||
to_port: '443',
|
||||
},
|
||||
smtps: {
|
||||
name: 'SMTPS',
|
||||
ip_protocol: 'tcp',
|
||||
from_port: '465',
|
||||
to_port: '465',
|
||||
},
|
||||
imaps: {
|
||||
name: 'IMAPS',
|
||||
ip_protocol: 'tcp',
|
||||
from_port: '993',
|
||||
to_port: '993',
|
||||
},
|
||||
pop3s: {
|
||||
name: 'POP3S',
|
||||
ip_protocol: 'tcp',
|
||||
from_port: '995',
|
||||
to_port: '995',
|
||||
},
|
||||
ms_sql: {
|
||||
name: 'MS SQL',
|
||||
ip_protocol: 'tcp',
|
||||
from_port: '1433',
|
||||
to_port: '1433',
|
||||
},
|
||||
mysql: {
|
||||
name: 'MYSQL',
|
||||
ip_protocol: 'tcp',
|
||||
from_port: '3306',
|
||||
to_port: '3306',
|
||||
},
|
||||
rdp: {
|
||||
name: 'RDP',
|
||||
ip_protocol: 'tcp',
|
||||
from_port: '3389',
|
||||
to_port: '3389',
|
||||
custom_protocol: {
|
||||
name: t('Other Protocol'),
|
||||
},
|
||||
};
|
||||
}
|
||||
@ -229,7 +148,6 @@ export default class Create extends ModalAction {
|
||||
{
|
||||
remote_ip_prefix: '',
|
||||
remote_group_id: '',
|
||||
ethertype: '',
|
||||
},
|
||||
() => {
|
||||
this.updateDefaultValue();
|
||||
@ -271,6 +189,16 @@ export default class Create extends ModalAction {
|
||||
{ value: 'egress', label: t('Egress') },
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'ethertype',
|
||||
label: t('Ether Type'),
|
||||
type: 'select',
|
||||
required: true,
|
||||
options: [
|
||||
{ value: 'IPv4', label: t('IPv4') },
|
||||
{ value: 'IPv6', label: t('IPv6') },
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'portOrRange',
|
||||
label: t('Port Type'),
|
||||
@ -348,17 +276,6 @@ export default class Create extends ModalAction {
|
||||
hidden: !showSgAndEther,
|
||||
options: this.allGroups,
|
||||
},
|
||||
{
|
||||
name: 'ethertype',
|
||||
label: t('Ether Type'),
|
||||
type: 'select',
|
||||
required: showSgAndEther,
|
||||
hidden: !showSgAndEther,
|
||||
options: [
|
||||
{ value: 'IPv4', label: t('IPv4') },
|
||||
{ value: 'IPv6', label: t('IPv6') },
|
||||
],
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
@ -383,7 +300,7 @@ export default class Create extends ModalAction {
|
||||
? this.defaultRules[protocol].ip_protocol
|
||||
: ipProtocol;
|
||||
const modalValue = {
|
||||
security_group_id: id,
|
||||
security_group_id: id || this.item.id,
|
||||
port_range_min:
|
||||
protocol === 'custom_icmp'
|
||||
? icmpType
|
||||
@ -399,6 +316,10 @@ export default class Create extends ModalAction {
|
||||
protocol: newProtocol,
|
||||
...rest,
|
||||
};
|
||||
if (protocol.includes('all')) {
|
||||
delete modalValue.remote_ip_prefix;
|
||||
delete modalValue.remote_group_id;
|
||||
}
|
||||
return this.store.create(modalValue);
|
||||
};
|
||||
}
|
||||
|
@ -15,7 +15,7 @@
|
||||
import { observer, inject } from 'mobx-react';
|
||||
import Base from 'containers/List';
|
||||
import globalSecurityGroupRuleStore from 'stores/neutron/security-rule';
|
||||
import { columns, filterParams } from 'resources/security-group-rule';
|
||||
import { filterParams, getSelfColumns } from 'resources/security-group-rule';
|
||||
import actionConfigs from './actions';
|
||||
|
||||
@inject('rootStore')
|
||||
@ -33,7 +33,7 @@ export default class Rule extends Base {
|
||||
return t('security group rules');
|
||||
}
|
||||
|
||||
getColumns = () => columns;
|
||||
getColumns = () => getSelfColumns(this);
|
||||
|
||||
get actionConfigs() {
|
||||
return this.isAdminPage
|
||||
|
@ -15,6 +15,7 @@
|
||||
import { inject, observer } from 'mobx-react';
|
||||
import { SecurityGroupStore } from 'stores/neutron/security-group';
|
||||
import Base from 'containers/TabDetail';
|
||||
import { isEqual } from 'lodash';
|
||||
import members from './Rule';
|
||||
import actionConfigs from '../actions';
|
||||
|
||||
@ -71,4 +72,10 @@ export default class SecurityGroupDetail extends Base {
|
||||
init() {
|
||||
this.store = new SecurityGroupStore();
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
if (!isEqual(this.props.match.params, prevProps.match.params)) {
|
||||
this.fetchDataWithPolicy();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,11 +15,15 @@
|
||||
import Create from './Create';
|
||||
import Edit from './Edit';
|
||||
import Delete from './Delete';
|
||||
import CreateRule from '../Detail/Rule/actions/Create';
|
||||
|
||||
const actionConfigs = {
|
||||
rowActions: {
|
||||
firstAction: Edit,
|
||||
moreActions: [
|
||||
{
|
||||
action: CreateRule,
|
||||
},
|
||||
{
|
||||
action: Delete,
|
||||
},
|
||||
|
@ -23,7 +23,7 @@ import { toJS } from 'mobx';
|
||||
import { CaretRightOutlined } from '@ant-design/icons';
|
||||
import PrimaryActionButtons from 'components/Tables/Base/PrimaryActionButtons';
|
||||
import ItemActionButtons from 'components/Tables/Base/ItemActionButtons';
|
||||
import { columns } from 'resources/security-group-rule';
|
||||
import { getSelfColumns } from 'resources/security-group-rule';
|
||||
import { isAdminPage } from 'utils/index';
|
||||
import Detach from './actions/Detach';
|
||||
import styles from './index.less';
|
||||
@ -42,6 +42,10 @@ export default class SecurityGroup extends React.Component {
|
||||
this.refreshSecurityGroup();
|
||||
}
|
||||
|
||||
getUrl(path, adminStr) {
|
||||
return this.isAdminPage ? `${path}${adminStr || '-admin'}` : path;
|
||||
}
|
||||
|
||||
get portId() {
|
||||
const {
|
||||
detail: { id },
|
||||
@ -109,7 +113,7 @@ export default class SecurityGroup extends React.Component {
|
||||
bordered={false}
|
||||
rowKey="id"
|
||||
{...this.state}
|
||||
columns={columns}
|
||||
columns={getSelfColumns(this)}
|
||||
dataSource={
|
||||
item.security_group_rules ? toJS(item.security_group_rules) : null
|
||||
}
|
||||
|
@ -11,8 +11,9 @@
|
||||
// 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 { isNumber } from 'lodash';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
export const ipProtocols = [
|
||||
{ value: 'ah', label: t('AH') },
|
||||
@ -54,7 +55,7 @@ export const protocols = (protocol) => {
|
||||
return protocol.toUpperCase();
|
||||
};
|
||||
|
||||
export const columns = [
|
||||
export const getSelfColumns = (self) => [
|
||||
{
|
||||
title: t('Direction'),
|
||||
dataIndex: 'direction',
|
||||
@ -79,14 +80,28 @@ export const columns = [
|
||||
{
|
||||
title: t('Remote IP Prefix'),
|
||||
dataIndex: 'remote_ip_prefix',
|
||||
valueRender: 'noValue',
|
||||
render: (value) => value || '0.0.0.0/0',
|
||||
isHideable: true,
|
||||
},
|
||||
{
|
||||
title: t('Remote Group Id'),
|
||||
dataIndex: 'remote_group_id',
|
||||
valueRender: 'noValue',
|
||||
isHideable: true,
|
||||
render: (value) => {
|
||||
return (
|
||||
<div>
|
||||
{value ? (
|
||||
<Link
|
||||
to={`/network/${self.getUrl('security-group')}/detail/${value}`}
|
||||
>
|
||||
{value}
|
||||
</Link>
|
||||
) : (
|
||||
'-'
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
},
|
||||
},
|
||||
{
|
||||
title: t('ICMP Type/ICMP Code'),
|
||||
@ -121,11 +136,6 @@ export const filterParams = [
|
||||
},
|
||||
];
|
||||
|
||||
export const tableOptions = {
|
||||
filterParams,
|
||||
columns,
|
||||
};
|
||||
|
||||
export const mapperRule = (data) => {
|
||||
let icmpTypeCode = '';
|
||||
let port_range = 'Any';
|
Loading…
Reference in New Issue
Block a user