diff --git a/src/components/TableButton/RuleButton.jsx b/src/components/TableButton/RuleButton.jsx
index 63eef477..3fd83769 100644
--- a/src/components/TableButton/RuleButton.jsx
+++ b/src/components/TableButton/RuleButton.jsx
@@ -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 ;
diff --git a/src/components/Tables/Base/index.jsx b/src/components/Tables/Base/index.jsx
index 3713f169..814e80b0 100644
--- a/src/components/Tables/Base/index.jsx
+++ b/src/components/Tables/Base/index.jsx
@@ -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 = {
diff --git a/src/locales/en.json b/src/locales/en.json
index 5f884343..7c487da6 100644
--- a/src/locales/en.json
+++ b/src/locales/en.json
@@ -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",
diff --git a/src/locales/zh.json b/src/locales/zh.json
index 4bd47211..4c93adbc 100644
--- a/src/locales/zh.json
+++ b/src/locales/zh.json
@@ -77,6 +77,7 @@
"All Image": "全部镜像",
"All Network": "所有网络",
"All Port": "所有端口",
+ "All Proto": "所有协议",
"All QoS Policy": "所有QoS策略",
"All TCP": "所有TCP协议",
"All UDP": "所有UDP协议",
diff --git a/src/pages/compute/containers/Instance/Detail/BaseDetail/index.jsx b/src/pages/compute/containers/Instance/Detail/BaseDetail/index.jsx
index 0bb9c27b..2958cf90 100644
--- a/src/pages/compute/containers/Instance/Detail/BaseDetail/index.jsx
+++ b/src/pages/compute/containers/Instance/Detail/BaseDetail/index.jsx
@@ -168,13 +168,15 @@ export default class BaseDetail extends Base {
label: t('Name'),
dataIndex: 'security_groups',
render: () =>
- (items || []).map((it) => (
-
-
- {it}
-
-
- )),
+ items && items.length
+ ? items.map((it) => (
+
+
+ {it}
+
+
+ ))
+ : '-',
},
];
return {
diff --git a/src/pages/compute/containers/Instance/Detail/SecurityGroup/index.jsx b/src/pages/compute/containers/Instance/Detail/SecurityGroup/index.jsx
index 60f14fcf..c9733641 100644
--- a/src/pages/compute/containers/Instance/Detail/SecurityGroup/index.jsx
+++ b/src/pages/compute/containers/Instance/Detail/SecurityGroup/index.jsx
@@ -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}
/>
@@ -151,7 +157,7 @@ export default class SecurityGroup extends React.Component {
pagination={false}
bordered={false}
{...this.state}
- columns={tableColumns}
+ columns={this.tableColumns}
dataSource={IngressData}
/>
@@ -191,21 +197,21 @@ export default class SecurityGroup extends React.Component {
const { filterData, activeInterfaceId } = this.state;
return (
-
-
- {interfaces
- ? toJS(interfaces).map((item, index) =>
- this.renderRadio(item, index)
- )
- : null}
-
-
+ {interfaces && interfaces.length ? (
+
+
+ {toJS(interfaces).map((item, index) =>
+ this.renderRadio(item, index)
+ )}
+
+
+ ) : null}
{!this.isAdminPage && (
{t('Attach Security Group')} */}
)}
-
- (
-
- )}
- >
- {filterData
- ? filterData.map((item, index) => this.renderPanel(item, index))
- : null}
-
-
+ {filterData && filterData.length ? (
+
+ (
+
+ )}
+ >
+ {filterData.map((item, index) => this.renderPanel(item, index))}
+
+
+ ) : null}
);
}
diff --git a/src/pages/network/containers/SecurityGroup/Detail/Rule/actions/Create.jsx b/src/pages/network/containers/SecurityGroup/Detail/Rule/actions/Create.jsx
index 66a92534..fc1a704f 100644
--- a/src/pages/network/containers/SecurityGroup/Detail/Rule/actions/Create.jsx
+++ b/src/pages/network/containers/SecurityGroup/Detail/Rule/actions/Create.jsx
@@ -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);
};
}
diff --git a/src/pages/network/containers/SecurityGroup/Detail/Rule/index.jsx b/src/pages/network/containers/SecurityGroup/Detail/Rule/index.jsx
index f2f3cde4..b5a74700 100644
--- a/src/pages/network/containers/SecurityGroup/Detail/Rule/index.jsx
+++ b/src/pages/network/containers/SecurityGroup/Detail/Rule/index.jsx
@@ -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
diff --git a/src/pages/network/containers/SecurityGroup/Detail/index.jsx b/src/pages/network/containers/SecurityGroup/Detail/index.jsx
index ab93db6c..b147c513 100644
--- a/src/pages/network/containers/SecurityGroup/Detail/index.jsx
+++ b/src/pages/network/containers/SecurityGroup/Detail/index.jsx
@@ -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();
+ }
+ }
}
diff --git a/src/pages/network/containers/SecurityGroup/actions/index.jsx b/src/pages/network/containers/SecurityGroup/actions/index.jsx
index a6dc8c86..6be7b9a1 100644
--- a/src/pages/network/containers/SecurityGroup/actions/index.jsx
+++ b/src/pages/network/containers/SecurityGroup/actions/index.jsx
@@ -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,
},
diff --git a/src/pages/network/containers/VirtualAdapter/Detail/SecurityGroups/index.jsx b/src/pages/network/containers/VirtualAdapter/Detail/SecurityGroups/index.jsx
index 60779227..a5b8be4a 100644
--- a/src/pages/network/containers/VirtualAdapter/Detail/SecurityGroups/index.jsx
+++ b/src/pages/network/containers/VirtualAdapter/Detail/SecurityGroups/index.jsx
@@ -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
}
diff --git a/src/resources/security-group-rule.js b/src/resources/security-group-rule.jsx
similarity index 88%
rename from src/resources/security-group-rule.js
rename to src/resources/security-group-rule.jsx
index c5ffdf52..526f9f57 100644
--- a/src/resources/security-group-rule.js
+++ b/src/resources/security-group-rule.jsx
@@ -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 (
+
+ {value ? (
+
+ {value}
+
+ ) : (
+ '-'
+ )}
+
+ );
+ },
},
{
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';