diff --git a/src/client/client/constants.js b/src/client/client/constants.js
index 0ff7329b..f7cfa343 100644
--- a/src/client/client/constants.js
+++ b/src/client/client/constants.js
@@ -30,6 +30,7 @@ export const endpointVersionMap = {
heat: 'v1',
octavia: 'v2',
swift: 'v1',
+ trove: 'v1.0'
};
export const endpointsDefault = {
@@ -65,6 +66,7 @@ export const placementBase = () => getOpenstackEndpoint('placement');
export const heatBase = () => getOpenstackEndpoint('heat');
export const octaviaBase = () => getOpenstackEndpoint('octavia');
export const swiftBase = () => getOpenstackEndpoint('swift');
+export const troveBase = () => getOpenstackEndpoint('trove');
export const ironicOriginEndpoint = () => getOriginEndpoint('ironic');
export const vpnEndpoint = () => getOriginEndpoint('neutron_vpn');
diff --git a/src/client/index.js b/src/client/index.js
index f4fb0a68..3944f0f2 100644
--- a/src/client/index.js
+++ b/src/client/index.js
@@ -23,6 +23,7 @@ import octavia from './octavia';
import placement from './placement';
import ironic from './ironic';
import swift from './swift';
+import trove from './trove';
const client = {
skyline,
@@ -36,6 +37,7 @@ const client = {
placement,
ironic,
swift,
+ trove
};
window.client = client;
diff --git a/src/client/trove/index.js b/src/client/trove/index.js
new file mode 100644
index 00000000..8104665b
--- /dev/null
+++ b/src/client/trove/index.js
@@ -0,0 +1,87 @@
+// 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 Base from '../client/base';
+import { troveBase } from '../client/constants';
+
+class TroveClient extends Base {
+ get baseUrl() {
+ return troveBase();
+ }
+
+ get projectInUrl() {
+ return true;
+ }
+
+ get resources() {
+ return [
+ {
+ name: 'instances',
+ key: 'instances',
+ responseKey: 'instance',
+ subResources: [
+ {
+ key: 'users',
+ responseKey: 'user',
+ },
+ {
+ key: 'databases',
+ responseKey: 'database',
+ },
+ {
+ key: 'backups',
+ responseKey: 'backup',
+ },
+ {
+ key: 'log',
+ responseKey: 'log',
+ }
+ ],
+ },
+ {
+ name: 'datastores',
+ key: 'datastores',
+ responseKey: 'datastore',
+ },
+ {
+ name: 'backups',
+ key: 'backups',
+ responseKey: 'backup',
+ },
+ {
+ name: 'configurations',
+ key: 'configurations',
+ responseKey: 'configuration',
+ extendOperations: [
+ {
+ key: 'get',
+ generate: (data) =>
+ this.request.get(
+ this.getDetailUrl('configurations', data),
+ null,
+ {
+ headers: {
+ 'content-type': 'application/json',
+ },
+ }
+ ),
+ },
+ ],
+ },
+ ];
+ }
+}
+
+const troveClient = new TroveClient();
+export default troveClient;
diff --git a/src/layouts/menu.jsx b/src/layouts/menu.jsx
index d83e0a64..88702b3d 100644
--- a/src/layouts/menu.jsx
+++ b/src/layouts/menu.jsx
@@ -19,6 +19,7 @@ import {
GlobalOutlined,
// ToolOutlined,
HomeOutlined,
+ DatabaseFilled,
AppstoreOutlined,
} from '@ant-design/icons';
@@ -435,6 +436,65 @@ const renderMenu = (t) => {
},
],
},
+ {
+ path: '/database',
+ name: t('Database'),
+ key: 'database',
+ icon: ,
+ children: [
+ {
+ path: '/database/instances',
+ name: t('Instances'),
+ key: 'databaseInstances',
+ level: 1,
+ children: [
+ {
+ path: /^\/database\/instances\/detail\/.[^/]+$/,
+ name: t('Instance Detail'),
+ key: 'databaseInstanceDetail',
+ level: 2,
+ routePath: '/database/instances/detail/:id',
+ },
+ {
+ path: '/database/instances/create',
+ name: t('Create Instance'),
+ key: 'databaseInstanceCreate',
+ level: 2,
+ },
+ ],
+ },
+ {
+ path: '/database/backups',
+ name: t('Backups'),
+ key: 'databaseBackups',
+ level: 1,
+ children: [
+ {
+ path: /^\/database\/backup\/detail\/.[^/]+$/,
+ name: t('Backup Detail'),
+ key: 'databaseBackupDetail',
+ level: 2,
+ routePath: '/database/backups/detail/:id',
+ },
+ ],
+ },
+ {
+ path: '/database/configurations',
+ name: t('Configuration Groups'),
+ key: 'configurations',
+ level: 1,
+ children: [
+ {
+ path: /^\/database\/configuration\/detail\/.[^/]+$/,
+ name: t('Configuration Detail'),
+ key: 'configurationsDetail',
+ level: 2,
+ routePath: '/database/configurations/detail/:id',
+ },
+ ],
+ },
+ ],
+ },
];
return menu;
};
diff --git a/src/pages/basic/routes/index.js b/src/pages/basic/routes/index.js
index f11b2655..205b2ba0 100644
--- a/src/pages/basic/routes/index.js
+++ b/src/pages/basic/routes/index.js
@@ -44,6 +44,9 @@ const UserCenter = lazy(() =>
const MonitorCenter = lazy(() =>
import(/* webpackChunkName: "monitor-center" */ 'pages/monitor/App')
);
+const Database = lazy(() =>
+ import(/* webpackChunkName: "monitor-center" */ 'pages/database/App')
+);
const E404 = lazy(() =>
import(/* webpackChunkName: "E404" */ 'pages/base/containers/404')
);
@@ -88,6 +91,10 @@ export default [
path: `/user`,
component: UserCenter,
},
+ {
+ path: `/database`,
+ component: Database
+ },
{ path: '*', component: E404 },
],
},
diff --git a/src/pages/database/App.jsx b/src/pages/database/App.jsx
new file mode 100644
index 00000000..014bcad1
--- /dev/null
+++ b/src/pages/database/App.jsx
@@ -0,0 +1,21 @@
+// 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 renderRoutes from 'utils/RouterConfig';
+
+import routes from './routes';
+
+const App = (props) => renderRoutes(routes, props);
+
+export default App;
diff --git a/src/pages/database/containers/Backups/Detail/BaseDetail.jsx b/src/pages/database/containers/Backups/Detail/BaseDetail.jsx
new file mode 100644
index 00000000..34c15eed
--- /dev/null
+++ b/src/pages/database/containers/Backups/Detail/BaseDetail.jsx
@@ -0,0 +1,64 @@
+// 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';
+
+@inject("rootStore")
+@observer
+export default class BaseDetail extends Base {
+
+ get leftCards() {
+ return [this.baseInfoCard]
+ }
+
+ get baseInfoCard() {
+ const options = [
+ {
+ label: t("Datastore"),
+ dataIndex: "datastore.type"
+ },
+ {
+ label: t("Datastore Version"),
+ dataIndex: "datastore.version"
+ },
+ {
+ label: t("Backup File Location"),
+ dataIndex: "locationRef",
+ },
+ {
+ label: t("Initial Volume Size"),
+ dataIndex: "size",
+ },
+ {
+ label: t("Created"),
+ dataIndex: "created",
+ },
+ {
+ label: t("Updated"),
+ dataIndex: "updated",
+ }
+ ,
+ {
+ label: t("Status"),
+ dataIndex: "status"
+ },
+ ]
+
+ return {
+ title: t("Base Info"),
+ options
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/pages/database/containers/Backups/Detail/index.jsx b/src/pages/database/containers/Backups/Detail/index.jsx
new file mode 100644
index 00000000..dc64d7fb
--- /dev/null
+++ b/src/pages/database/containers/Backups/Detail/index.jsx
@@ -0,0 +1,61 @@
+// 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/TabDetail';
+import BaseDetail from './BaseDetail';
+import { BackupsStore } from '@/stores/trove/backups';
+
+@inject('rootStore')
+@observer
+export default class BackupsDetail extends Base {
+ init() {
+ this.store = new BackupsStore();
+ }
+
+ get name() {
+ return "Backup Detail"
+ }
+
+ get listUrl() {
+ return this.getRoutePath('databaseBackups');
+ }
+
+ get policy() {
+ return 'backup:show';
+ }
+
+ get detailInfos() {
+ return [
+ {
+ title: t("Name"),
+ dataIndex: "name"
+ },
+ {
+ title: t("Description"),
+ dataIndex: "description"
+ }
+ ]
+ }
+
+ get tabs() {
+ return [
+ {
+ title: t("General Info"),
+ key: "general_info",
+ component: BaseDetail
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/src/pages/database/containers/Backups/actions/Create.jsx b/src/pages/database/containers/Backups/actions/Create.jsx
new file mode 100644
index 00000000..ec18a939
--- /dev/null
+++ b/src/pages/database/containers/Backups/actions/Create.jsx
@@ -0,0 +1,95 @@
+// 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 { ModalAction } from "@/containers/Action";
+import { inject, observer } from "mobx-react";
+import globalInstancesStore from "stores/trove/instances";
+import globalBackupsStore from "stores/trove/backups";
+
+@inject('rootStore')
+@observer
+export default class Create extends ModalAction {
+
+ init() {
+ this.store = globalBackupsStore;
+ this.getDatabaseInstance();
+ }
+
+ static id = "create-backups";
+
+ static title = t("Create Backups");
+
+ static get modalSize() {
+ return "middle";
+ }
+
+ getModalSize() {
+ return 'middle';
+ }
+
+ get name() {
+ return t("Create Backups");
+ }
+
+ static policy = "backup:create";
+
+ static allowed() {
+ return Promise.resolve(true);
+ }
+
+ get listInstanceName() {
+ return (globalInstancesStore.list.data || [])
+ .map((it) => ({
+ value: it.id,
+ label: it.name,
+ }));
+ }
+
+ async getDatabaseInstance() {
+ await globalInstancesStore.fetchListWithoutDetail();
+ }
+
+ get formItems() {
+ return [
+ {
+ name: "name",
+ label: t("Backup Name"),
+ type: "input",
+ required: true
+ },
+ {
+ name: "instance",
+ label: t("Database Instance"),
+ type: "select",
+ options: this.listInstanceName,
+ required: true
+ },
+ {
+ name: "description",
+ label: t("Description"),
+ type: "input"
+ }
+ ]
+ }
+
+ onSubmit = (values) => {
+ return this.store.create({
+ backup: {
+ description: values.description,
+ instance: values.instance,
+ name: values.name,
+ },
+ });
+ };
+}
\ No newline at end of file
diff --git a/src/pages/database/containers/Backups/actions/Delete.jsx b/src/pages/database/containers/Backups/actions/Delete.jsx
new file mode 100644
index 00000000..bb76d28b
--- /dev/null
+++ b/src/pages/database/containers/Backups/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 globalBackupsStore from 'stores/trove/backups';
+
+export default class Delete extends ConfirmAction {
+ get id() {
+ return 'delete';
+ }
+
+ get title() {
+ return t('Delete Backup');
+ }
+
+ get actionName() {
+ return t('Delete Backup');
+ }
+
+ get buttonType() {
+ return 'danger';
+ }
+
+ allowedCheckFunction = () => true;
+
+ policy = 'instance:delete';
+
+ onSubmit = (item) => {
+ return globalBackupsStore.delete({ id: item.id });
+ };
+}
diff --git a/src/pages/database/containers/Backups/actions/index.jsx b/src/pages/database/containers/Backups/actions/index.jsx
new file mode 100644
index 00000000..5d425806
--- /dev/null
+++ b/src/pages/database/containers/Backups/actions/index.jsx
@@ -0,0 +1,13 @@
+
+import Create from './Create';
+import Delete from './Delete';
+
+const actionConfigs = {
+ rowActions: {
+ firstAction: Delete,
+ },
+ batchActions: [Delete],
+ primaryActions: [Create],
+};
+
+export default { actionConfigs };
diff --git a/src/pages/database/containers/Backups/index.jsx b/src/pages/database/containers/Backups/index.jsx
new file mode 100644
index 00000000..e4ee58b8
--- /dev/null
+++ b/src/pages/database/containers/Backups/index.jsx
@@ -0,0 +1,61 @@
+// 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 Base from 'containers/List';
+
+import { inject, observer } from 'mobx-react';
+import actions from './actions';
+import globalBackupsStore from 'stores/trove/backups';
+
+@inject('rootStore')
+@observer
+export default class Backups extends Base {
+ init() {
+ this.store = globalBackupsStore;
+ }
+
+ get name() {
+ return t('backups');
+ }
+
+ get actionConfigs() {
+ return actions.actionConfigs;
+ }
+
+ get policy() {
+ return 'backup:index';
+ }
+
+ get searchFilters() {
+ return [
+ {
+ label: t('Name'),
+ name: 'name',
+ },
+ ];
+ }
+
+ getColumns = () => [
+ {
+ title: t('Backup Name'),
+ dataIndex: 'name',
+ routeName: this.getRouteName("databaseBackupDetail")
+ },
+ {
+ title: t('Description'),
+ isHideable: true,
+ dataIndex: 'description',
+ },
+ ];
+}
\ No newline at end of file
diff --git a/src/pages/database/containers/Configurations/Detail/BaseDetail.jsx b/src/pages/database/containers/Configurations/Detail/BaseDetail.jsx
new file mode 100644
index 00000000..904028ab
--- /dev/null
+++ b/src/pages/database/containers/Configurations/Detail/BaseDetail.jsx
@@ -0,0 +1,62 @@
+// 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';
+
+@inject("rootStore")
+@observer
+export default class BaseDetail extends Base {
+
+ get leftCards() {
+ return [this.baseInfoCard];
+ }
+
+ get baseInfoCard() {
+ const options = [
+ {
+ label: t("Name"),
+ dataIndex: "name"
+ },
+ {
+ label: t("Description"),
+ dataIndex: "description"
+ },
+ {
+ label: t("Datastore"),
+ dataIndex: "datastore_name"
+ }
+ ,
+ {
+ label: t("Datastore Version"),
+ dataIndex: "datastore_version_name"
+ }
+ ,
+ {
+ label: t("Created"),
+ dataIndex: "created"
+ }
+ ,
+ {
+ label: t("Updated"),
+ dataIndex: "updated"
+ }
+ ];
+
+ return {
+ title: t("Base Info"),
+ options
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/pages/database/containers/Configurations/Detail/Instances.jsx b/src/pages/database/containers/Configurations/Detail/Instances.jsx
new file mode 100644
index 00000000..249b012d
--- /dev/null
+++ b/src/pages/database/containers/Configurations/Detail/Instances.jsx
@@ -0,0 +1,39 @@
+// 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 Base from "containers/BaseDetail"
+import { inject, observer } from "mobx-react";
+
+@inject("rootStore")
+@observer
+export default class Instances extends Base {
+
+ get leftCards() {
+ return [this.baseInfoCard];
+ }
+
+ get baseInfoCard() {
+ const options = [
+ {
+ label: t("Instances"),
+ dataIndex: "instance_count"
+ }
+ ]
+
+ return {
+ title: t("Defaults"),
+ options
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/pages/database/containers/Configurations/Detail/Values.jsx b/src/pages/database/containers/Configurations/Detail/Values.jsx
new file mode 100644
index 00000000..77c4b7e8
--- /dev/null
+++ b/src/pages/database/containers/Configurations/Detail/Values.jsx
@@ -0,0 +1,39 @@
+// 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 Base from "containers/BaseDetail"
+import { inject, observer } from "mobx-react";
+
+@inject("rootStore")
+@observer
+export default class Values extends Base {
+
+ get leftCards() {
+ return [this.baseInfoCard];
+ }
+
+ get baseInfoCard() {
+ const options = [
+ {
+ label: t('Values'),
+ dataIndex: 'values',
+ },
+ ];
+
+ return {
+ title: t('Defaults'),
+ options,
+ };
+ }
+}
\ No newline at end of file
diff --git a/src/pages/database/containers/Configurations/Detail/index.jsx b/src/pages/database/containers/Configurations/Detail/index.jsx
new file mode 100644
index 00000000..dd961080
--- /dev/null
+++ b/src/pages/database/containers/Configurations/Detail/index.jsx
@@ -0,0 +1,67 @@
+// 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/TabDetail';
+import BaseDetail from './BaseDetail';
+import globalConfigurationsStore from '@/stores/trove/configurations';
+import Values from './Values';
+import Instances from './Instances';
+
+@inject('rootStore')
+@observer
+export default class ConfigurationsDetail extends Base {
+ init() {
+ this.store = globalConfigurationsStore;
+ }
+
+ get name() {
+ return "Configurations Detail"
+ }
+
+ get listUrl() {
+ return this.getRoutePath('configurations');
+ }
+
+ get policy() {
+ return 'configuration:show';
+ }
+
+ get detailInfos() {
+ return [
+ {
+ title: t("Name"),
+ dataIndex: "name"
+ }
+ ]
+ }
+
+ get tabs() {
+ return [
+ {
+ title: t("General Info"),
+ key: "general_info",
+ component: BaseDetail
+ }, {
+ title: t("Values"),
+ key: "values",
+ component: Values
+ }, {
+ title: t("Instances"),
+ key: "instances",
+ component: Instances
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/src/pages/database/containers/Configurations/actions/Create.jsx b/src/pages/database/containers/Configurations/actions/Create.jsx
new file mode 100644
index 00000000..605d477f
--- /dev/null
+++ b/src/pages/database/containers/Configurations/actions/Create.jsx
@@ -0,0 +1,131 @@
+// 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 { ModalAction } from "@/containers/Action";
+import { inject, observer } from "mobx-react";
+import globalInstancesStore from "stores/trove/instances";
+import globalConfigurationsStore from "stores/trove/configurations";
+import { toJS } from 'mobx';
+
+@inject('rootStore')
+@observer
+export default class Create extends ModalAction {
+
+ init() {
+ this.store = globalConfigurationsStore;
+ this.getDatastores();
+ this.state.datastore_type = null;
+ }
+
+ static id = "create-configurations";
+
+ static title = t("Create Configurations");
+
+ static get modalSize() {
+ return "middle";
+ }
+
+ getModalSize() {
+ return 'middle';
+ }
+
+ get name() {
+ return t("Create Configurations");
+ }
+
+ static policy = "configuration:create";
+
+ static allowed() {
+ return Promise.resolve(true);
+ }
+
+ async getDatastores() {
+ await globalInstancesStore.listDatastores();
+ }
+
+ get datastores() {
+ return (globalInstancesStore.dataList || []).map((it) => ({
+ label: it.name,
+ value: it.name,
+ originData: toJS(it),
+ }));
+ }
+
+ onChangeDatastoresTypeChange = (value) => {
+ this.setState({
+ datastore_type: value
+ })
+ this.resetFormValue(['datastore_version']);
+ };
+
+ get datastoresVersion() {
+ var dizi = (this.datastores).filter((item) => item.label === this.state.datastoreType)
+ .map((it) => {
+ return it.originData.versions.map((e) => ({
+ label: e.name,
+ value: e.name
+ }))
+ })
+ return dizi[0];
+ }
+
+ get formItems() {
+ return [
+ {
+ name: "name",
+ label: t("Name"),
+ type: "input",
+ required: true
+ },
+ {
+ name: "description",
+ label: t("Description"),
+ type: "input"
+ },
+ {
+ name: "datastore_type",
+ label: t("Datastore Type"),
+ type: "select",
+ options: this.datastores,
+ onChange: (value) => {
+ this.onChangeDatastoresTypeChange(value)
+ },
+ required: true,
+ },
+ {
+ name: "datastore_version",
+ label: t("Datastore Version"),
+ type: "select",
+ options: this.datastoresVersion,
+ required: true,
+ },
+ ]
+ }
+
+ onSubmit = (values) => {
+ return this.store.create({
+ configuration: {
+ description: values.description,
+ datastore: {
+ type: values.datastore_type,
+ version: values.datastore_version,
+ },
+ name: values.name,
+ values: {
+ connect_timeout: 200
+ }
+ }
+ })
+ };
+}
\ No newline at end of file
diff --git a/src/pages/database/containers/Configurations/actions/Delete.jsx b/src/pages/database/containers/Configurations/actions/Delete.jsx
new file mode 100644
index 00000000..f883e48d
--- /dev/null
+++ b/src/pages/database/containers/Configurations/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 globalConfigurationsStore from "stores/trove/configurations";
+
+export default class Delete extends ConfirmAction {
+ get id() {
+ return 'delete';
+ }
+
+ get title() {
+ return t('Delete Configuration');
+ }
+
+ get actionName() {
+ return t('Delete Configuration');
+ }
+
+ get buttonType() {
+ return 'danger';
+ }
+
+ allowedCheckFunction = () => true;
+
+ policy = 'instance:delete';
+
+ onSubmit = (item) => {
+ return globalConfigurationsStore.delete({ id: item.id });
+ };
+}
diff --git a/src/pages/database/containers/Configurations/actions/index.jsx b/src/pages/database/containers/Configurations/actions/index.jsx
new file mode 100644
index 00000000..4530be61
--- /dev/null
+++ b/src/pages/database/containers/Configurations/actions/index.jsx
@@ -0,0 +1,13 @@
+
+import Create from './Create';
+import Delete from './Delete';
+
+const actionConfigs = {
+ rowActions: {
+ firstAction: Delete,
+ },
+ batchActions: [Delete],
+ primaryActions: [Create]
+};
+
+export default { actionConfigs };
diff --git a/src/pages/database/containers/Configurations/index.jsx b/src/pages/database/containers/Configurations/index.jsx
new file mode 100644
index 00000000..ed352a97
--- /dev/null
+++ b/src/pages/database/containers/Configurations/index.jsx
@@ -0,0 +1,70 @@
+// 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 Base from 'containers/List';
+
+import { inject, observer } from 'mobx-react';
+import actions from './actions';
+import globalConfigurationsStore from 'stores/trove/configurations';
+
+@inject('rootStore')
+@observer
+export default class Configurations extends Base {
+
+ init() {
+ this.store = globalConfigurationsStore;
+ }
+
+ get name() {
+ return t('configurations');
+ }
+
+ get actionConfigs() {
+ return actions.actionConfigs;
+ }
+
+ get policy() {
+ return 'configuration:index';
+ }
+
+ get searchFilters() {
+ return [
+ {
+ label: t('Name'),
+ name: 'name',
+ },
+ ];
+ }
+
+ getColumns = () => [
+ {
+ title: t('Configuration Group Name'),
+ dataIndex: 'name',
+ routeName: this.getRouteName("configurationsDetail")
+ },
+ {
+ title: t('Description'),
+ isHideable: true,
+ dataIndex: 'description',
+ },
+ {
+ title: t('Datastore'),
+ dataIndex: 'datastore',
+ },
+ {
+ title: t('Datastore Version'),
+ dataIndex: 'datastoreVersion',
+ },
+ ];
+}
\ No newline at end of file
diff --git a/src/pages/database/containers/Instances/Detail/Backups.jsx b/src/pages/database/containers/Instances/Detail/Backups.jsx
new file mode 100644
index 00000000..b2499620
--- /dev/null
+++ b/src/pages/database/containers/Instances/Detail/Backups.jsx
@@ -0,0 +1,59 @@
+// 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 Base from "containers/List"
+import { inject, observer } from "mobx-react";
+import { InstanceBackupsStore } from "stores/trove/instanceBackups";
+
+@inject("rootStore")
+@observer
+export default class Backups extends Base {
+
+ init() {
+ this.store = new InstanceBackupsStore()
+ }
+
+ get name() {
+ return t("Backups")
+ }
+
+ get policy() {
+ return "instance:backups";
+ }
+
+ getColumns = () => {
+ return [
+ {
+ title: t("Name"),
+ dataIndex: "name"
+ },
+ {
+ title: t("Created"),
+ dataIndex: "created"
+ },
+ {
+ title: t("Backup File"),
+ dataIndex: "locationRef"
+ },
+ {
+ title: t("Incremental"),
+ dataIndex: "incremental"
+ },
+ {
+ title: t("Status"),
+ dataIndex: "status"
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/src/pages/database/containers/Instances/Detail/BaseDetail.jsx b/src/pages/database/containers/Instances/Detail/BaseDetail.jsx
new file mode 100644
index 00000000..43980532
--- /dev/null
+++ b/src/pages/database/containers/Instances/Detail/BaseDetail.jsx
@@ -0,0 +1,155 @@
+// 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';
+
+@inject("rootStore")
+@observer
+export default class BaseDetail extends Base {
+
+ get leftCards() {
+ return [this.baseInfoCard, this.specsCard, this.connectionInfoCard];
+ }
+
+ get rightCards() {
+ return [this.faultCard]
+ }
+
+ get baseInfoCard() {
+ const options = [
+ {
+ label: t("Name"),
+ dataIndex: "name"
+ },
+ {
+ label: t("Datastore"),
+ dataIndex: "datastore.type"
+ },
+ {
+ label: t("Datastore Version"),
+ dataIndex: "datastore.version"
+ },
+ {
+ label: t("Status"),
+ dataIndex: "status"
+ },
+ {
+ label: t("Locality"),
+ dataIndex: "locality"
+ }
+ ];
+
+ return {
+ title: t("Base Info"),
+ options
+ }
+ }
+
+ get specsCard() {
+ const options = [
+ {
+ label: t('Flavor'),
+ dataIndex: 'flavor.id',
+ render: (value) => {
+ return this.getLinkRender('flavorDetail', value, {
+ id: value,
+ }, null)
+ },
+ },
+ {
+ label: t("Volume Size"),
+ dataIndex: "volume.size"
+ },
+ {
+ label: t("Created"),
+ dataIndex: "created",
+ valueRender: "toLocalTime"
+ },
+ {
+ label: t("Updated"),
+ dataIndex: "updated",
+ valueRender: "toLocalTime"
+ },
+ {
+ label: t("Service Status Updated"),
+ dataIndex: "service_status_update"
+ }
+ ];
+
+ return {
+ title: t("Specs"),
+ options
+ }
+ }
+
+ get connectionInfoCard() {
+ const options = [
+ {
+ label: t("Host"),
+ dataIndex: "ip",
+ render: (value) => value ? value.map(it => it) : "-",
+ },
+ {
+ label: t("Database Port"),
+ dataIndex: "datastore.type",
+ render: (value) => {
+ switch (value) {
+ case 'mysql':
+ return '3306';
+ case 'mongodb':
+ return '27017';
+ case 'postgresql':
+ return '5432';
+ default:
+ break;
+ }
+ }
+ },
+ {
+ label: t("Connection Examples"),
+ dataIndex: "connection_examples"
+ }
+ ];
+
+ return {
+ title: t("Connection Information"),
+ options
+ }
+ }
+
+ get faultCard() {
+ const options = [
+ {
+ label: t("Created"),
+ dataIndex: "created",
+ valueRender: "toLocalTime"
+ },
+ {
+ label: t("Message"),
+ dataIndex: "fault.message"
+ },
+ {
+ label: t("Message Details"),
+ dataIndex: "fault.details"
+ }
+ ];
+
+ return {
+ title: t("Fault"),
+ labelCol: 2,
+ options
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/pages/database/containers/Instances/Detail/DatabaseAction.jsx b/src/pages/database/containers/Instances/Detail/DatabaseAction.jsx
new file mode 100644
index 00000000..3b832378
--- /dev/null
+++ b/src/pages/database/containers/Instances/Detail/DatabaseAction.jsx
@@ -0,0 +1,11 @@
+import DeleteDatabase from './DatabaseDelete';
+
+const actionConfigs = {
+ rowActions: {
+ firstAction: DeleteDatabase,
+ },
+ batchActions: [DeleteDatabase],
+ primaryActions: []
+};
+
+export default actionConfigs;
diff --git a/src/pages/database/containers/Instances/Detail/DatabaseDelete.jsx b/src/pages/database/containers/Instances/Detail/DatabaseDelete.jsx
new file mode 100644
index 00000000..8e082835
--- /dev/null
+++ b/src/pages/database/containers/Instances/Detail/DatabaseDelete.jsx
@@ -0,0 +1,30 @@
+import { ConfirmAction } from 'containers/Action';
+import globalInstancesDatabases from 'stores/trove/instances-database';
+
+export default class DatabaseDelete extends ConfirmAction {
+ get id() {
+ return 'delete-database-database';
+ }
+
+ get title() {
+ return t('Delete Database');
+ }
+
+ get actionName() {
+ return t('Delete Database');
+ }
+
+ get buttonType() {
+ return 'danger';
+ }
+
+ allowedCheckFunction = () => true;
+
+ policy = "instance:extension:database:delete";
+
+ onSubmit = (item) => {
+ const id = this.containerProps.detail.id;
+ const name = item.name || this.item.name;
+ return globalInstancesDatabases.deleteDatabase({ id, name });
+ };
+}
\ No newline at end of file
diff --git a/src/pages/database/containers/Instances/Detail/Databases.jsx b/src/pages/database/containers/Instances/Detail/Databases.jsx
new file mode 100644
index 00000000..59354c7c
--- /dev/null
+++ b/src/pages/database/containers/Instances/Detail/Databases.jsx
@@ -0,0 +1,51 @@
+// 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 Base from "containers/List"
+import { inject, observer } from "mobx-react";
+import { InstancesDatabasesStore } from "stores/trove/instances-database";
+import actions from "./DatabaseAction";
+
+@inject("rootStore")
+@observer
+export default class Databases extends Base {
+
+ init() {
+ this.store = new InstancesDatabasesStore()
+ }
+ get name() {
+ return "Databases"
+ }
+
+ get policy() {
+ return "instance:detail"
+ }
+
+ get actionConfigs() {
+ return actions;
+ }
+
+ get hideCustom() {
+ return true;
+ }
+
+ getColumns = () => {
+ return [
+ {
+ title: t("Database Name"),
+ dataIndex: "name"
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/src/pages/database/containers/Instances/Detail/Defaults.jsx b/src/pages/database/containers/Instances/Detail/Defaults.jsx
new file mode 100644
index 00000000..d35d623a
--- /dev/null
+++ b/src/pages/database/containers/Instances/Detail/Defaults.jsx
@@ -0,0 +1,39 @@
+// 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 Base from "containers/BaseDetail"
+import { inject, observer } from "mobx-react";
+
+@inject("rootStore")
+@observer
+export default class Defaults extends Base {
+
+ get leftCards() {
+ return [this.baseInfoCard]
+ }
+
+ get baseInfoCard() {
+ const options = [
+ {
+ label: t("Number of Nodes"),
+ dataIndex: "node_groups[0].count"
+ }
+ ];
+
+ return {
+ title: t("Defaults"),
+ options
+ };
+ }
+}
\ No newline at end of file
diff --git a/src/pages/database/containers/Instances/Detail/Logs.jsx b/src/pages/database/containers/Instances/Detail/Logs.jsx
new file mode 100644
index 00000000..6a1664bf
--- /dev/null
+++ b/src/pages/database/containers/Instances/Detail/Logs.jsx
@@ -0,0 +1,43 @@
+// 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 Base from "containers/List"
+import { inject, observer } from "mobx-react";
+import { InstancesLogStore } from "stores/trove/instancesLogs";
+
+@inject("rootStore")
+@observer
+export default class Logs extends Base {
+
+ init() {
+ this.store = new InstancesLogStore()
+ }
+
+ get name() {
+ return t("Log")
+ }
+
+ get policy() {
+ return "instance:guest_log_list";
+ }
+
+ getColumns = () => {
+ return [
+ {
+ title: t("Name"),
+ dataIndex: "name"
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/src/pages/database/containers/Instances/Detail/UserAction.jsx b/src/pages/database/containers/Instances/Detail/UserAction.jsx
new file mode 100644
index 00000000..d2262787
--- /dev/null
+++ b/src/pages/database/containers/Instances/Detail/UserAction.jsx
@@ -0,0 +1,11 @@
+import DeleteUser from './UserDelete';
+
+const actionConfigs = {
+ rowActions: {
+ firstAction: DeleteUser,
+ },
+ batchActions: [DeleteUser],
+ primaryActions: []
+};
+
+export default actionConfigs;
diff --git a/src/pages/database/containers/Instances/Detail/UserDelete.jsx b/src/pages/database/containers/Instances/Detail/UserDelete.jsx
new file mode 100644
index 00000000..b16ee45b
--- /dev/null
+++ b/src/pages/database/containers/Instances/Detail/UserDelete.jsx
@@ -0,0 +1,30 @@
+import { ConfirmAction } from 'containers/Action';
+import globalInstancesUsersStore from 'stores/trove/instances-user';
+
+export default class UserDelete extends ConfirmAction {
+ get id() {
+ return 'delete-database-user';
+ }
+
+ get title() {
+ return t('Delete User');
+ }
+
+ get actionName() {
+ return t('Delete User');
+ }
+
+ get buttonType() {
+ return 'danger';
+ }
+
+ allowedCheckFunction = () => true;
+
+ policy = 'instance:extension:user:delete';
+
+ onSubmit = (item) => {
+ const id = this.containerProps.detail.id;
+ const name = item.name || this.item.name;
+ return globalInstancesUsersStore.deleteUser({id, name});
+ };
+}
\ No newline at end of file
diff --git a/src/pages/database/containers/Instances/Detail/Users.jsx b/src/pages/database/containers/Instances/Detail/Users.jsx
new file mode 100644
index 00000000..5f240529
--- /dev/null
+++ b/src/pages/database/containers/Instances/Detail/Users.jsx
@@ -0,0 +1,59 @@
+// 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 Base from 'containers/List';
+import { inject, observer } from 'mobx-react';
+import { InstancesUsersStore } from 'stores/trove/instances-user';
+import actions from './UserAction';
+
+@inject('rootStore')
+@observer
+export default class Users extends Base {
+ init() {
+ this.store = new InstancesUsersStore();
+ }
+
+ get name() {
+ return t('Users');
+ }
+
+ get actionConfigs() {
+ return actions;
+ }
+
+ get policy() {
+ return 'instance:extension:user:index';
+ }
+
+ get hideCustom() {
+ return true;
+ }
+
+ getColumns = () => {
+ return [
+ {
+ title: t('User Name'),
+ dataIndex: 'name',
+ },
+ {
+ title: t('Allowed Host'),
+ dataIndex: 'host',
+ },
+ {
+ title: t('Databases'),
+ dataIndex: 'databases.name',
+ },
+ ];
+ };
+}
diff --git a/src/pages/database/containers/Instances/Detail/index.jsx b/src/pages/database/containers/Instances/Detail/index.jsx
new file mode 100644
index 00000000..0d791add
--- /dev/null
+++ b/src/pages/database/containers/Instances/Detail/index.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/TabDetail';
+import BaseDetail from './BaseDetail';
+import globalInstancesStore from '@/stores/trove/instances';
+import Users from './Users';
+import Databases from './Databases';
+import Backups from './Backups';
+import Logs from './Logs';
+import Defaults from './Defaults';
+
+@inject('rootStore')
+@observer
+export default class InstancesDetail extends Base {
+ init() {
+ this.store = globalInstancesStore;
+ }
+
+ get name() {
+ return t("Backup Detail");
+ }
+
+ get policy() {
+ return 'instance:detail';
+ }
+
+ get listUrl() {
+ return this.getRoutePath('databaseInstances');
+ }
+
+ get detailInfos() {
+ return [
+ {
+ title: t("ID"),
+ dataIndex: "id"
+ },
+ {
+ title: t("Name"),
+ dataIndex: "name"
+ },
+ {
+ title: t("Status"),
+ dataIndex: "status"
+ },
+ {
+ title: t("Tenant Id"),
+ dataIndex: "tenant_id"
+ }
+ ]
+ }
+
+ get tabs() {
+ return [
+ {
+ title: t("General Info"),
+ key: "general_info",
+ component: BaseDetail
+ },
+ {
+ title: t("Users"),
+ key: "users",
+ component: Users
+ },
+ {
+ title: t("Databases"),
+ key: "databases",
+ component: Databases
+ },
+ {
+ title: t("Backups"),
+ key: "backups",
+ component: Backups
+ },
+ {
+ title: t("Logs"),
+ key: "logs",
+ component: Logs
+ },
+ {
+ title: t("Defaults"),
+ key: "defaults",
+ component: Defaults
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/src/pages/database/containers/Instances/actions/Delete.jsx b/src/pages/database/containers/Instances/actions/Delete.jsx
new file mode 100644
index 00000000..21434225
--- /dev/null
+++ b/src/pages/database/containers/Instances/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 globalInstancesStore from 'stores/trove/instances';
+
+export default class Delete extends ConfirmAction {
+ get id() {
+ return 'delete';
+ }
+
+ get title() {
+ return t('Delete');
+ }
+
+ get actionName() {
+ return t('Delete');
+ }
+
+ get buttonType() {
+ return 'danger';
+ }
+
+ allowedCheckFunction = () => true;
+
+ policy = 'instance:delete';
+
+ onSubmit = (item) => {
+ return globalInstancesStore.delete({ id: item.id });
+ };
+}
\ No newline at end of file
diff --git a/src/pages/database/containers/Instances/actions/StepCreate/StepAdvanced/index.jsx b/src/pages/database/containers/Instances/actions/StepCreate/StepAdvanced/index.jsx
new file mode 100644
index 00000000..9903e132
--- /dev/null
+++ b/src/pages/database/containers/Instances/actions/StepCreate/StepAdvanced/index.jsx
@@ -0,0 +1,51 @@
+import { inject, observer } from 'mobx-react';
+import Base from 'components/Form';
+import globalInstancesStore from '@/stores/trove/instances';
+
+@inject('rootStore')
+@observer
+export default class StepAdvanced extends Base {
+
+ init() {
+ this.getConfigurationGroups();
+ }
+ get title() {
+ return t('Initialize Databases');
+ }
+
+ get name() {
+ return 'Initialize Databases';
+ }
+
+ allowed = () => Promise.resolve();
+
+ get configurationGroup() {
+ return (globalInstancesStore.list.data || []).map((it) => ({
+ label: it.name,
+ value: it.id
+ }));
+ }
+
+ async getConfigurationGroups() {
+ globalInstancesStore.listConfigurationGroup();
+ }
+
+ get formItems() {
+ return [
+ {
+ name: "project",
+ label: t("Project"),
+ type: "label"
+ },
+ {
+ type: "divider"
+ },
+ {
+ name: "configurationGroup",
+ label: t("Configuration Group"),
+ type: 'select',
+ options: this.configurationGroup
+ }
+ ]
+ }
+}
diff --git a/src/pages/database/containers/Instances/actions/StepCreate/StepDetails/index.jsx b/src/pages/database/containers/Instances/actions/StepCreate/StepDetails/index.jsx
new file mode 100644
index 00000000..82903964
--- /dev/null
+++ b/src/pages/database/containers/Instances/actions/StepCreate/StepDetails/index.jsx
@@ -0,0 +1,227 @@
+// 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 'components/Form';
+import { toJS } from 'mobx';
+import globalInstancesStore from '@/stores/trove/instances';
+import globalAvailabilityZoneStore from 'stores/nova/zone';
+import FlavorSelectTable from '@/pages/compute/containers/Instance/components/FlavorSelectTable';
+
+@inject('rootStore')
+@observer
+export default class StepDetails extends Base {
+ init() {
+ this.instancesStore = globalInstancesStore;
+ this.getDatastores();
+ this.getAvailZones();
+ }
+
+ get title() {
+ return t('Details *');
+ }
+
+ get name() {
+ return 'Details';
+ }
+
+ allowed = () => Promise.resolve();
+
+ get nameForStateUpdate() {
+ return ['flavor', 'datastore_type'];
+ }
+
+ get defaultValue() {
+ const values = {
+ project: this.currentProjectName
+ };
+ return values;
+ }
+
+ get availableZones() {
+ return (globalAvailabilityZoneStore.list.data || [])
+ .filter((it) => it.zoneState.available)
+ .map((it) => ({
+ value: it.zoneName,
+ label: it.zoneName,
+ }));
+ }
+
+ async getAvailZones() {
+ globalAvailabilityZoneStore.fetchListWithoutDetail();
+ }
+
+ get datastores() {
+ return (globalInstancesStore.dataList || []).map((it) => ({
+ label: it.name,
+ value: it.name,
+ originData: toJS(it),
+ }));
+ }
+
+ async getDatastores() {
+ globalInstancesStore.listDatastores();
+ }
+
+ onChangeDatastoresTypeChange = (value) => {
+ this.setState({
+ datastoreType: value
+ });
+ this.resetFormValue(["datastore_version"]);
+ }
+
+ get datastoresVersion() {
+ var dizi = (this.datastores).filter((item) => item.label === this.state.datastore_type)
+ .map((it) => {
+ return it.originData.versions.map((e) => ({
+ label: e.name,
+ value: e.name
+ }))
+ })
+ return dizi[0];
+ }
+
+ getFlavorComponent() {
+ return ;
+ }
+
+ onFlavorChange = (value) => {
+ this.updateContext({
+ flavor: value,
+ });
+ };
+
+ checkSystemDisk = (rule, value) => {
+ if (!value.type) {
+ // eslint-disable-next-line prefer-promise-reject-errors
+ return Promise.reject('');
+ }
+ return Promise.resolve();
+ };
+
+ getSystemDiskMinSize() {
+ const flavorSize = (this.state.flavor || {}).disk || 0;
+ let imageSize = 0;
+ return Math.max(flavorSize, imageSize, 1);
+ }
+
+ onSystemDiskChange = (value) => {
+ this.updateContext({
+ volume_type: value,
+ });
+ };
+
+ get formItems() {
+ return [
+ {
+ name: 'project',
+ label: t('Project'),
+ type: 'label',
+ },
+ {
+ type: 'divider',
+ },
+ {
+ name: 'zone',
+ label: t('Availability Zone'),
+ type: 'select',
+ placeholder: t('Please select'),
+ options: this.availableZones,
+ required: true,
+ },
+ {
+ name: 'instance_name',
+ label: t('Instance Name'),
+ type: 'input',
+ required: true,
+ },
+ {
+ name: 'size',
+ label: t('Size (GB)'),
+ type: 'input-number',
+ min: 1,
+ max: 50,
+ placeholder: t('Size'),
+ required: true,
+ wrapperCol: {
+ xs: {
+ span: 24,
+ },
+ sm: {
+ span: 18,
+ },
+ },
+ },
+ {
+ type: 'divider',
+ },
+ {
+ name: 'datastore_type',
+ label: t('Datastore Type'),
+ type: 'select',
+ options: this.datastores,
+ onChange: (value) => {
+ this.onChangeDatastoresTypeChange(value);
+ },
+ required: true,
+ tip: t('Type of datastore'),
+ },
+ {
+ name: 'datastore_version',
+ label: t('Datastore Version'),
+ type: 'select',
+ options: this.datastoresVersion,
+ required: true,
+ tip: t('Version of datastore'),
+ },
+ {
+ type: 'divider',
+ },
+ {
+ name: 'flavor',
+ label: t('Flavor'),
+ component: this.getFlavorComponent(),
+ wrapperCol: {
+ xs: {
+ span: 24,
+ },
+ sm: {
+ span: 18,
+ },
+ },
+ tip: t('Size of image to launch'),
+ required: true,
+ },
+ {
+ name: 'locality',
+ label: t('Locality'),
+ type: 'select',
+ options: [
+ {
+ label: 'Affinity',
+ value: 'affinity',
+ },
+ {
+ label: 'Anti-affinity',
+ value: 'anti-affinity',
+ },
+ ],
+ tip: t(
+ 'Specify whether future replicated instances will be created on the same hypervisor (affinity) or on different hypervisors (anti-affinity). This value is ignored if the instance to be launched is a replica.'
+ ),
+ },
+ ];
+ }
+}
diff --git a/src/pages/database/containers/Instances/actions/StepCreate/StepInitializeDatabases/index.jsx b/src/pages/database/containers/Instances/actions/StepCreate/StepInitializeDatabases/index.jsx
new file mode 100644
index 00000000..2456ace2
--- /dev/null
+++ b/src/pages/database/containers/Instances/actions/StepCreate/StepInitializeDatabases/index.jsx
@@ -0,0 +1,56 @@
+
+import { inject, observer } from 'mobx-react';
+import Base from 'components/Form';
+
+@inject('rootStore')
+@observer
+export default class StepInitializeDatabases extends Base {
+
+ get title() {
+ return t('Initialize Databases');
+ }
+
+ get name() {
+ return 'Initialize Databases';
+ }
+
+ allowed = () => Promise.resolve();
+
+ get defaultValue() {
+ const values = {
+ project: this.currentProjectName
+ };
+ return values;
+ }
+
+ get formItems() {
+ return [
+ {
+ name: 'project',
+ label: t('Project'),
+ type: 'label',
+ },
+ {
+ type: 'divider',
+ },
+ {
+ name: 'initialDatabases',
+ label: t('Initial Databases'),
+ type: 'input',
+ required: true,
+ },
+ {
+ name: 'initialAdminUser',
+ label: t('Initial Admin User'),
+ type: 'input',
+ required: true,
+ },
+ {
+ name: 'password',
+ label: t('Password'),
+ type: 'input-password',
+ required: true,
+ },
+ ];
+ }
+}
diff --git a/src/pages/database/containers/Instances/actions/StepCreate/StepNetworking/index.jsx b/src/pages/database/containers/Instances/actions/StepCreate/StepNetworking/index.jsx
new file mode 100644
index 00000000..b7965696
--- /dev/null
+++ b/src/pages/database/containers/Instances/actions/StepCreate/StepNetworking/index.jsx
@@ -0,0 +1,62 @@
+import { inject, observer } from 'mobx-react';
+import Base from 'components/Form';
+import globalNetworkStore from 'stores/neutron/network';
+
+@inject('rootStore')
+@observer
+export default class StepNetworking extends Base {
+
+ init() {
+ this.getNetworkStore();
+ this.selectedNetwork = [];
+ }
+ get title() {
+ return t('Networking *');
+ }
+
+ get name() {
+ return 'Networking';
+ }
+ get networking() {
+ return (globalNetworkStore.list.data || []).map((it) => ({
+ label: it.name,
+ value: it.id
+ }));
+ }
+
+ allowed = () => Promise.resolve();
+
+ async getNetworkStore() {
+ await globalNetworkStore.fetchList();
+ }
+
+ onChangeNetworkGroup = (checkedValues) => {
+ this.selectedNetwork = checkedValues;
+ }
+
+ get defaultValue() {
+ const values = {
+ project: this.currentProjectName
+ };
+ return values;
+ }
+
+ get formItems() {
+ return [
+ {
+ name: 'project',
+ label: t('Project'),
+ type: 'label',
+ },
+ {
+ type: 'divider',
+ },
+ {
+ name: 'network',
+ label: t('Options'),
+ type: 'network-select-table',
+ options: this.networking,
+ },
+ ];
+ }
+}
diff --git a/src/pages/database/containers/Instances/actions/StepCreate/index.jsx b/src/pages/database/containers/Instances/actions/StepCreate/index.jsx
new file mode 100644
index 00000000..a84eb985
--- /dev/null
+++ b/src/pages/database/containers/Instances/actions/StepCreate/index.jsx
@@ -0,0 +1,117 @@
+// 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
+//
+// Unles //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 { StepAction } from 'containers/Action';
+import { inject, observer } from 'mobx-react';
+import globalInstancesStore from '@/stores/trove/instances';
+import StepDetails from './StepDetails';
+import StepNetworking from './StepNetworking';
+import StepInitializeDatabases from './StepInitializeDatabases';
+import StepAdvanced from './StepAdvanced';
+
+@inject('rootStore')
+@observer
+export default class StepCreate extends StepAction {
+
+ init() {
+ this.store = globalInstancesStore;
+ }
+
+ static id = "create-instance";
+
+ static title = t("Create Instance")
+
+ static path = '/database/instances/create';
+
+ static policy = "instance:create";
+
+ static allowed() {
+ return Promise.resolve(true);
+ }
+
+ get name() {
+ return t("Create Instance");
+ }
+
+ get listUrl() {
+ return this.getRoutePath('databaseInstances');
+ }
+
+ get hasConfirmStep() {
+ return false;
+ }
+
+ get steps() {
+ return [
+ {
+ title: t('Details *'),
+ component: StepDetails,
+ },
+ {
+ title: t('Networking *'),
+ component: StepNetworking,
+ },
+ {
+ title: t('Initialize Databases'),
+ component: StepInitializeDatabases,
+ },
+ {
+ title: t('Advanced'),
+ component: StepAdvanced,
+ },
+ ];
+ }
+
+ onSubmit = (values) => {
+ let network = []
+
+ const { selectedRowKeys = [] } = values.network;
+ network = selectedRowKeys.map(it => ({ 'net-id': it }))
+ network = [{ 'net-id': selectedRowKeys[0] }]
+
+ return this.store.create({
+ instance: {
+ datastore: {
+ type: values.datastore_type,
+ version: values.datastore_version,
+ },
+ name: values.instance_name,
+ flavorRef: values.flavor.selectedRowKeys[0],
+ volume: { size: values.size },
+ availability_zone: values.zone,
+ nics: network,
+ locality: values.locality,
+ configuration: values.configurationGroup,
+ databases: [
+ {
+ character_set: 'utf8',
+ collate: 'utf8_general_ci',
+ name: values.initialDatabases,
+ },
+ ],
+ users: [
+ {
+ databases: [
+ {
+ name: values.initialDatabases,
+ },
+ ],
+ name: values.initialAdminUser,
+ password: values.password,
+ },
+ ],
+ },
+ });
+ };
+}
\ No newline at end of file
diff --git a/src/pages/database/containers/Instances/actions/index.jsx b/src/pages/database/containers/Instances/actions/index.jsx
new file mode 100644
index 00000000..8c050ac0
--- /dev/null
+++ b/src/pages/database/containers/Instances/actions/index.jsx
@@ -0,0 +1,25 @@
+// 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';
+import StepCreate from './StepCreate';
+
+const actionConfigs = {
+ rowActions: {
+ firstAction: Delete,
+ },
+ primaryActions: [StepCreate]
+};
+
+export default actionConfigs;
diff --git a/src/pages/database/containers/Instances/index.jsx b/src/pages/database/containers/Instances/index.jsx
new file mode 100644
index 00000000..1303a856
--- /dev/null
+++ b/src/pages/database/containers/Instances/index.jsx
@@ -0,0 +1,79 @@
+// 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 actions from './actions';
+import globalInstancesStore from '@/stores/trove/instances';
+
+@inject('rootStore')
+@observer
+export default class Instances extends Base {
+ init() {
+ this.store = globalInstancesStore;
+ }
+
+ get name() {
+ return t('Instances');
+ }
+
+ get actionConfigs() {
+ return actions;
+ }
+
+ get policy() {
+ return 'instance:index';
+ }
+
+ get searchFilters() {
+ return [
+ {
+ label: t('Name'),
+ name: 'name',
+ },
+ ];
+ }
+
+ getColumns = () => [
+ {
+ title: t('Instance Name'),
+ dataIndex: 'name',
+ routeName: this.getRouteName('databaseInstanceDetail'),
+ },
+ {
+ title: t("Datastore"),
+ dataIndex: "datastore.type"
+ },
+ {
+ title: t("Datastore Version"),
+ dataIndex: "datastore.version",
+ isHideable: true,
+ },
+ {
+ title: t("Host"),
+ dataIndex: "ip",
+ isHideable: true,
+ },
+ {
+ title: t('Volume Size'),
+ dataIndex: 'volume',
+ isHideable: true,
+ render: (value) => value ? value.size + "GB" : "-"
+ },
+ {
+ title: t('Status'),
+ dataIndex: 'status',
+ },
+ ];
+}
\ No newline at end of file
diff --git a/src/pages/database/routes/index.jsx b/src/pages/database/routes/index.jsx
new file mode 100644
index 00000000..4b89f3db
--- /dev/null
+++ b/src/pages/database/routes/index.jsx
@@ -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 BaseLayout from 'layouts/Basic';
+import E404 from 'pages/base/containers/404';
+import Instances from '../containers/Instances';
+import StepCreate from '../containers/Instances/actions/StepCreate';
+import Backups from '../containers/Backups';
+import Configurations from '../containers/Configurations';
+import InstancesDetail from '../containers/Instances/Detail';
+import ConfigurationsDetail from '../containers/Configurations/Detail';
+import BackupsDetail from '../containers/Backups/Detail';
+
+const PATH = '/database';
+export default [
+ {
+ path: PATH,
+ component: BaseLayout,
+ routes: [
+ { path: `${PATH}/instances`, component: Instances, exact: true },
+ { path: `${PATH}/instances/create`, component: StepCreate, exact: true },
+ { path: `${PATH}/backups`, component: Backups, exact: true },
+ { path: `${PATH}/configurations`, component: Configurations, exact: true },
+ { path: `${PATH}/instances/detail/:id`, component: InstancesDetail, exact: true },
+ { path: `${PATH}/backups/detail/:id`, component: BackupsDetail, exact: true },
+ { path: `${PATH}/configurations/detail/:id`, component: ConfigurationsDetail, exact: true },
+ { path: '*', component: E404 },
+ ]
+ }
+]
\ No newline at end of file
diff --git a/src/stores/trove/backups.js b/src/stores/trove/backups.js
new file mode 100644
index 00000000..7497a705
--- /dev/null
+++ b/src/stores/trove/backups.js
@@ -0,0 +1,22 @@
+import Base from 'stores/base';
+import client from 'client';
+import { action } from 'mobx';
+
+export class BackupsStore extends Base {
+ get client() {
+ return client.trove.backups;
+ }
+
+ @action
+ async create(newbody) {
+ return this.client.create(newbody);
+ }
+
+ @action
+ async delete({ params }, newbody) {
+ return this.client.delete(params, newbody);
+ }
+}
+
+const globalBackupsStore = new BackupsStore();
+export default globalBackupsStore;
diff --git a/src/stores/trove/configurations.js b/src/stores/trove/configurations.js
new file mode 100644
index 00000000..53d87881
--- /dev/null
+++ b/src/stores/trove/configurations.js
@@ -0,0 +1,22 @@
+import Base from 'stores/base';
+import client from 'client';
+import { action } from 'mobx';
+
+export class ConfigurationsStore extends Base {
+ get client() {
+ return client.trove.configurations;
+ }
+
+ @action
+ async create(newbody) {
+ return this.client.create(newbody);
+ }
+
+ @action
+ async delete({ params }, newbody) {
+ return this.client.delete(params, newbody);
+ }
+}
+
+const globalConfigurationsStore = new ConfigurationsStore();
+export default globalConfigurationsStore;
\ No newline at end of file
diff --git a/src/stores/trove/instanceBackups.js b/src/stores/trove/instanceBackups.js
new file mode 100644
index 00000000..46eb86de
--- /dev/null
+++ b/src/stores/trove/instanceBackups.js
@@ -0,0 +1,37 @@
+// 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 Base from 'stores/base';
+import client from 'client';
+
+export class InstanceBackupsStore extends Base {
+ get client() {
+ return client.trove.instances.backups;
+ }
+
+ get responseKey() {
+ return 'backup';
+ }
+
+ get isSubResource() {
+ return true;
+ }
+
+ get paramsFunc() {
+ return () => { };
+ }
+}
+
+const globalInstanceBackups = new InstanceBackupsStore();
+export default globalInstanceBackups;
\ No newline at end of file
diff --git a/src/stores/trove/instances-database.js b/src/stores/trove/instances-database.js
new file mode 100644
index 00000000..bd8d6d8f
--- /dev/null
+++ b/src/stores/trove/instances-database.js
@@ -0,0 +1,46 @@
+// 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 Base from 'stores/base';
+import client from 'client';
+import { action } from 'mobx';
+
+export class InstancesDatabasesStore extends Base {
+ get client() {
+ return client.trove.instances.databases;
+ }
+
+ get isSubResource() {
+ return true;
+ }
+
+ get responseKey() {
+ return 'database';
+ }
+
+ get paramsFunc() {
+ return (params) => {
+ const { id, ...rest } = params;
+ return rest;
+ };
+ }
+
+ @action
+ async deleteDatabase({ id, name }) {
+ return this.submitting(this.client.delete(id, name));
+ }
+}
+
+const globalInstancesDatabases = new InstancesDatabasesStore();
+export default globalInstancesDatabases;
diff --git a/src/stores/trove/instances-user.js b/src/stores/trove/instances-user.js
new file mode 100644
index 00000000..820418f5
--- /dev/null
+++ b/src/stores/trove/instances-user.js
@@ -0,0 +1,46 @@
+// 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 Base from 'stores/base';
+import client from 'client';
+import { action } from 'mobx';
+
+export class InstancesUsersStore extends Base {
+ get client() {
+ return client.trove.instances.users;
+ }
+
+ get isSubResource() {
+ return true;
+ }
+
+ get responseKey() {
+ return 'user';
+ }
+
+ get paramsFunc() {
+ return (params) => {
+ const { id, ...rest } = params;
+ return rest;
+ };
+ }
+
+ @action
+ async deleteUser({ id, name }) {
+ return this.submitting(this.client.delete(id, name));
+ }
+}
+
+const globalInstancesUsersStore = new InstancesUsersStore();
+export default globalInstancesUsersStore;
\ No newline at end of file
diff --git a/src/stores/trove/instances.js b/src/stores/trove/instances.js
new file mode 100644
index 00000000..f0ac0490
--- /dev/null
+++ b/src/stores/trove/instances.js
@@ -0,0 +1,68 @@
+// 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 Base from 'stores/base';
+import client from 'client';
+import { action, observable } from 'mobx';
+
+export class InstancesStore extends Base {
+ @observable
+ dataList = [];
+
+ get client() {
+ return client.trove.instances;
+ }
+
+ get clientDatastore() {
+ return client.trove.datastores;
+ }
+
+ get clientConfigurationGroup() {
+ return client.trove.configurations;
+ }
+
+ @action
+ async create(newbody) {
+ return this.submitting(this.client.create(newbody));
+ }
+
+ @action
+ async delete({ params }, newbody) {
+ return this.client.delete(params, newbody);
+ }
+
+ @action
+ async listDatastores() {
+ const result = await this.clientDatastore.list();
+ const data = result.datastores;
+ this.dataList = data.map(this.mapper);
+ }
+
+ @action
+ async fetchListWithoutDetail() {
+ const result = await this.client.list();
+ const data = result[this.listResponseKey];
+ this.list.data = data.map(this.mapper);
+ }
+
+ @action
+ async listConfigurationGroup() {
+ const result = await this.clientConfigurationGroup.list();
+ const data = result.configurations;
+ this.list.data = data.map(this.mapper);
+ }
+}
+
+const globalInstancesStore = new InstancesStore();
+export default globalInstancesStore;
\ No newline at end of file
diff --git a/src/stores/trove/instancesLogs.js b/src/stores/trove/instancesLogs.js
new file mode 100644
index 00000000..ce0db35f
--- /dev/null
+++ b/src/stores/trove/instancesLogs.js
@@ -0,0 +1,37 @@
+// 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 Base from 'stores/base';
+import client from 'client';
+
+export class InstancesLogStore extends Base {
+ get client() {
+ return client.trove.instances.log;
+ }
+
+ get responseKey() {
+ return 'logs';
+ }
+
+ get isSubResource() {
+ return true;
+ }
+
+ get paramsFunc() {
+ return () => { };
+ }
+}
+
+const globalInstancesLog = new InstancesLogStore();
+export default globalInstancesLog;
\ No newline at end of file