diff --git a/src/client/manila/index.js b/src/client/manila/index.js index 03f53748..68e64aa6 100644 --- a/src/client/manila/index.js +++ b/src/client/manila/index.js @@ -173,6 +173,11 @@ export class ManilaClient extends Base { key: 'quota-sets', responseKey: 'quota_set', }, + { + name: 'shareServers', + key: 'share-servers', + responseKey: 'share_server', + }, ]; } } diff --git a/src/layouts/admin-menu.jsx b/src/layouts/admin-menu.jsx index 80f26372..5f0c1c9c 100644 --- a/src/layouts/admin-menu.jsx +++ b/src/layouts/admin-menu.jsx @@ -469,6 +469,22 @@ const renderMenu = (t) => { }, ], }, + { + path: '/share/share-server-admin', + name: t('Share Server'), + key: 'shareServerAdmin', + level: 1, + endpoints: 'manilav2', + children: [ + { + path: /^\/share\/share-server-admin\/detail\/.[^/]+$/, + name: t('Share Server Detail'), + key: 'shareServerDetailAdmin', + level: 2, + routePath: '/share/share-server-admin/detail/:id', + }, + ], + }, { path: '/share/share-instance-admin', name: t('Share Instance'), diff --git a/src/locales/en.json b/src/locales/en.json index 5ac4dc6f..7ee8cb51 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -581,6 +581,7 @@ "Delete Share Group Type": "Delete Share Group Type", "Delete Share Metadata": "Delete Share Metadata", "Delete Share Network": "Delete Share Network", + "Delete Share Server": "Delete Share Server", "Delete Share Type": "Delete Share Type", "Delete Snapshot": "Delete Snapshot", "Delete Static Route": "Delete Static Route", @@ -1053,6 +1054,7 @@ "Instance Addr": "Instance Addr", "Instance Architecture": "Instance Architecture", "Instance Detail": "Instance Detail", + "Instance ID": "Instance ID", "Instance IP": "Instance IP", "Instance Info": "Instance Info", "Instance Name": "Instance Name", @@ -1622,6 +1624,7 @@ "Provisioning Status": "Provisioning Status", "Public": "Public", "Public Access": "Public Access", + "Public Address": "Public Address", "Public Image": "Public Image", "Public Key": "Public Key", "Published In": "Published In", @@ -1804,6 +1807,7 @@ "Server Group Member": "Server Group Member", "Server Status": "Server Status", "Service": "Service", + "Service Port ID": "Service Port ID", "Service State": "Service State", "Service Status": "Service Status", "Service Status Updated": "Service Status Updated", @@ -1831,6 +1835,7 @@ "Share Protocol": "Share Protocol", "Share Replica ID": "Share Replica ID", "Share Server": "Share Server", + "Share Server Detail": "Share Server Detail", "Share Type": "Share Type", "Share Type Detail": "Share Type Detail", "Share Type ID": "Share Type ID", @@ -2504,6 +2509,8 @@ "share instances": "share instances", "share metadata": "share metadata", "share network": "share network", + "share server": "share server", + "share servers": "share servers", "share type": "share type", "share types": "share types", "shelve instance": "shelve instance", diff --git a/src/locales/zh.json b/src/locales/zh.json index 0be0e8c0..3b848a7a 100644 --- a/src/locales/zh.json +++ b/src/locales/zh.json @@ -581,6 +581,7 @@ "Delete Share Group Type": "删除共享组类型", "Delete Share Metadata": "删除共享元数据", "Delete Share Network": "删除共享网络", + "Delete Share Server": "删除共享服务器", "Delete Share Type": "删除共享类型", "Delete Snapshot": "删除快照", "Delete Static Route": "删除静态路由", @@ -1053,6 +1054,7 @@ "Instance Addr": "所在主机", "Instance Architecture": "云主机架构图", "Instance Detail": "云主机详情", + "Instance ID": "实例ID", "Instance IP": "云主机IP", "Instance Info": "云主机信息", "Instance Name": "云主机名称", @@ -1622,6 +1624,7 @@ "Provisioning Status": "配置状态", "Public": "公有", "Public Access": "公开访问", + "Public Address": "", "Public Image": "公有镜像", "Public Key": "公钥", "Published In": "", @@ -1804,6 +1807,7 @@ "Server Group Member": "云主机组成员", "Server Status": "", "Service": "服务", + "Service Port ID": "服务端口ID", "Service State": "服务状态", "Service Status": "管理状态", "Service Status Updated": "服务状态更新", @@ -1831,6 +1835,7 @@ "Share Protocol": "共享协议", "Share Replica ID": "共享副本ID", "Share Server": "共享服务器", + "Share Server Detail": "共享服务器详情", "Share Type": "共享类型", "Share Type Detail": "共享类型详情", "Share Type ID": "共享类型ID", @@ -2504,6 +2509,8 @@ "share instances": "共享实例", "share metadata": "共享元数据", "share network": "共享网络", + "share server": "共享服务器", + "share servers": "共享服务器", "share type": "共享类型", "share types": "共享类型", "shelve instance": "归档云主机", diff --git a/src/pages/share/containers/Share/Detail/BaseDetail.jsx b/src/pages/share/containers/Share/Detail/BaseDetail.jsx index 7ad500ee..1600c518 100644 --- a/src/pages/share/containers/Share/Detail/BaseDetail.jsx +++ b/src/pages/share/containers/Share/Detail/BaseDetail.jsx @@ -16,7 +16,7 @@ import React from 'react'; import { inject, observer } from 'mobx-react'; import Base from 'containers/BaseDetail'; import { shareProtocol } from 'resources/manila/share'; -import { getYesNo, toLocalTimeFilter } from 'utils/index'; +import { getYesNo } from 'utils/index'; export class BaseDetail extends Base { get leftCards() { @@ -32,7 +32,7 @@ export class BaseDetail extends Base { } get rightCards() { - return [this.exportLocationsCard, this.accessCard]; + return [this.exportLocationsCard]; } get baseInfoCard() { @@ -185,53 +185,6 @@ export class BaseDetail extends Base { labelCol: 4, }; } - - get accessCard() { - const { accessList = [] } = this.detailData; - const access = accessList[0] || {}; - const options = [ - { - label: t('Access Type'), - dataIndex: 'access_type', - render: () => access.access_type, - }, - { - label: t('Access To'), - dataIndex: 'access_to', - render: () => access.access_to, - }, - { - label: t('Access Level'), - dataIndex: 'access_level', - render: () => access.access_level, - }, - { - label: t('State'), - dataIndex: 'state', - render: () => access.state, - }, - { - label: t('Access Key'), - dataIndex: 'access_key', - render: () => access.access_key, - }, - { - label: t('Created At'), - dataIndex: 'created_at', - render: () => toLocalTimeFilter(access.created_at), - }, - { - label: t('Updated At'), - dataIndex: 'updated_at', - render: () => toLocalTimeFilter(access.updated_at), - }, - ]; - return { - title: t('Access Rule'), - options, - labelCol: 4, - }; - } } export default inject('rootStore')(observer(BaseDetail)); diff --git a/src/pages/share/containers/Share/index.jsx b/src/pages/share/containers/Share/index.jsx index 21a29e49..e2137de7 100644 --- a/src/pages/share/containers/Share/index.jsx +++ b/src/pages/share/containers/Share/index.jsx @@ -51,6 +51,11 @@ export class Share extends Base { return this.inDetailPage && pathname.includes('share-network'); } + get inShareServerDetailPage() { + const { pathname } = this.props.location; + return this.inDetailPage && pathname.includes('share-server'); + } + updateFetchParamsByPage = (params) => { const { id, ...rest } = params; const newParams = { ...rest }; @@ -63,6 +68,9 @@ export class Share extends Base { if (this.inShareNetworkDetailPage) { newParams.share_network_id = id; } + if (this.inShareServerDetailPage) { + newParams.share_server_id = id; + } return newParams; }; diff --git a/src/pages/share/containers/ShareInstance/index.jsx b/src/pages/share/containers/ShareInstance/index.jsx index 81d214ba..f13fa168 100644 --- a/src/pages/share/containers/ShareInstance/index.jsx +++ b/src/pages/share/containers/ShareInstance/index.jsx @@ -40,6 +40,7 @@ export class ShareInstance extends Base { dataIndex: 'id', routeName: 'shareInstanceDetailAdmin', isLink: true, + withoutName: true, }, { title: t('Host'), @@ -58,14 +59,26 @@ export class ShareInstance extends Base { { title: t('Share Network'), dataIndex: 'share_network_id', + isLink: true, + routeName: this.getRouteName('shareNetworkDetail'), + idKey: 'share_network_id', + withoutName: true, }, { title: t('Share Server'), dataIndex: 'share_server_id', + isLink: true, + routeName: this.getRouteName('shareServerDetail'), + idKey: 'share_server_id', + withoutName: true, }, { title: t('Share Id'), dataIndex: 'share_id', + isLink: true, + routeName: this.getRouteName('shareDetail'), + idKey: 'share_id', + withoutName: true, }, ]; } diff --git a/src/pages/share/containers/ShareServer/Detail/BaseDetail.jsx b/src/pages/share/containers/ShareServer/Detail/BaseDetail.jsx new file mode 100644 index 00000000..2f2555d2 --- /dev/null +++ b/src/pages/share/containers/ShareServer/Detail/BaseDetail.jsx @@ -0,0 +1,99 @@ +// 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 Base from 'containers/BaseDetail'; + +export class BaseDetail extends Base { + get leftCards() { + return [this.baseInfoCard]; + } + + get rightCards() { + return [this.detailCard]; + } + + get baseInfoCard() { + const options = [ + { + label: t('Host'), + dataIndex: 'host', + }, + { + label: t('Share Network'), + dataIndex: 'share_network_name', + render: (value, record) => { + if (!value) { + return '-'; + } + const { share_network_id } = record; + const link = this.getLinkRender('shareNetworkDetail', value, { + id: share_network_id, + }); + return link; + }, + }, + ]; + + return { + title: t('Base Info'), + options, + }; + } + + get detailCard() { + const options = [ + { + label: t('Instance ID'), + dataIndex: 'backend_details.instance_id', + }, + { + label: t('IP'), + dataIndex: 'backend_details.ip', + }, + { + label: t('Public Address'), + dataIndex: 'backend_details.public_address', + }, + { + label: t('Username'), + dataIndex: 'backend_details.username', + }, + { + label: t('Password'), + dataIndex: 'backend_details.password', + }, + { + label: t('Router ID'), + dataIndex: 'backend_details.router_id', + }, + { + label: t('Subnet ID'), + dataIndex: 'backend_details.subnet_id', + }, + { + label: t('Service Port ID'), + dataIndex: 'backend_details.service_port_id', + }, + ]; + + return { + title: t('Detail Info'), + options, + labelCol: 4, + }; + } +} + +export default inject('rootStore')(observer(BaseDetail)); diff --git a/src/pages/share/containers/ShareServer/Detail/index.jsx b/src/pages/share/containers/ShareServer/Detail/index.jsx new file mode 100644 index 00000000..39a6aa4b --- /dev/null +++ b/src/pages/share/containers/ShareServer/Detail/index.jsx @@ -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 { inject, observer } from 'mobx-react'; +import { ShareServerStore } from 'stores/manila/share-server'; +import Base from 'containers/TabDetail'; +import { shareServerStatus } from 'resources/manila/share-server'; +import Share from 'pages/share/containers/Share'; +import BaseDetail from './BaseDetail'; +import actionConfigs from '../actions'; + +export class Detail extends Base { + get name() { + return t('share server'); + } + + get policy() { + return 'manila:share_server:show'; + } + + get listUrl() { + return this.getRoutePath('shareServer'); + } + + get actionConfigs() { + return actionConfigs; + } + + get detailInfos() { + return [ + { + title: t('Host'), + dataIndex: 'host', + }, + { + title: t('Status'), + dataIndex: 'status', + render: (value) => shareServerStatus[value] || value, + }, + { + title: t('Created'), + dataIndex: 'created_at', + valueRender: 'toLocalTime', + }, + { + title: t('Updated'), + dataIndex: 'updated_at', + valueRender: 'toLocalTime', + }, + ]; + } + + get tabs() { + return [ + { + title: t('Base Info'), + key: 'baseInfo', + component: BaseDetail, + }, + { + title: t('Share'), + key: 'share', + component: Share, + }, + ]; + } + + init() { + this.store = new ShareServerStore(); + } +} + +export default inject('rootStore')(observer(Detail)); diff --git a/src/pages/share/containers/ShareServer/actions/Delete.jsx b/src/pages/share/containers/ShareServer/actions/Delete.jsx new file mode 100644 index 00000000..ea553fcd --- /dev/null +++ b/src/pages/share/containers/ShareServer/actions/Delete.jsx @@ -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 globalShareServerStore from 'stores/manila/share-server'; + +export default class Delete extends ConfirmAction { + get id() { + return 'delete'; + } + + get title() { + return t('Delete Share Server'); + } + + get buttonType() { + return 'danger'; + } + + get buttonText() { + return t('Delete'); + } + + get actionName() { + return t('Delete Share Server'); + } + + policy = 'manila:share_server:delete'; + + onSubmit = (data) => globalShareServerStore.delete(data); +} diff --git a/src/pages/share/containers/ShareServer/actions/index.jsx b/src/pages/share/containers/ShareServer/actions/index.jsx new file mode 100644 index 00000000..e553605e --- /dev/null +++ b/src/pages/share/containers/ShareServer/actions/index.jsx @@ -0,0 +1,26 @@ +// 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 Delete from './Delete'; + +const actionConfigs = { + rowActions: { + firstAction: Delete, + moreActions: [], + }, + primaryActions: [], + batchActions: [Delete], +}; + +export default actionConfigs; diff --git a/src/pages/share/containers/ShareServer/index.jsx b/src/pages/share/containers/ShareServer/index.jsx new file mode 100644 index 00000000..7ce01c8e --- /dev/null +++ b/src/pages/share/containers/ShareServer/index.jsx @@ -0,0 +1,71 @@ +// 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 { observer, inject } from 'mobx-react'; +import Base from 'containers/List'; +import globalShareServerStore from 'stores/manila/share-server'; +import { shareServerStatus } from 'resources/manila/share-server'; +import actionConfigs from './actions'; + +export class ShareServer extends Base { + init() { + this.store = globalShareServerStore; + } + + get policy() { + return 'manila:share_server:index'; + } + + get name() { + return t('share servers'); + } + + get actionConfigs() { + return actionConfigs; + } + + getColumns = () => [ + { + title: t('ID'), + dataIndex: 'id', + routeName: 'shareServerDetailAdmin', + isLink: true, + withoutName: true, + }, + { + title: t('Host'), + dataIndex: 'host', + isHideable: true, + }, + { + title: t('Project ID/Name'), + dataIndex: 'project_name', + isHideable: true, + }, + { + title: t('Status'), + dataIndex: 'status', + render: (value) => shareServerStatus[value] || value, + }, + { + title: t('Share Network'), + dataIndex: 'share_network_name', + isLink: true, + routeName: this.getRouteName('shareNetworkDetail'), + idKey: 'share_network_id', + }, + ]; +} + +export default inject('rootStore')(observer(ShareServer)); diff --git a/src/pages/share/routes/index.js b/src/pages/share/routes/index.js index 9e55dfc8..7969f5d5 100644 --- a/src/pages/share/routes/index.js +++ b/src/pages/share/routes/index.js @@ -27,6 +27,8 @@ import ShareGroupDetail from '../containers/ShareGroup/Detail'; import Share from '../containers/Share'; import ShareDetail from '../containers/Share/Detail'; import ShareCreate from '../containers/Share/actions/Create'; +import ShareServer from '../containers/ShareServer'; +import ShareServerDetail from '../containers/ShareServer/Detail'; const PATH = '/share'; export default [ @@ -125,6 +127,16 @@ export default [ component: ShareDetail, exact: true, }, + { + path: `${PATH}/share-server-admin`, + component: ShareServer, + exact: true, + }, + { + path: `${PATH}/share-server-admin/detail/:id`, + component: ShareServerDetail, + exact: true, + }, { path: '*', component: E404 }, ], }, diff --git a/src/resources/manila/share-server.js b/src/resources/manila/share-server.js new file mode 100644 index 00000000..1798f924 --- /dev/null +++ b/src/resources/manila/share-server.js @@ -0,0 +1,6 @@ +export const shareServerStatus = { + active: t('Active'), + error: t('Error'), + creating: t('Creating'), + deleting: t('Deleting'), +}; diff --git a/src/resources/manila/share.js b/src/resources/manila/share.js index e328eb62..9a8b4b2f 100644 --- a/src/resources/manila/share.js +++ b/src/resources/manila/share.js @@ -58,4 +58,5 @@ export const shareAccessRuleState = { queued_to_apply: t('Queued To Apply'), queued_to_deny: t('Queued To Deny'), denying: t('Denying'), + applying: t('Applying'), }; diff --git a/src/stores/manila/share-server.js b/src/stores/manila/share-server.js new file mode 100644 index 00000000..0c95dd4d --- /dev/null +++ b/src/stores/manila/share-server.js @@ -0,0 +1,32 @@ +// 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 client from 'client'; +import Base from 'stores/base'; + +export class ShareServerStore extends Base { + get client() { + return client.manila.shareServers; + } + + get paramsFunc() { + return (params) => { + const { all_projects, ...rest } = params; + return rest; + }; + } +} + +const globalShareServerStore = new ShareServerStore(); +export default globalShareServerStore; diff --git a/src/utils/table.jsx b/src/utils/table.jsx index 2d7d941f..cba3af7a 100644 --- a/src/utils/table.jsx +++ b/src/utils/table.jsx @@ -197,6 +197,7 @@ export const getNameRenderByRouter = (render, column, rowKey) => { routeParamsKey = 'id', routeQuery = {}, routeParamsFunc, + withoutName = false, } = column; return (value, record) => { const nameValue = value || get(record, dataIndex) || '-'; @@ -217,7 +218,7 @@ export const getNameRenderByRouter = (render, column, rowKey) => { return (
{link}
-
{nameValue}
+ {!withoutName &&
{nameValue}
}
); };