feat: Support client module
1. Add client module to request openstack api 2. Remove window.request, stores use client to request api 3. Remove window.globals, use globalRootStore to deal with user info Change-Id: I5657cfd8cf142dbacce8716991f805bbbb4a9222
This commit is contained in:
parent
0061ce4f15
commit
c960f06c1a
@ -127,6 +127,7 @@ module.exports = {
|
|||||||
locales: root('src/locales'),
|
locales: root('src/locales'),
|
||||||
styles: root('src/styles'),
|
styles: root('src/styles'),
|
||||||
resources: root('src/resources'),
|
resources: root('src/resources'),
|
||||||
|
client: root('src/client'),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
|
@ -81,7 +81,8 @@
|
|||||||
"react-highcharts": "^16.0.2",
|
"react-highcharts": "^16.0.2",
|
||||||
"react-router": "^4.3.1",
|
"react-router": "^4.3.1",
|
||||||
"react-router-dom": "^4.3.1",
|
"react-router-dom": "^4.3.1",
|
||||||
"react-sortable-hoc": "1.11.0"
|
"react-sortable-hoc": "1.11.0",
|
||||||
|
"uuid": "^8.3.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.14.3",
|
"@babel/core": "^7.14.3",
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
* @param {String} key api url
|
* @param {String} key api url
|
||||||
* @returns {String}
|
* @returns {String}
|
||||||
*/
|
*/
|
||||||
import { cinderBase } from 'utils/constants';
|
import { cinderBase } from 'client/client/constants';
|
||||||
|
|
||||||
const getCinderBaseUrl = (key) => `${cinderBase()}/${key}`;
|
const getCinderBaseUrl = (key) => `${cinderBase()}/${key}`;
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
* @param {String} key api url
|
* @param {String} key api url
|
||||||
* @returns {String}
|
* @returns {String}
|
||||||
*/
|
*/
|
||||||
import { glanceBase } from 'utils/constants';
|
import { glanceBase } from 'client/client/constants';
|
||||||
|
|
||||||
const getGlanceBaseUrl = (key) => `${glanceBase()}/${key}`;
|
const getGlanceBaseUrl = (key) => `${glanceBase()}/${key}`;
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
* @param {String} key api url
|
* @param {String} key api url
|
||||||
* @returns {String}
|
* @returns {String}
|
||||||
*/
|
*/
|
||||||
import { gocronBase } from 'utils/constants';
|
import { gocronBase } from 'client/client/constants';
|
||||||
|
|
||||||
const getGocronBaseUrl = (key) => `${gocronBase()}/${key}`;
|
const getGocronBaseUrl = (key) => `${gocronBase()}/${key}`;
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
* @param {String} key api url
|
* @param {String} key api url
|
||||||
* @returns {String}
|
* @returns {String}
|
||||||
*/
|
*/
|
||||||
import { heatBase } from 'utils/constants';
|
import { heatBase } from 'client/client/constants';
|
||||||
|
|
||||||
const getHeatBaseUrl = (key) => `${heatBase()}/${key}`;
|
const getHeatBaseUrl = (key) => `${heatBase()}/${key}`;
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
* @param {String} key api url
|
* @param {String} key api url
|
||||||
* @returns {String}
|
* @returns {String}
|
||||||
*/
|
*/
|
||||||
import { ironicInspectorBase } from 'utils/constants';
|
import { ironicInspectorBase } from 'client/client/constants';
|
||||||
|
|
||||||
const getIronicInspectorBaseUrl = (key) => `${ironicInspectorBase()}/${key}`;
|
const getIronicInspectorBaseUrl = (key) => `${ironicInspectorBase()}/${key}`;
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
* @param {String} key api url
|
* @param {String} key api url
|
||||||
* @returns {String}
|
* @returns {String}
|
||||||
*/
|
*/
|
||||||
import { ironicBase } from 'utils/constants';
|
import { ironicBase } from 'client/client/constants';
|
||||||
|
|
||||||
const getIronicBaseUrl = (key) => `${ironicBase()}/${key}`;
|
const getIronicBaseUrl = (key) => `${ironicBase()}/${key}`;
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
* @param {String} key api url
|
* @param {String} key api url
|
||||||
* @returns {String}
|
* @returns {String}
|
||||||
*/
|
*/
|
||||||
import { keystoneBase } from 'utils/constants';
|
import { keystoneBase } from 'client/client/constants';
|
||||||
|
|
||||||
const getKeystoneBaseUrl = (key) => `${keystoneBase()}/${key}`;
|
const getKeystoneBaseUrl = (key) => `${keystoneBase()}/${key}`;
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
* @param {String} key api url
|
* @param {String} key api url
|
||||||
* @returns {String}
|
* @returns {String}
|
||||||
*/
|
*/
|
||||||
import { neutronBase } from 'utils/constants';
|
import { neutronBase } from 'client/client/constants';
|
||||||
|
|
||||||
const getNeutronBaseUrl = (key) => `${neutronBase()}/${key}`;
|
const getNeutronBaseUrl = (key) => `${neutronBase()}/${key}`;
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
* @param {String} key api url
|
* @param {String} key api url
|
||||||
* @returns {String}
|
* @returns {String}
|
||||||
*/
|
*/
|
||||||
import { novaBase } from 'utils/constants';
|
import { novaBase } from 'client/client/constants';
|
||||||
|
|
||||||
const getNovaBaseUrl = (key) => `${novaBase()}/${key}`;
|
const getNovaBaseUrl = (key) => `${novaBase()}/${key}`;
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
* @param {String} key api url
|
* @param {String} key api url
|
||||||
* @returns {String}
|
* @returns {String}
|
||||||
*/
|
*/
|
||||||
import { octaviaBase } from 'utils/constants';
|
import { octaviaBase } from 'client/client/constants';
|
||||||
|
|
||||||
const getOctaviaBaseUrl = (key) => `${octaviaBase()}/${key}`;
|
const getOctaviaBaseUrl = (key) => `${octaviaBase()}/${key}`;
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
* @param {String} key api url
|
* @param {String} key api url
|
||||||
* @returns {String}
|
* @returns {String}
|
||||||
*/
|
*/
|
||||||
import { pankoBase } from 'utils/constants';
|
import { pankoBase } from 'client/client/constants';
|
||||||
|
|
||||||
const getPankoBaseUrl = (key) => `${pankoBase()}/${key}`;
|
const getPankoBaseUrl = (key) => `${pankoBase()}/${key}`;
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
* @param {String} key api url
|
* @param {String} key api url
|
||||||
* @returns {String}
|
* @returns {String}
|
||||||
*/
|
*/
|
||||||
import { placementBase } from 'utils/constants';
|
import { placementBase } from 'client/client/constants';
|
||||||
|
|
||||||
const getPlacementBaseUrl = (key) => `${placementBase()}/${key}`;
|
const getPlacementBaseUrl = (key) => `${placementBase()}/${key}`;
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
* @param {String} key api url
|
* @param {String} key api url
|
||||||
* @returns {String}
|
* @returns {String}
|
||||||
*/
|
*/
|
||||||
import { skylineBase } from 'utils/constants';
|
import { skylineBase } from 'client/client/constants';
|
||||||
|
|
||||||
const getSkylineBaseUrl = (key) => `${skylineBase()}/${key}`;
|
const getSkylineBaseUrl = (key) => `${skylineBase()}/${key}`;
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
* @param {String} key api url
|
* @param {String} key api url
|
||||||
* @returns {String}
|
* @returns {String}
|
||||||
*/
|
*/
|
||||||
import { swiftBase } from 'utils/constants';
|
import { swiftBase } from 'client/client/constants';
|
||||||
|
|
||||||
const getSwiftBaseUrl = (key) => `${swiftBase()}/${key}`;
|
const getSwiftBaseUrl = (key) => `${swiftBase()}/${key}`;
|
||||||
|
|
||||||
|
155
src/client/cinder/index.js
Normal file
155
src/client/cinder/index.js
Normal file
@ -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 Base from '../client/base';
|
||||||
|
import { cinderBase } from '../client/constants';
|
||||||
|
|
||||||
|
class CinderClient extends Base {
|
||||||
|
get baseUrl() {
|
||||||
|
return cinderBase();
|
||||||
|
}
|
||||||
|
|
||||||
|
get projectInUrl() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
get resources() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
key: 'volumes',
|
||||||
|
responseKey: 'volume',
|
||||||
|
extendOperations: [
|
||||||
|
{
|
||||||
|
key: 'action',
|
||||||
|
method: 'post',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'types',
|
||||||
|
responseKey: 'volume_type',
|
||||||
|
extendOperations: [
|
||||||
|
{
|
||||||
|
key: 'action',
|
||||||
|
method: 'post',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'getAccess',
|
||||||
|
key: 'os-volume-type-access',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
subResources: [
|
||||||
|
{
|
||||||
|
name: 'extraSpecs',
|
||||||
|
key: 'extra_specs',
|
||||||
|
responseKey: 'extra_spec',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'encryption',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'snapshots',
|
||||||
|
responseKey: 'snapshot',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'backups',
|
||||||
|
responseKey: 'backup',
|
||||||
|
extendOperations: [
|
||||||
|
{
|
||||||
|
key: 'restore',
|
||||||
|
isDetail: true,
|
||||||
|
method: 'post',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'backupChains',
|
||||||
|
key: 'backup_chains',
|
||||||
|
responseKey: 'backup_chain',
|
||||||
|
extendOperations: [
|
||||||
|
{
|
||||||
|
key: 'restore',
|
||||||
|
isDetail: true,
|
||||||
|
method: 'post',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'pools',
|
||||||
|
key: 'scheduler-stats/get_pools',
|
||||||
|
responseKey: 'pool',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'qosSpecs',
|
||||||
|
key: 'qos-specs',
|
||||||
|
responseKey: 'qos_spec',
|
||||||
|
extendOperations: [
|
||||||
|
{
|
||||||
|
name: 'deleteKeys',
|
||||||
|
key: 'delete_keys',
|
||||||
|
method: 'put',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'associate',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'disassociate',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'services',
|
||||||
|
key: 'os-services',
|
||||||
|
responseKey: 'service',
|
||||||
|
extendOperations: [
|
||||||
|
{
|
||||||
|
key: 'enable',
|
||||||
|
isDetail: false,
|
||||||
|
method: 'put',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'reason',
|
||||||
|
key: 'disable-log-reason',
|
||||||
|
isDetail: false,
|
||||||
|
method: 'put',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'quotaSets',
|
||||||
|
key: 'os-quota-sets',
|
||||||
|
responseKey: 'quota_set',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'azones',
|
||||||
|
key: 'os-availability-zone',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'volumeTransfers',
|
||||||
|
key: 'volume-transfers',
|
||||||
|
extendOperations: [
|
||||||
|
{
|
||||||
|
key: 'accept',
|
||||||
|
method: 'post',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const cinderClient = new CinderClient();
|
||||||
|
export default cinderClient;
|
420
src/client/client/base.js
Normal file
420
src/client/client/base.js
Normal file
@ -0,0 +1,420 @@
|
|||||||
|
// 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 globalRootStore from 'stores/root';
|
||||||
|
import clientRequest from './request';
|
||||||
|
|
||||||
|
export default class BaseClient {
|
||||||
|
constructor() {
|
||||||
|
this.generateAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
getUrl = (url) => {
|
||||||
|
if (this.projectInUrl) {
|
||||||
|
return `${this.baseUrl}/${this.project}/${url}`;
|
||||||
|
}
|
||||||
|
return `${this.baseUrl}/${url}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
get request() {
|
||||||
|
const { request } = clientRequest;
|
||||||
|
return {
|
||||||
|
get: (url, params, conf) => request.get(this.getUrl(url), params, conf),
|
||||||
|
post: (url, data, params, conf) =>
|
||||||
|
request.post(this.getUrl(url), data, params, conf),
|
||||||
|
put: (url, data, params, conf) =>
|
||||||
|
request.put(this.getUrl(url), data, params, conf),
|
||||||
|
delete: (url, data, params, conf) =>
|
||||||
|
request.delete(this.getUrl(url), data, params, conf),
|
||||||
|
patch: (url, data, params, conf) =>
|
||||||
|
request.patch(this.getUrl(url), data, params, conf),
|
||||||
|
head: (url, params, conf) => request.head(this.getUrl(url), params, conf),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
get originRequest() {
|
||||||
|
const { request } = clientRequest;
|
||||||
|
return request;
|
||||||
|
}
|
||||||
|
|
||||||
|
get params() {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
get baseUrl() {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
get projectInUrl() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
get project() {
|
||||||
|
if (!this.projectInUrl) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
const { project: { id } = {} } = globalRootStore.user || {};
|
||||||
|
return id || '';
|
||||||
|
}
|
||||||
|
|
||||||
|
get enabled() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
get resources() {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
getListUrl(resourceName) {
|
||||||
|
return resourceName;
|
||||||
|
}
|
||||||
|
|
||||||
|
getDetailUrl(resourceName, id) {
|
||||||
|
if (!id) {
|
||||||
|
return resourceName;
|
||||||
|
}
|
||||||
|
if (resourceName[resourceName.length - 1] === '/') {
|
||||||
|
return `${resourceName.substr(0, resourceName.length - 1)}/${id}`;
|
||||||
|
}
|
||||||
|
return `${resourceName}/${id}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
getSubResourceUrl(resourceName, subResourceName) {
|
||||||
|
if (!resourceName) {
|
||||||
|
return subResourceName;
|
||||||
|
}
|
||||||
|
if (resourceName[resourceName.length - 1] === '/') {
|
||||||
|
return `${resourceName.substr(
|
||||||
|
0,
|
||||||
|
resourceName.length - 1
|
||||||
|
)}/${subResourceName}`;
|
||||||
|
}
|
||||||
|
return `${resourceName}/${subResourceName}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
getSubResourceUrlById(resourceName, subResourceName, id) {
|
||||||
|
return `${this.getDetailUrl(resourceName, id)}/${subResourceName}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
getSubResourceUrlBySubId(resourceName, subResourceName, id, subId) {
|
||||||
|
return `${this.getSubResourceUrlById(
|
||||||
|
resourceName,
|
||||||
|
subResourceName,
|
||||||
|
id
|
||||||
|
)}/${subId}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
getSubSubResourceListUrl(
|
||||||
|
resourceName,
|
||||||
|
subResourceName,
|
||||||
|
subSubResourceName,
|
||||||
|
id,
|
||||||
|
subId
|
||||||
|
) {
|
||||||
|
return `${this.getSubResourceUrlBySubId(
|
||||||
|
resourceName,
|
||||||
|
subResourceName,
|
||||||
|
id,
|
||||||
|
subId
|
||||||
|
)}/${subSubResourceName}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
getSubSubResourceDetailUrl(
|
||||||
|
resourceName,
|
||||||
|
subResourceName,
|
||||||
|
subSubResourceName,
|
||||||
|
id,
|
||||||
|
subId,
|
||||||
|
subSubId
|
||||||
|
) {
|
||||||
|
return `${this.getSubSubResourceListUrl(
|
||||||
|
resourceName,
|
||||||
|
subResourceName,
|
||||||
|
subSubResourceName,
|
||||||
|
id,
|
||||||
|
subId
|
||||||
|
)}/${subSubId}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
generateResource = (resourceName, responseKey, enabled = true) => {
|
||||||
|
const listUrl = this.getListUrl(resourceName);
|
||||||
|
return {
|
||||||
|
list: (params, conf) => this.request.get(listUrl, params, conf),
|
||||||
|
listDetail: (params, conf) =>
|
||||||
|
this.request.get(`${listUrl}/detail`, params, conf),
|
||||||
|
show: (id, params, conf) => {
|
||||||
|
return this.request.get(
|
||||||
|
this.getDetailUrl(resourceName, id),
|
||||||
|
params,
|
||||||
|
conf
|
||||||
|
);
|
||||||
|
},
|
||||||
|
create: (data, ...args) => this.request.post(listUrl, data, ...args),
|
||||||
|
update: (id, data, ...args) =>
|
||||||
|
this.request.put(this.getDetailUrl(resourceName, id), data, ...args),
|
||||||
|
patch: (id, data, ...args) =>
|
||||||
|
this.request.patch(this.getDetailUrl(resourceName, id), data, ...args),
|
||||||
|
delete: (id, ...args) =>
|
||||||
|
this.request.delete(this.getDetailUrl(resourceName, id), ...args),
|
||||||
|
responseKey,
|
||||||
|
enabled,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
generateSubResource = (
|
||||||
|
resourceName,
|
||||||
|
subResourceName,
|
||||||
|
responseKey,
|
||||||
|
enabled
|
||||||
|
) => ({
|
||||||
|
list: (id, params, ...args) =>
|
||||||
|
this.request.get(
|
||||||
|
this.getSubResourceUrlById(resourceName, subResourceName, id),
|
||||||
|
params,
|
||||||
|
...args
|
||||||
|
),
|
||||||
|
listDetail: (id, params, ...args) =>
|
||||||
|
this.request.get(
|
||||||
|
`${this.getSubResourceUrlById(
|
||||||
|
resourceName,
|
||||||
|
subResourceName,
|
||||||
|
id
|
||||||
|
)}/detail`,
|
||||||
|
params,
|
||||||
|
...args
|
||||||
|
),
|
||||||
|
show: (id, subId, params, ...args) =>
|
||||||
|
this.request.get(
|
||||||
|
this.getSubResourceUrlBySubId(resourceName, subResourceName, id, subId),
|
||||||
|
params,
|
||||||
|
...args
|
||||||
|
),
|
||||||
|
create: (id, data, ...args) =>
|
||||||
|
this.request.post(
|
||||||
|
this.getSubResourceUrlById(resourceName, subResourceName, id),
|
||||||
|
data,
|
||||||
|
...args
|
||||||
|
),
|
||||||
|
update: (id, subId, data, ...args) =>
|
||||||
|
this.request.put(
|
||||||
|
this.getSubResourceUrlBySubId(resourceName, subResourceName, id, subId),
|
||||||
|
data,
|
||||||
|
...args
|
||||||
|
),
|
||||||
|
patch: (id, subId, data, ...args) =>
|
||||||
|
this.request.patch(
|
||||||
|
this.getSubResourceUrlBySubId(resourceName, subResourceName, id, subId),
|
||||||
|
data,
|
||||||
|
...args
|
||||||
|
),
|
||||||
|
delete: (id, subId, ...args) =>
|
||||||
|
this.request.delete(
|
||||||
|
this.getSubResourceUrlBySubId(resourceName, subResourceName, id, subId),
|
||||||
|
...args
|
||||||
|
),
|
||||||
|
responseKey,
|
||||||
|
enabled,
|
||||||
|
});
|
||||||
|
|
||||||
|
generateSubSonResource = (
|
||||||
|
resourceName,
|
||||||
|
subResourceName,
|
||||||
|
subSubResonseName,
|
||||||
|
responseKey
|
||||||
|
) => ({
|
||||||
|
list: (id, subId, params, ...args) =>
|
||||||
|
this.request.get(
|
||||||
|
this.getSubSubResourceListUrl(
|
||||||
|
resourceName,
|
||||||
|
subResourceName,
|
||||||
|
subSubResonseName,
|
||||||
|
id,
|
||||||
|
subId
|
||||||
|
),
|
||||||
|
params,
|
||||||
|
...args
|
||||||
|
),
|
||||||
|
show: (id, subId, subSubId, params, ...args) =>
|
||||||
|
this.request.get(
|
||||||
|
this.getSubSubResourceDetailUrl(
|
||||||
|
resourceName,
|
||||||
|
subResourceName,
|
||||||
|
subSubResonseName,
|
||||||
|
id,
|
||||||
|
subId,
|
||||||
|
subSubId
|
||||||
|
),
|
||||||
|
params,
|
||||||
|
...args
|
||||||
|
),
|
||||||
|
create: (id, subId, data, ...args) =>
|
||||||
|
this.request.post(
|
||||||
|
this.getSubSubResourceListUrl(
|
||||||
|
resourceName,
|
||||||
|
subResourceName,
|
||||||
|
subSubResonseName,
|
||||||
|
id,
|
||||||
|
subId
|
||||||
|
),
|
||||||
|
data,
|
||||||
|
...args
|
||||||
|
),
|
||||||
|
update: (id, subId, subSubId, data, ...args) =>
|
||||||
|
this.request.put(
|
||||||
|
this.getSubSubResourceDetailUrl(
|
||||||
|
resourceName,
|
||||||
|
subResourceName,
|
||||||
|
subSubResonseName,
|
||||||
|
id,
|
||||||
|
subId,
|
||||||
|
subSubId
|
||||||
|
),
|
||||||
|
data,
|
||||||
|
...args
|
||||||
|
),
|
||||||
|
patch: (id, subId, subSubId, data, ...args) =>
|
||||||
|
this.request.patch(
|
||||||
|
this.getSubSubResourceDetailUrl(
|
||||||
|
resourceName,
|
||||||
|
subResourceName,
|
||||||
|
subSubResonseName,
|
||||||
|
id,
|
||||||
|
subId,
|
||||||
|
subSubId
|
||||||
|
),
|
||||||
|
data,
|
||||||
|
...args
|
||||||
|
),
|
||||||
|
delete: (id, subId, subSubId, ...args) =>
|
||||||
|
this.request.delete(
|
||||||
|
this.getSubSubResourceDetailUrl(
|
||||||
|
resourceName,
|
||||||
|
subResourceName,
|
||||||
|
subSubResonseName,
|
||||||
|
id,
|
||||||
|
subId,
|
||||||
|
subSubId
|
||||||
|
),
|
||||||
|
...args
|
||||||
|
),
|
||||||
|
responseKey,
|
||||||
|
});
|
||||||
|
|
||||||
|
setRequest = (url, method, ...restArgs) => {
|
||||||
|
const lowerMethod = method.toLowerCase();
|
||||||
|
return this.request[lowerMethod](url, ...restArgs);
|
||||||
|
};
|
||||||
|
|
||||||
|
generateAll = () => {
|
||||||
|
this.resources.forEach((resource) => {
|
||||||
|
const {
|
||||||
|
name,
|
||||||
|
key,
|
||||||
|
responseKey,
|
||||||
|
enabled,
|
||||||
|
subResources = [],
|
||||||
|
isResource = true,
|
||||||
|
extendOperations = [],
|
||||||
|
} = resource;
|
||||||
|
const result = isResource
|
||||||
|
? this.generateResource(key, responseKey, enabled)
|
||||||
|
: {};
|
||||||
|
const realName = name || key;
|
||||||
|
extendOperations.forEach((other) => {
|
||||||
|
const {
|
||||||
|
name: otherName,
|
||||||
|
key: otherKey,
|
||||||
|
method = 'get',
|
||||||
|
isDetail,
|
||||||
|
generate,
|
||||||
|
url,
|
||||||
|
} = other;
|
||||||
|
const otherRealName = otherName || otherKey;
|
||||||
|
const otherUrl = url && url();
|
||||||
|
const otherIsDetail = isResource
|
||||||
|
? isDetail === undefined
|
||||||
|
? true
|
||||||
|
: isDetail
|
||||||
|
: isDetail === undefined
|
||||||
|
? false
|
||||||
|
: isDetail;
|
||||||
|
if (generate) {
|
||||||
|
result[otherRealName] = generate;
|
||||||
|
} else if (otherIsDetail) {
|
||||||
|
result[otherRealName] = (id, ...args) => {
|
||||||
|
return this.setRequest(
|
||||||
|
otherUrl || this.getSubResourceUrlById(key, otherKey, id),
|
||||||
|
method,
|
||||||
|
...args
|
||||||
|
);
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
result[otherRealName] = (...args) => {
|
||||||
|
return this.setRequest(
|
||||||
|
otherUrl || this.getSubResourceUrl(key, otherKey),
|
||||||
|
method,
|
||||||
|
...args
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
subResources.forEach((sub) => {
|
||||||
|
let subResult = {};
|
||||||
|
const {
|
||||||
|
name: subName,
|
||||||
|
key: subKey,
|
||||||
|
responseKey: subResponseKey,
|
||||||
|
method: subMethod,
|
||||||
|
enabled: subEnabled,
|
||||||
|
subResources: subSubResources = [],
|
||||||
|
} = sub;
|
||||||
|
const subRealName = subName || subKey;
|
||||||
|
if (!subMethod) {
|
||||||
|
subResult = this.generateSubResource(
|
||||||
|
key,
|
||||||
|
subKey,
|
||||||
|
subResponseKey,
|
||||||
|
subEnabled
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
subResult = (id, ...args) => {
|
||||||
|
const url = this.getSubResourceUrlById(key, subKey, id);
|
||||||
|
return this.setRequest(url, subMethod, ...args);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
subSubResources.forEach((son) => {
|
||||||
|
const {
|
||||||
|
key: sonKey,
|
||||||
|
name: sonName,
|
||||||
|
responseKey: sonResponseKey,
|
||||||
|
} = son;
|
||||||
|
subResult[sonName || sonKey] = this.generateSubSonResource(
|
||||||
|
key,
|
||||||
|
subKey,
|
||||||
|
sonKey,
|
||||||
|
sonResponseKey
|
||||||
|
);
|
||||||
|
});
|
||||||
|
result[subRealName] = subResult;
|
||||||
|
});
|
||||||
|
if (realName) {
|
||||||
|
this[realName] = result;
|
||||||
|
} else {
|
||||||
|
Object.keys(result).forEach((resultKey) => {
|
||||||
|
this[resultKey] = result[resultKey];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
125
src/client/client/constants.js
Normal file
125
src/client/client/constants.js
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
// 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 globalRootStore from 'stores/root';
|
||||||
|
import { toJS } from 'mobx';
|
||||||
|
|
||||||
|
export const groupNameVersionMap = {
|
||||||
|
core: 'v1',
|
||||||
|
system: 'v1',
|
||||||
|
};
|
||||||
|
|
||||||
|
const endpointVersionMap = {
|
||||||
|
keystone: 'v3',
|
||||||
|
nova: 'v2.1',
|
||||||
|
cinder: 'v3',
|
||||||
|
glance: 'v2',
|
||||||
|
neutron: 'v2.0',
|
||||||
|
ironic: 'v1',
|
||||||
|
ironicInspector: 'v1',
|
||||||
|
heat: 'v1',
|
||||||
|
swift: 'v1',
|
||||||
|
octavia: 'v2',
|
||||||
|
courier: 'v1',
|
||||||
|
prometheus: 'api/v1',
|
||||||
|
prometheus_sidecar: 'api/v1',
|
||||||
|
gocron: 'api',
|
||||||
|
panko: 'v2',
|
||||||
|
billing_system: 'api/core.io/v1',
|
||||||
|
workflow: 'api/core.io/v1',
|
||||||
|
};
|
||||||
|
|
||||||
|
const endpointsDefault = {
|
||||||
|
ironic: '/api/openstack/ironic',
|
||||||
|
ironicInspector: '/api/openstack/ironic-inspector',
|
||||||
|
swift: '/api/openstack/swift/swift',
|
||||||
|
octavia: '/api/openstack/octavia',
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getOpenstackEndpoint = (key) => {
|
||||||
|
const { endpoints = {} } = globalRootStore || {};
|
||||||
|
const version = endpointVersionMap[key];
|
||||||
|
const endpoint = endpoints[key] || endpointsDefault[key] || '';
|
||||||
|
return version ? `${endpoint}/${version}` : endpoint;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getOriginEndpoint = (key) => {
|
||||||
|
const endpoints = toJS((globalRootStore && globalRootStore.endpoints) || {});
|
||||||
|
return endpoints[key];
|
||||||
|
};
|
||||||
|
|
||||||
|
export const skylineBase = () => '/api/openstack/skyline/api/v1';
|
||||||
|
export const keystoneBase = () => getOpenstackEndpoint('keystone');
|
||||||
|
export const novaBase = () => getOpenstackEndpoint('nova');
|
||||||
|
export const cinderBase = () => getOpenstackEndpoint('cinder');
|
||||||
|
export const glanceBase = () => getOpenstackEndpoint('glance');
|
||||||
|
export const neutronBase = () => getOpenstackEndpoint('neutron');
|
||||||
|
export const ironicBase = () => getOpenstackEndpoint('ironic');
|
||||||
|
export const ironicInspectorBase = () =>
|
||||||
|
getOpenstackEndpoint('ironicInspector');
|
||||||
|
export const placementBase = () => getOpenstackEndpoint('placement');
|
||||||
|
export const heatBase = () => getOpenstackEndpoint('heat');
|
||||||
|
export const swiftBase = () => getOpenstackEndpoint('swift');
|
||||||
|
export const octaviaBase = () => getOpenstackEndpoint('octavia');
|
||||||
|
export const alertmanagerBase = () => getOpenstackEndpoint('alertmanager');
|
||||||
|
export const prometheusBase = () => getOpenstackEndpoint('prometheus');
|
||||||
|
export const prometheusSidecarBase = () =>
|
||||||
|
getOpenstackEndpoint('prometheus_sidecar');
|
||||||
|
export const courierBase = () => getOpenstackEndpoint('courier');
|
||||||
|
export const gocronBase = () => getOpenstackEndpoint('gocron');
|
||||||
|
export const pankoBase = () => getOpenstackEndpoint('panko');
|
||||||
|
export const s3Base = () => getOpenstackEndpoint('s3');
|
||||||
|
export const billingBase = () => getOpenstackEndpoint('billing_system');
|
||||||
|
export const workflowBase = () => getOpenstackEndpoint('workflow');
|
||||||
|
|
||||||
|
export const ironicOriginEndpoint = () => getOriginEndpoint('ironic');
|
||||||
|
export const s3OriginEndpoint = () => getOriginEndpoint('s3');
|
||||||
|
export const billingEndpoint = () => getOriginEndpoint('billing_system');
|
||||||
|
export const firewallEndpoint = () => getOriginEndpoint('neutron_firewall');
|
||||||
|
export const vpnEndpoint = () => getOriginEndpoint('neutron_vpn');
|
||||||
|
export const lbEndpoint = () => getOriginEndpoint('octavia');
|
||||||
|
|
||||||
|
export const apiVersionMaps = {
|
||||||
|
nova: {
|
||||||
|
key: 'Openstack-Api-Version',
|
||||||
|
value: 'compute 2.79',
|
||||||
|
},
|
||||||
|
placement: {
|
||||||
|
key: 'Openstack-Api-Version',
|
||||||
|
value: 'placement 1.28',
|
||||||
|
},
|
||||||
|
cinder: {
|
||||||
|
key: 'Openstack-Api-Version',
|
||||||
|
value: 'volume 3.59',
|
||||||
|
},
|
||||||
|
ironic: {
|
||||||
|
key: 'X-Openstack-Ironic-Api-Version',
|
||||||
|
value: '1.58',
|
||||||
|
},
|
||||||
|
'ironic-inspect': {
|
||||||
|
key: 'X-OpenStack-Ironic-Inspector-API-Version',
|
||||||
|
value: '1.15',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getOpenstackApiVersion = (url) => {
|
||||||
|
const key = Object.keys(apiVersionMaps).find((it) => url.indexOf(it) > -1);
|
||||||
|
if (!key) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return apiVersionMaps[key];
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getK8sTypeEndpoint = (groupName, baseUrl) =>
|
||||||
|
`${baseUrl}/${groupName}/${groupNameVersionMap[groupName]}`;
|
181
src/client/client/request.js
Normal file
181
src/client/client/request.js
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
// 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 Axios from 'axios';
|
||||||
|
import { getLocalStorageItem } from 'utils/local-storage';
|
||||||
|
import { isEqual } from 'lodash';
|
||||||
|
import qs from 'qs';
|
||||||
|
import globalRootStore from 'stores/root';
|
||||||
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
|
import { getOpenstackApiVersion } from './constants';
|
||||||
|
|
||||||
|
const METHODS = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD'];
|
||||||
|
/**
|
||||||
|
* @class HttpRequest
|
||||||
|
* request with axios
|
||||||
|
*/
|
||||||
|
export class HttpRequest {
|
||||||
|
constructor() {
|
||||||
|
this.request = {};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param instance instance of axios
|
||||||
|
* @param url request url
|
||||||
|
* interceptors includes request & response
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
interceptors(instance, url) {
|
||||||
|
instance.interceptors.request.use(
|
||||||
|
(config) => {
|
||||||
|
const uuid = uuidv4();
|
||||||
|
config.headers['X-Openstack-Request-Id'] = `req-${uuid}`;
|
||||||
|
const keystoneToken = getLocalStorageItem('keystone_token') || '';
|
||||||
|
const apiVersionMap = getOpenstackApiVersion(url);
|
||||||
|
if (keystoneToken) {
|
||||||
|
config.headers['X-Auth-Token'] = keystoneToken;
|
||||||
|
}
|
||||||
|
if (apiVersionMap) {
|
||||||
|
config.headers[apiVersionMap.key] = apiVersionMap.value;
|
||||||
|
}
|
||||||
|
const { options: { headers, isFormData, ...rest } = {} } = config;
|
||||||
|
if (!isEqual(headers)) {
|
||||||
|
config.headers = {
|
||||||
|
...config.headers,
|
||||||
|
...headers,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
if (isFormData) {
|
||||||
|
delete config.headers['Content-Type'];
|
||||||
|
}
|
||||||
|
Object.keys(rest).forEach((key) => {
|
||||||
|
config[key] = rest[key];
|
||||||
|
});
|
||||||
|
return config;
|
||||||
|
},
|
||||||
|
(err) => Promise.reject(err)
|
||||||
|
);
|
||||||
|
|
||||||
|
instance.interceptors.response.use(
|
||||||
|
(response) => {
|
||||||
|
// request is finished
|
||||||
|
const { data, status } = response;
|
||||||
|
const disposition = response.headers['content-disposition'] || '';
|
||||||
|
const contentType = response.headers['content-type'] || '';
|
||||||
|
if (contentType.includes('application/octet-stream')) {
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
if (disposition.includes('attachment')) {
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
if (status < 200 || status >= 300) {
|
||||||
|
return Promise.reject(data);
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
// request is finished
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.log('error.response', error.response, error);
|
||||||
|
if (error.response) {
|
||||||
|
const { status } = error.response;
|
||||||
|
if (status === 401) {
|
||||||
|
const currentPath = window.location.pathname;
|
||||||
|
if (currentPath.indexOf('login') < 0) {
|
||||||
|
globalRootStore.gotoLoginPage(currentPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Promise.reject(error);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create a new instance of axios with a custom config
|
||||||
|
*/
|
||||||
|
create() {
|
||||||
|
const conf = {
|
||||||
|
baseURL: '/',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json;charset=utf-8',
|
||||||
|
'cache-control': 'no-cache',
|
||||||
|
pragma: 'no-cache',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return Axios.create(conf);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Object} obj translated object
|
||||||
|
* @returns {Object} trim undefined & null
|
||||||
|
*/
|
||||||
|
omitNil(obj) {
|
||||||
|
if (typeof obj !== 'object') return obj;
|
||||||
|
return Object.keys(obj).reduce((acc, v) => {
|
||||||
|
if (obj[v] !== undefined && obj[v] !== null && obj[v] !== '')
|
||||||
|
acc[v] = obj[v];
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* build request
|
||||||
|
* @param {Object} config requests config
|
||||||
|
* @returns {Promise} axios instance return promise
|
||||||
|
*/
|
||||||
|
buildRequest(config) {
|
||||||
|
const method = config.method ? config.method.toLowerCase() : 'get';
|
||||||
|
const options = { ...config };
|
||||||
|
// Only get and head, we need to use null for some posts requests
|
||||||
|
if (options.params && ['get', 'head'].includes(method)) {
|
||||||
|
options.params = this.omitNil(options.params);
|
||||||
|
options.paramsSerializer = (p) =>
|
||||||
|
qs.stringify(p, { arrayFormat: 'repeat' });
|
||||||
|
}
|
||||||
|
const instance = this.create();
|
||||||
|
this.interceptors(instance, options.url);
|
||||||
|
return instance(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
generateRequestMap = () => {
|
||||||
|
METHODS.forEach((method) => {
|
||||||
|
const lowerMethod = method.toLowerCase();
|
||||||
|
if (lowerMethod === 'get' || lowerMethod === 'head') {
|
||||||
|
this.request[lowerMethod] = (url, params = {}, options) => {
|
||||||
|
return this.buildRequest({
|
||||||
|
method: lowerMethod,
|
||||||
|
url,
|
||||||
|
params,
|
||||||
|
options,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
this.request[lowerMethod] = (url, data, params, options) => {
|
||||||
|
return this.buildRequest({
|
||||||
|
method: lowerMethod,
|
||||||
|
url,
|
||||||
|
data,
|
||||||
|
params,
|
||||||
|
options,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const httpRequest = new HttpRequest();
|
||||||
|
httpRequest.generateRequestMap();
|
||||||
|
export default httpRequest;
|
87
src/client/glance/index.js
Normal file
87
src/client/glance/index.js
Normal file
@ -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 { glanceBase } from '../client/constants';
|
||||||
|
|
||||||
|
class GlanceClient extends Base {
|
||||||
|
get baseUrl() {
|
||||||
|
return glanceBase();
|
||||||
|
}
|
||||||
|
|
||||||
|
get resources() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
key: 'images',
|
||||||
|
responseKey: 'image',
|
||||||
|
extendOperations: [
|
||||||
|
{
|
||||||
|
key: 'count',
|
||||||
|
isDetail: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'uploadFile',
|
||||||
|
generate: (id, body, conf = {}) => {
|
||||||
|
return this.request.put(
|
||||||
|
`${this.getDetailUrl('images', id)}/file`,
|
||||||
|
body,
|
||||||
|
null,
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
'content-type': 'application/octet-stream',
|
||||||
|
},
|
||||||
|
...conf,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'patch',
|
||||||
|
generate: (id, data) =>
|
||||||
|
this.request.patch(this.getDetailUrl('images', id), data, null, {
|
||||||
|
headers: {
|
||||||
|
'content-type':
|
||||||
|
'application/openstack-images-v2.1-json-patch',
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
subResources: [
|
||||||
|
{
|
||||||
|
key: 'members',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'namespaces',
|
||||||
|
key: 'metadefs/namespaces',
|
||||||
|
responseKey: 'namespace',
|
||||||
|
subResources: [
|
||||||
|
{
|
||||||
|
name: 'resourceTypes',
|
||||||
|
key: 'resource_types',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'resourceTypes',
|
||||||
|
key: 'metadefs/resource_types',
|
||||||
|
responseKey: 'resource_type',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const glanceClient = new GlanceClient();
|
||||||
|
export default glanceClient;
|
93
src/client/heat/index.js
Normal file
93
src/client/heat/index.js
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
// 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 { heatBase } from '../client/constants';
|
||||||
|
|
||||||
|
class HeatClient extends Base {
|
||||||
|
get baseUrl() {
|
||||||
|
return heatBase();
|
||||||
|
}
|
||||||
|
|
||||||
|
get projectInUrl() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
getDetailUrlForStack = ({ id, name }) => `stacks/${name}/${id}`;
|
||||||
|
|
||||||
|
get resources() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
key: 'stacks',
|
||||||
|
responseKey: 'stack',
|
||||||
|
extendOperations: [
|
||||||
|
{
|
||||||
|
key: 'show',
|
||||||
|
generate: ({ id, name }, params) => {
|
||||||
|
return this.request.get(
|
||||||
|
this.getDetailUrlForStack({ id, name }),
|
||||||
|
params
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'update',
|
||||||
|
generate: ({ id, name }, data) =>
|
||||||
|
this.request.put(this.getDetailUrlForStack({ id, name }), data),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'delete',
|
||||||
|
generate: ({ id, name }) =>
|
||||||
|
this.request.delete(this.getDetailUrlForStack({ id, name })),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'abandon',
|
||||||
|
generate: ({ id, name }) =>
|
||||||
|
this.request.delete(
|
||||||
|
`${this.getDetailUrlForStack({ id, name })}/abandon`
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'template',
|
||||||
|
generate: ({ id, name }) =>
|
||||||
|
this.request.get(
|
||||||
|
`${this.getDetailUrlForStack({ id, name })}/template`
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'events',
|
||||||
|
generate: ({ id, name }) =>
|
||||||
|
this.request.get(
|
||||||
|
`${this.getDetailUrlForStack({ id, name })}/events`
|
||||||
|
),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'resources',
|
||||||
|
generate: ({ id, name }) =>
|
||||||
|
this.request.get(
|
||||||
|
`${this.getDetailUrlForStack({ id, name })}/resources`
|
||||||
|
),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'services',
|
||||||
|
responseKey: 'service',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const heatClient = new HeatClient();
|
||||||
|
export default heatClient;
|
41
src/client/index.js
Normal file
41
src/client/index.js
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
// Copyright 2021 99cloud
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
import skyline from './skyline';
|
||||||
|
import nova from './nova';
|
||||||
|
import cinder from './cinder';
|
||||||
|
import glance from './glance';
|
||||||
|
import neutron from './neutron';
|
||||||
|
import keystone from './keystone';
|
||||||
|
import heat from './heat';
|
||||||
|
import octavia from './octavia';
|
||||||
|
import placement from './placement';
|
||||||
|
import ironic from './ironic';
|
||||||
|
|
||||||
|
const client = {
|
||||||
|
skyline,
|
||||||
|
nova,
|
||||||
|
cinder,
|
||||||
|
glance,
|
||||||
|
neutron,
|
||||||
|
keystone,
|
||||||
|
heat,
|
||||||
|
octavia,
|
||||||
|
placement,
|
||||||
|
ironic,
|
||||||
|
};
|
||||||
|
|
||||||
|
window.client = client;
|
||||||
|
|
||||||
|
export default client;
|
96
src/client/ironic/index.js
Normal file
96
src/client/ironic/index.js
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
// 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 { ironicBase } from '../client/constants';
|
||||||
|
|
||||||
|
class IronicClient extends Base {
|
||||||
|
get baseUrl() {
|
||||||
|
return ironicBase();
|
||||||
|
}
|
||||||
|
|
||||||
|
get resources() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
key: 'nodes',
|
||||||
|
responseKey: 'node',
|
||||||
|
extendOperations: [
|
||||||
|
{
|
||||||
|
name: 'updateStatesProvision',
|
||||||
|
key: 'states/provision',
|
||||||
|
method: 'put',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'UpdateStatesPower',
|
||||||
|
key: 'states/power',
|
||||||
|
method: 'put',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'updateMaintenance',
|
||||||
|
key: 'maintenance',
|
||||||
|
method: 'put',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'deleteMaintenance',
|
||||||
|
key: 'maintenance',
|
||||||
|
method: 'delete',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'getManagementBootDevice',
|
||||||
|
key: 'management/boot_device',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'updateManagementBootDevice',
|
||||||
|
key: 'management/boot_device',
|
||||||
|
method: 'put',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'getManagementBootDeviceSupported',
|
||||||
|
key: 'management/boot_device/supported',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'updateTraits',
|
||||||
|
method: 'put',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
subResources: [
|
||||||
|
{
|
||||||
|
key: 'states',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'validate',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'ports',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'portgroups',
|
||||||
|
responseKey: 'portgroup',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'ports',
|
||||||
|
responseKey: 'port',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'portgroups',
|
||||||
|
responseKey: 'portgroup',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const ironicClient = new IronicClient();
|
||||||
|
export default ironicClient;
|
149
src/client/keystone/index.js
Normal file
149
src/client/keystone/index.js
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
// 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 { keystoneBase } from '../client/constants';
|
||||||
|
|
||||||
|
class KeystoneClient extends Base {
|
||||||
|
get baseUrl() {
|
||||||
|
return keystoneBase();
|
||||||
|
}
|
||||||
|
|
||||||
|
get resources() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
name: 'catalog',
|
||||||
|
key: 'auth/catalog',
|
||||||
|
responseKey: 'catalog',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'projects',
|
||||||
|
responseKey: 'project',
|
||||||
|
extendOperations: [
|
||||||
|
{
|
||||||
|
name: 'updateTags',
|
||||||
|
key: 'tags',
|
||||||
|
method: 'put',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
subResources: [
|
||||||
|
{
|
||||||
|
key: 'tags',
|
||||||
|
responseKey: 'tag',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'groups',
|
||||||
|
subResources: [
|
||||||
|
{
|
||||||
|
key: 'roles',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'users',
|
||||||
|
subResources: [
|
||||||
|
{
|
||||||
|
key: 'roles',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'domains',
|
||||||
|
responseKey: 'domain',
|
||||||
|
subResources: [
|
||||||
|
{
|
||||||
|
key: 'groups',
|
||||||
|
subResources: [
|
||||||
|
{
|
||||||
|
key: 'roles',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'users',
|
||||||
|
subResources: [
|
||||||
|
{
|
||||||
|
key: 'roles',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'roles',
|
||||||
|
responseKey: 'role',
|
||||||
|
subResources: [
|
||||||
|
{
|
||||||
|
key: 'implies',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'roleAssignments',
|
||||||
|
key: 'role_assignments',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'users',
|
||||||
|
responseKey: 'user',
|
||||||
|
subResources: [
|
||||||
|
{
|
||||||
|
key: 'projects',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'groups',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
extendOperations: [
|
||||||
|
{
|
||||||
|
name: 'updatePassword',
|
||||||
|
key: 'password',
|
||||||
|
method: 'post',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'groups',
|
||||||
|
responseKey: 'group',
|
||||||
|
subResources: [
|
||||||
|
{
|
||||||
|
key: 'users',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'systemGroups',
|
||||||
|
key: 'system/groups',
|
||||||
|
subResources: [
|
||||||
|
{
|
||||||
|
key: 'roles',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'systemUsers',
|
||||||
|
key: 'system/users',
|
||||||
|
subResources: [
|
||||||
|
{
|
||||||
|
key: 'roles',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const keystoneClient = new KeystoneClient();
|
||||||
|
export default keystoneClient;
|
201
src/client/neutron/index.js
Normal file
201
src/client/neutron/index.js
Normal file
@ -0,0 +1,201 @@
|
|||||||
|
// 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 { neutronBase } from '../client/constants';
|
||||||
|
|
||||||
|
class NeutronClient extends Base {
|
||||||
|
get baseUrl() {
|
||||||
|
return neutronBase();
|
||||||
|
}
|
||||||
|
|
||||||
|
get resources() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
key: 'networks',
|
||||||
|
responseKey: 'network',
|
||||||
|
subResources: [
|
||||||
|
{
|
||||||
|
name: 'dhcpAgents',
|
||||||
|
key: 'dhcp-agents',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'subnets',
|
||||||
|
responseKey: 'subnet',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'extensions',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'ports',
|
||||||
|
responseKey: 'port',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'routers',
|
||||||
|
responseKey: 'router',
|
||||||
|
extendOperations: [
|
||||||
|
{
|
||||||
|
name: 'addRouterInterface',
|
||||||
|
key: 'add_router_interface',
|
||||||
|
method: 'put',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'removeRouterInterface',
|
||||||
|
key: 'remove_router_interface',
|
||||||
|
method: 'put',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'addExtraRoutes',
|
||||||
|
key: 'add_extraroutes',
|
||||||
|
method: 'put',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'removeExtraRoutes',
|
||||||
|
key: 'remove_extraroutes',
|
||||||
|
method: 'put',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'floatingips',
|
||||||
|
responseKey: 'floatingip',
|
||||||
|
subResources: [
|
||||||
|
{
|
||||||
|
name: 'portForwardings',
|
||||||
|
key: 'port_forwardings',
|
||||||
|
responseKey: 'port_forwarding',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'agents',
|
||||||
|
responseKey: 'agent',
|
||||||
|
subResources: [
|
||||||
|
{
|
||||||
|
name: 'dhcpNetworks',
|
||||||
|
key: 'dhcp-networks',
|
||||||
|
responseKey: 'network',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'l3Routers',
|
||||||
|
key: 'l3-routers',
|
||||||
|
responseKey: 'router',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'firewalls',
|
||||||
|
key: 'fwaas/firewall_groups',
|
||||||
|
responseKey: 'firewall_group',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'firewallPolicies',
|
||||||
|
key: 'fwaas/firewall_policies',
|
||||||
|
responseKey: 'firewall_policy',
|
||||||
|
extendOperations: [
|
||||||
|
{
|
||||||
|
name: 'insertRule',
|
||||||
|
key: 'insert_rule',
|
||||||
|
method: 'put',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'removeRule',
|
||||||
|
key: 'remove_rule',
|
||||||
|
method: 'put',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'firewallRules',
|
||||||
|
key: 'fwaas/firewall_rules',
|
||||||
|
responseKey: 'firewall_rule',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'networkIpAvailabilities',
|
||||||
|
key: 'network-ip-availabilities',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'azones',
|
||||||
|
key: 'availability_zones',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'qosPolicies',
|
||||||
|
key: 'qos/policies',
|
||||||
|
responseKey: 'policy',
|
||||||
|
subResources: [
|
||||||
|
{
|
||||||
|
name: 'bandwidthLimitRules',
|
||||||
|
key: 'bandwidth_limit_rules',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'dscpMarkingRules',
|
||||||
|
key: 'dscp_marking_rules',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'securityGroups',
|
||||||
|
key: 'security-groups',
|
||||||
|
responseKey: 'security_group',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'securityGroupRules',
|
||||||
|
key: 'security-group-rules',
|
||||||
|
responseKey: 'security_group_rule',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'subnets',
|
||||||
|
responseKey: 'subnet',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'endpointGroups',
|
||||||
|
key: 'endpoint-groups',
|
||||||
|
responseKey: 'endpoint_group',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'ikePolicies',
|
||||||
|
key: 'ikepolicies',
|
||||||
|
responseKey: 'ikepolicy',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'ipsecPolicies',
|
||||||
|
key: 'ipsecpolicies',
|
||||||
|
responseKey: 'ipsecpolicy',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'ipsecSiteConnections',
|
||||||
|
key: 'ipsec_site_connections',
|
||||||
|
responseKey: 'ipsec_site_connection',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'vpnservices',
|
||||||
|
responseKey: 'vpnservice',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'quotas',
|
||||||
|
responseKey: 'quota',
|
||||||
|
extendOperations: [
|
||||||
|
{
|
||||||
|
key: 'details',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const neutronClient = new NeutronClient();
|
||||||
|
export default neutronClient;
|
134
src/client/nova/index.js
Normal file
134
src/client/nova/index.js
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
// 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 { novaBase } from '../client/constants';
|
||||||
|
|
||||||
|
class NovaClient extends Base {
|
||||||
|
get baseUrl() {
|
||||||
|
return novaBase();
|
||||||
|
}
|
||||||
|
|
||||||
|
get resources() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
key: 'servers',
|
||||||
|
responseKey: 'server',
|
||||||
|
subResources: [
|
||||||
|
{
|
||||||
|
name: 'interfaces',
|
||||||
|
key: 'os-interface',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'volumeAttachments',
|
||||||
|
key: 'os-volume_attachments',
|
||||||
|
responseKey: 'volumeAttachment',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'instanceActions',
|
||||||
|
key: 'os-instance-actions',
|
||||||
|
responseKey: 'instanceAction',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
extendOperations: [
|
||||||
|
{
|
||||||
|
name: 'createConsole',
|
||||||
|
key: 'remote-consoles',
|
||||||
|
method: 'post',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'action',
|
||||||
|
method: 'post',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'zone',
|
||||||
|
key: 'os-availability-zone',
|
||||||
|
responseKey: 'availabilityZoneInfo',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'flavors',
|
||||||
|
responseKey: 'flavor',
|
||||||
|
extendOperations: [
|
||||||
|
{
|
||||||
|
name: 'action',
|
||||||
|
key: 'action',
|
||||||
|
method: 'post',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
subResources: [
|
||||||
|
{
|
||||||
|
name: 'access',
|
||||||
|
key: 'os-flavor-access',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'extraSpecs',
|
||||||
|
key: 'os-extra_specs',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'keypairs',
|
||||||
|
key: 'os-keypairs',
|
||||||
|
responseKey: 'keypair',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'serverGroups',
|
||||||
|
key: 'os-server-groups',
|
||||||
|
responseKey: 'server_group',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'aggregates',
|
||||||
|
key: 'os-aggregates',
|
||||||
|
responseKey: 'aggregate',
|
||||||
|
extendOperations: [
|
||||||
|
{
|
||||||
|
name: 'action',
|
||||||
|
key: 'action',
|
||||||
|
method: 'post',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'services',
|
||||||
|
key: 'os-services',
|
||||||
|
responseKey: 'service',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'quotaSets',
|
||||||
|
key: 'os-quota-sets',
|
||||||
|
responseKey: 'quota_set',
|
||||||
|
extendOperations: [
|
||||||
|
{
|
||||||
|
key: 'detail',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'hypervisors',
|
||||||
|
key: 'os-hypervisors',
|
||||||
|
responseKey: 'hypervisor',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'pciDevices',
|
||||||
|
key: 'os-pci-devices',
|
||||||
|
responseKey: 'pci_device',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const novaClient = new NovaClient();
|
||||||
|
export default novaClient;
|
62
src/client/octavia/index.js
Normal file
62
src/client/octavia/index.js
Normal file
@ -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 Base from '../client/base';
|
||||||
|
import { octaviaBase } from '../client/constants';
|
||||||
|
|
||||||
|
class OctaviaClient extends Base {
|
||||||
|
get baseUrl() {
|
||||||
|
return octaviaBase();
|
||||||
|
}
|
||||||
|
|
||||||
|
get resources() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
name: 'healthMonitors',
|
||||||
|
key: 'lbaas/healthmonitors',
|
||||||
|
responseKey: 'healthmonitor',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'listeners',
|
||||||
|
key: 'lbaas/listeners',
|
||||||
|
responseKey: 'listener',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'loadbalancers',
|
||||||
|
key: 'lbaas/loadbalancers',
|
||||||
|
responseKey: 'loadbalancer',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'pools',
|
||||||
|
key: 'lbaas/pools',
|
||||||
|
responseKey: 'pool',
|
||||||
|
extendOperations: [
|
||||||
|
{
|
||||||
|
name: 'batchUpdateMembers',
|
||||||
|
key: 'members',
|
||||||
|
method: 'put',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
subResources: [
|
||||||
|
{
|
||||||
|
key: 'members',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const octaviaClient = new OctaviaClient();
|
||||||
|
export default octaviaClient;
|
42
src/client/placement/index.js
Normal file
42
src/client/placement/index.js
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
// Copyright 2021 99cloud
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
import Base from '../client/base';
|
||||||
|
import { placementBase } from '../client/constants';
|
||||||
|
|
||||||
|
class PlacementClient extends Base {
|
||||||
|
get baseUrl() {
|
||||||
|
return placementBase();
|
||||||
|
}
|
||||||
|
|
||||||
|
get resources() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
name: 'resourceProviders',
|
||||||
|
key: 'resource_providers',
|
||||||
|
subResources: [
|
||||||
|
{
|
||||||
|
key: 'inventories',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'traits',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const placementClient = new PlacementClient();
|
||||||
|
export default placementClient;
|
123
src/client/skyline/index.js
Normal file
123
src/client/skyline/index.js
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
// 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 { skylineBase } from '../client/constants';
|
||||||
|
|
||||||
|
class SkylineClient extends Base {
|
||||||
|
get baseUrl() {
|
||||||
|
return skylineBase();
|
||||||
|
}
|
||||||
|
|
||||||
|
get resources() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
key: 'contrib',
|
||||||
|
isResource: false,
|
||||||
|
extendOperations: [
|
||||||
|
{
|
||||||
|
key: 'domains',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'regions',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'keystoneEndpoints',
|
||||||
|
key: 'keystone_endpoints',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'extension',
|
||||||
|
isResource: false,
|
||||||
|
extendOperations: [
|
||||||
|
{
|
||||||
|
key: 'servers',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'recycleServers',
|
||||||
|
key: 'recycle_servers',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'volumes',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'volumeSnapshots',
|
||||||
|
key: 'volume_snapshots',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'ports',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'policies',
|
||||||
|
key: 'policies',
|
||||||
|
extendOperations: [
|
||||||
|
{
|
||||||
|
name: 'check',
|
||||||
|
key: 'check',
|
||||||
|
isDetail: false,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '',
|
||||||
|
key: '',
|
||||||
|
isResource: false,
|
||||||
|
extendOperations: [
|
||||||
|
{
|
||||||
|
key: 'login',
|
||||||
|
method: 'post',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'logout',
|
||||||
|
method: 'post',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'profile',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'switchProject',
|
||||||
|
method: 'post',
|
||||||
|
generate: (projectId, domainId) => {
|
||||||
|
const url = `switch_project/${projectId}`;
|
||||||
|
const data = {
|
||||||
|
project_id: projectId,
|
||||||
|
project_domain_id: domainId,
|
||||||
|
};
|
||||||
|
const params = {
|
||||||
|
project_domain_id: domainId,
|
||||||
|
};
|
||||||
|
return this.request.post(url, data, params);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
key: 'setting',
|
||||||
|
responseKey: 'setting',
|
||||||
|
extendOperations: [
|
||||||
|
{
|
||||||
|
key: 'list',
|
||||||
|
url: () => 'settings',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const skylineClient = new SkylineClient();
|
||||||
|
export default skylineClient;
|
@ -104,6 +104,11 @@ export default class BaseForm extends React.Component {
|
|||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get currentUser() {
|
||||||
|
const { user } = this.props.rootStore || {};
|
||||||
|
return user || {};
|
||||||
|
}
|
||||||
|
|
||||||
get isAdminPage() {
|
get isAdminPage() {
|
||||||
const { pathname = '' } = this.props.location || {};
|
const { pathname = '' } = this.props.location || {};
|
||||||
return isAdminPage(pathname);
|
return isAdminPage(pathname);
|
||||||
@ -114,11 +119,11 @@ export default class BaseForm extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get currentProjectId() {
|
get currentProjectId() {
|
||||||
return globals.user.project.id;
|
return this.props.rootStore.projectId;
|
||||||
}
|
}
|
||||||
|
|
||||||
get currentProjectName() {
|
get currentProjectName() {
|
||||||
return globals.user.project.name;
|
return this.props.rootStore.projectName;
|
||||||
}
|
}
|
||||||
|
|
||||||
getUrl(path, adminStr) {
|
getUrl(path, adminStr) {
|
||||||
@ -258,7 +263,7 @@ export default class BaseForm extends React.Component {
|
|||||||
this.responseError = err;
|
this.responseError = err;
|
||||||
this.showNotice && Notify.errorWithDetail(err, this.errorText);
|
this.showNotice && Notify.errorWithDetail(err, this.errorText);
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.log(err);
|
console.log('err', err);
|
||||||
if (callback && isFunction(callback)) {
|
if (callback && isFunction(callback)) {
|
||||||
callback(false, true);
|
callback(false, true);
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ export default class NetworkSelectTable extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get currentProjectId() {
|
get currentProjectId() {
|
||||||
return globals.user.project.id;
|
return this.props.rootStore.projectId;
|
||||||
}
|
}
|
||||||
|
|
||||||
get hasAdminRole() {
|
get hasAdminRole() {
|
||||||
|
@ -34,7 +34,7 @@ export default class VolumeSelectTable extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get currentProjectId() {
|
get currentProjectId() {
|
||||||
return globals.user.project.id;
|
return this.props.rootStore.projectId;
|
||||||
}
|
}
|
||||||
|
|
||||||
get hasAdminRole() {
|
get hasAdminRole() {
|
||||||
|
@ -126,7 +126,7 @@ class AvatarDropdown extends React.Component {
|
|||||||
<ItemActionButtons
|
<ItemActionButtons
|
||||||
actions={{ moreActions: [{ action: Password }] }}
|
actions={{ moreActions: [{ action: Password }] }}
|
||||||
onFinishAction={this.afterChangePassword}
|
onFinishAction={this.afterChangePassword}
|
||||||
item={globals.user.user}
|
item={this.user && this.user.user}
|
||||||
isWide
|
isWide
|
||||||
/>
|
/>
|
||||||
</Menu.Item>
|
</Menu.Item>
|
||||||
|
@ -28,7 +28,7 @@ const gotoConsole = (type, props) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const GlobalHeaderRight = (props) => {
|
const GlobalHeaderRight = (props) => {
|
||||||
const { isAdminPage = false, rootStore: { hasAdminRole = false } = {} } =
|
const { isAdminPage = false, rootStore: { hasAdminPageRole = false } = {} } =
|
||||||
props;
|
props;
|
||||||
let linkRender = null;
|
let linkRender = null;
|
||||||
if (isAdminPage) {
|
if (isAdminPage) {
|
||||||
@ -41,7 +41,7 @@ const GlobalHeaderRight = (props) => {
|
|||||||
{t('Console')}
|
{t('Console')}
|
||||||
</Button>
|
</Button>
|
||||||
);
|
);
|
||||||
} else if (hasAdminRole) {
|
} else if (hasAdminPageRole) {
|
||||||
linkRender = (
|
linkRender = (
|
||||||
<Button
|
<Button
|
||||||
type="link"
|
type="link"
|
||||||
|
@ -107,6 +107,15 @@ export default class BaseStepForm extends React.Component {
|
|||||||
return this.checkEndpoint && !this.endpoint;
|
return this.checkEndpoint && !this.endpoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get currentUser() {
|
||||||
|
const { user } = this.props.rootStore || {};
|
||||||
|
return user || {};
|
||||||
|
}
|
||||||
|
|
||||||
|
get currentProjectId() {
|
||||||
|
return this.props.rootStore.projectId;
|
||||||
|
}
|
||||||
|
|
||||||
get labelCol() {
|
get labelCol() {
|
||||||
return {
|
return {
|
||||||
xs: { span: 4 },
|
xs: { span: 4 },
|
||||||
@ -218,9 +227,10 @@ export default class BaseStepForm extends React.Component {
|
|||||||
Notify.success(this.successText);
|
Notify.success(this.successText);
|
||||||
},
|
},
|
||||||
(err) => {
|
(err) => {
|
||||||
// eslint-disable-next-line no-console
|
this.responseError = err;
|
||||||
console.log('reject', err);
|
const { response: { data: responseData } = {} } = err;
|
||||||
Notify.errorWithDetail(err, this.errorText);
|
console.log('err', err, responseData);
|
||||||
|
Notify.errorWithDetail(responseData, this.errorText);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -243,7 +243,8 @@ class ActionButton extends Component {
|
|||||||
const message = submitErrorMsgBatch
|
const message = submitErrorMsgBatch
|
||||||
? submitErrorMsgBatch(data)
|
? submitErrorMsgBatch(data)
|
||||||
: getDefaultMsg(this.props.action, data).submitErrorMsgBatch;
|
: getDefaultMsg(this.props.action, data).submitErrorMsgBatch;
|
||||||
Notify.errorWithDetail(error, message);
|
const { data: responseData } = error.response || error || {};
|
||||||
|
Notify.errorWithDetail(responseData || error, message);
|
||||||
this.onCallback(false, true);
|
this.onCallback(false, true);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -260,10 +261,12 @@ class ActionButton extends Component {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const { submitErrorMsg } = this.props.action;
|
const { submitErrorMsg } = this.props.action;
|
||||||
|
const { data: responseData } = error.response || error || {};
|
||||||
|
const realError = responseData || error;
|
||||||
const message = submitErrorMsg
|
const message = submitErrorMsg
|
||||||
? submitErrorMsg(data, error)
|
? submitErrorMsg(data, realError)
|
||||||
: getDefaultMsg(this.props.action, data).submitErrorMsg;
|
: getDefaultMsg(this.props.action, data).submitErrorMsg;
|
||||||
Notify.errorWithDetail(error, message);
|
Notify.errorWithDetail(realError, message);
|
||||||
this.onCallback(false, true);
|
this.onCallback(false, true);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -59,9 +59,16 @@ function DropdownActionButton({
|
|||||||
const menuItems = actions.map((it) => {
|
const menuItems = actions.map((it) => {
|
||||||
const key = `table-batch-more-${generateId()}`;
|
const key = `table-batch-more-${generateId()}`;
|
||||||
const newConf = updateConf(it, selectedItems);
|
const newConf = updateConf(it, selectedItems);
|
||||||
const { buttonType } = newConf;
|
const { buttonType, name } = newConf;
|
||||||
newConf.onFinishAction = onFinishAction;
|
newConf.onFinishAction = onFinishAction;
|
||||||
newConf.danger = buttonType === 'danger';
|
newConf.danger = buttonType === 'danger';
|
||||||
|
if (!selectedItems.length) {
|
||||||
|
return (
|
||||||
|
<Menu.Item key={key} disabled style={{ textAlign: 'center' }}>
|
||||||
|
{name}
|
||||||
|
</Menu.Item>
|
||||||
|
);
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<Menu.Item key={key}>
|
<Menu.Item key={key}>
|
||||||
<ActionButton
|
<ActionButton
|
||||||
|
@ -55,8 +55,8 @@ export default class TablePrimaryButtons extends Component {
|
|||||||
this.getActionsAllowed();
|
this.getActionsAllowed();
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidUpdate(nextProps) {
|
componentDidUpdate(prevProps) {
|
||||||
if (!isEqual(nextProps, this.props)) {
|
if (!isEqual(prevProps, this.props)) {
|
||||||
this.getActionsAllowed();
|
this.getActionsAllowed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -223,8 +223,12 @@ export default class SimpleTable extends React.Component {
|
|||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
const { selectedRowKeys, onChange, type, getCheckboxProps } =
|
const {
|
||||||
rowSelection;
|
selectedRowKeys = [],
|
||||||
|
onChange,
|
||||||
|
type,
|
||||||
|
getCheckboxProps,
|
||||||
|
} = rowSelection || {};
|
||||||
if (getCheckboxProps) {
|
if (getCheckboxProps) {
|
||||||
const { disabled } = getCheckboxProps(record);
|
const { disabled } = getCheckboxProps(record);
|
||||||
if (disabled) {
|
if (disabled) {
|
||||||
|
@ -35,8 +35,13 @@ export default class BaseDetail extends React.Component {
|
|||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
get currentProject() {
|
get currentUser() {
|
||||||
return globals.user.project.id;
|
const { user } = this.props.rootStore || {};
|
||||||
|
return user || {};
|
||||||
|
}
|
||||||
|
|
||||||
|
get currentProjectId() {
|
||||||
|
return this.props.rootStore.projectId;
|
||||||
}
|
}
|
||||||
|
|
||||||
get projectId() {
|
get projectId() {
|
||||||
@ -45,7 +50,7 @@ export default class BaseDetail extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get isMyResource() {
|
get isMyResource() {
|
||||||
return this.projectId === this.currentProject;
|
return this.projectId === this.currentProjectId;
|
||||||
}
|
}
|
||||||
|
|
||||||
get detailData() {
|
get detailData() {
|
||||||
|
@ -271,8 +271,13 @@ export default class BaseList extends React.Component {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get currentUser() {
|
||||||
|
const { user } = this.props.rootStore || {};
|
||||||
|
return user || {};
|
||||||
|
}
|
||||||
|
|
||||||
get currentProjectId() {
|
get currentProjectId() {
|
||||||
return globals.user.project.id;
|
return this.props.rootStore.projectId;
|
||||||
}
|
}
|
||||||
|
|
||||||
get fetchDataByCurrentProject() {
|
get fetchDataByCurrentProject() {
|
||||||
@ -480,7 +485,7 @@ export default class BaseList extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getDataWithPolicy(params) {
|
getDataWithPolicy(params) {
|
||||||
if (!globals.user) {
|
if (!this.currentUser || isEmpty(this.currentUser)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (this.endpointError) {
|
if (this.endpointError) {
|
||||||
@ -510,7 +515,7 @@ export default class BaseList extends React.Component {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.log('fetch list error', e);
|
console.log('fetch list error', e);
|
||||||
const { message = '', data, status } = e || {};
|
const { message = '', data, status } = e.response || e || {};
|
||||||
if (status === 500) {
|
if (status === 500) {
|
||||||
const sysErr = t('System is error, please try again later.');
|
const sysErr = t('System is error, please try again later.');
|
||||||
const title = `${t('Get {name} error.', {
|
const title = `${t('Get {name} error.', {
|
||||||
@ -520,7 +525,7 @@ export default class BaseList extends React.Component {
|
|||||||
} else {
|
} else {
|
||||||
const error = {
|
const error = {
|
||||||
message: data || message || e || '',
|
message: data || message || e || '',
|
||||||
status: e.status,
|
status,
|
||||||
};
|
};
|
||||||
Notify.errorWithDetail(
|
Notify.errorWithDetail(
|
||||||
error,
|
error,
|
||||||
|
@ -245,12 +245,8 @@ export default class DetailBase extends React.Component {
|
|||||||
catch = (e) => {
|
catch = (e) => {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.log(e);
|
console.log(e);
|
||||||
if (
|
const { data, status } = e.response || e || {};
|
||||||
e.code === 404 ||
|
if (status === 404) {
|
||||||
e.status === 404 ||
|
|
||||||
e.reason === 'NotFound' ||
|
|
||||||
e.reason === 'Not Found'
|
|
||||||
) {
|
|
||||||
this.setState({ notFound: true });
|
this.setState({ notFound: true });
|
||||||
Notify.warn(
|
Notify.warn(
|
||||||
t('{name} {id} could not be found.', {
|
t('{name} {id} could not be found.', {
|
||||||
@ -260,8 +256,8 @@ export default class DetailBase extends React.Component {
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
const error = {
|
const error = {
|
||||||
message: e,
|
message: data,
|
||||||
status: e.code || e.status,
|
status,
|
||||||
};
|
};
|
||||||
Notify.errorWithDetail(
|
Notify.errorWithDetail(
|
||||||
error,
|
error,
|
||||||
|
@ -21,34 +21,13 @@ import { ConfigProvider } from 'antd';
|
|||||||
import zhCN from 'antd/es/locale/zh_CN';
|
import zhCN from 'antd/es/locale/zh_CN';
|
||||||
import enUS from 'antd/es/locale/en_US';
|
import enUS from 'antd/es/locale/en_US';
|
||||||
import globalRootStore from 'stores/root';
|
import globalRootStore from 'stores/root';
|
||||||
import request from 'utils/request';
|
|
||||||
import PageLoading from 'components/PageLoading';
|
import PageLoading from 'components/PageLoading';
|
||||||
import i18n from './i18n';
|
import i18n from './i18n';
|
||||||
import App from './App';
|
import App from './App';
|
||||||
|
|
||||||
window.t = i18n.t;
|
window.t = i18n.t;
|
||||||
window.request = request;
|
|
||||||
window.globals = {
|
|
||||||
user: null,
|
|
||||||
};
|
|
||||||
|
|
||||||
const store = globalRootStore;
|
const store = globalRootStore;
|
||||||
|
|
||||||
// request error handler
|
|
||||||
window.onunhandledrejection = function (e) {
|
|
||||||
if (e && (e.status === 'Failure' || e.status >= 400)) {
|
|
||||||
if (e.status === 401) {
|
|
||||||
// session timeout handler, except app store page.
|
|
||||||
/* eslint-disable no-alert */
|
|
||||||
const currentPath = window.location.pathname;
|
|
||||||
if (currentPath.indexOf('login') < 0) {
|
|
||||||
store.gotoLoginPage(currentPath);
|
|
||||||
// window.location.href = `/user/login?referer=${currentPath}`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const browserHistory = createBrowserHistory();
|
const browserHistory = createBrowserHistory();
|
||||||
const history = syncHistoryWithStore(browserHistory, store.routing);
|
const history = syncHistoryWithStore(browserHistory, store.routing);
|
||||||
const lang = i18n.getLocale();
|
const lang = i18n.getLocale();
|
||||||
|
@ -61,6 +61,10 @@ class BaseLayout extends Component {
|
|||||||
return this.user && this.rootStore.hasAdminRole;
|
return this.user && this.rootStore.hasAdminRole;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get hasAdminPageRole() {
|
||||||
|
return this.user && this.rootStore.hasAdminPageRole;
|
||||||
|
}
|
||||||
|
|
||||||
get originMenu() {
|
get originMenu() {
|
||||||
if (this.isAdminPage) {
|
if (this.isAdminPage) {
|
||||||
return renderAdminMenu(i18n.t);
|
return renderAdminMenu(i18n.t);
|
||||||
|
@ -71,7 +71,7 @@ const renderMenu = (t) => {
|
|||||||
level: 2,
|
level: 2,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: /^\/compute\/flavor-admin\/detail\/.[^/]+$/,
|
path: /^\/compute\/flavor-admin\/detail\/[^/]+$/,
|
||||||
name: t('Flavor Detail'),
|
name: t('Flavor Detail'),
|
||||||
key: 'flavor-detail',
|
key: 'flavor-detail',
|
||||||
level: 2,
|
level: 2,
|
||||||
|
@ -236,7 +236,6 @@
|
|||||||
"Clear Gateway": "Clear Gateway",
|
"Clear Gateway": "Clear Gateway",
|
||||||
"Click here for filters.": "Click here for filters.",
|
"Click here for filters.": "Click here for filters.",
|
||||||
"Click to Upload": "Click to Upload",
|
"Click to Upload": "Click to Upload",
|
||||||
"Click to see": "Click to see",
|
|
||||||
"Click to show detail": "Click to show detail",
|
"Click to show detail": "Click to show detail",
|
||||||
"Clone Volume": "Clone Volume",
|
"Clone Volume": "Clone Volume",
|
||||||
"Clone volume": "Clone volume",
|
"Clone volume": "Clone volume",
|
||||||
@ -1159,7 +1158,6 @@
|
|||||||
"Please select!": "Please select!",
|
"Please select!": "Please select!",
|
||||||
"Please set CPU && Ram first.": "Please set CPU && Ram first.",
|
"Please set CPU && Ram first.": "Please set CPU && Ram first.",
|
||||||
"Please set MUNA": "Please set MUNA",
|
"Please set MUNA": "Please set MUNA",
|
||||||
"Please set expiration time": "Please set expiration time",
|
|
||||||
"Pleasse input a valid ip!": "Pleasse input a valid ip!",
|
"Pleasse input a valid ip!": "Pleasse input a valid ip!",
|
||||||
"Pleasse select a network!": "Pleasse select a network!",
|
"Pleasse select a network!": "Pleasse select a network!",
|
||||||
"Pleasse select a subnet!": "Pleasse select a subnet!",
|
"Pleasse select a subnet!": "Pleasse select a subnet!",
|
||||||
@ -1509,7 +1507,6 @@
|
|||||||
"The current operation requires the instance to be shut down:": "The current operation requires the instance to be shut down:",
|
"The current operation requires the instance to be shut down:": "The current operation requires the instance to be shut down:",
|
||||||
"The description can be up to 255 characters long.": "The description can be up to 255 characters long.",
|
"The description can be up to 255 characters long.": "The description can be up to 255 characters long.",
|
||||||
"The entire inspection process takes 5 to 10 minutes, so you need to be patient. After the registration is completed, the node configuration status will return to the manageable status.": "The entire inspection process takes 5 to 10 minutes, so you need to be patient. After the registration is completed, the node configuration status will return to the manageable status.",
|
"The entire inspection process takes 5 to 10 minutes, so you need to be patient. After the registration is completed, the node configuration status will return to the manageable status.": "The entire inspection process takes 5 to 10 minutes, so you need to be patient. After the registration is completed, the node configuration status will return to the manageable status.",
|
||||||
"The expiration time needs to be greater than the current time.": "The expiration time needs to be greater than the current time.",
|
|
||||||
"The feasible configuration of cloud-init or cloudbase-init service in the image is not synced to image's properties, so the Login Name is unknown.": "The feasible configuration of cloud-init or cloudbase-init service in the image is not synced to image's properties, so the Login Name is unknown.",
|
"The feasible configuration of cloud-init or cloudbase-init service in the image is not synced to image's properties, so the Login Name is unknown.": "The feasible configuration of cloud-init or cloudbase-init service in the image is not synced to image's properties, so the Login Name is unknown.",
|
||||||
"The instance": "The instance",
|
"The instance": "The instance",
|
||||||
"The instance architecture diagram mainly shows the overall architecture composition of the instance. If you need to view the network topology of the instance, please go to: ": "The instance architecture diagram mainly shows the overall architecture composition of the instance. If you need to view the network topology of the instance, please go to: ",
|
"The instance architecture diagram mainly shows the overall architecture composition of the instance. If you need to view the network topology of the instance, please go to: ": "The instance architecture diagram mainly shows the overall architecture composition of the instance. If you need to view the network topology of the instance, please go to: ",
|
||||||
@ -1549,6 +1546,7 @@
|
|||||||
"The timeout period of waiting for the return of the health check request, the check timeout will be judged as a check failure": "The timeout period of waiting for the return of the health check request, the check timeout will be judged as a check failure",
|
"The timeout period of waiting for the return of the health check request, the check timeout will be judged as a check failure": "The timeout period of waiting for the return of the health check request, the check timeout will be judged as a check failure",
|
||||||
"The trait name of the flavor needs to correspond to the trait of the scheduling node; by injecting the necessary traits into the ironic instance, the computing service will only schedule the instance to the bare metal node with all necessary traits (for example: the trait of the scheduling node has HW_CPU_X86_VMX trait, and the flavor adds HW_CPU_X86_VMX, it can be scheduled to this node for necessary traits).": "The trait name of the flavor needs to correspond to the trait of the scheduling node; by injecting the necessary traits into the ironic instance, the computing service will only schedule the instance to the bare metal node with all necessary traits (for example: the trait of the scheduling node has HW_CPU_X86_VMX trait, and the flavor adds HW_CPU_X86_VMX, it can be scheduled to this node for necessary traits).",
|
"The trait name of the flavor needs to correspond to the trait of the scheduling node; by injecting the necessary traits into the ironic instance, the computing service will only schedule the instance to the bare metal node with all necessary traits (for example: the trait of the scheduling node has HW_CPU_X86_VMX trait, and the flavor adds HW_CPU_X86_VMX, it can be scheduled to this node for necessary traits).": "The trait name of the flavor needs to correspond to the trait of the scheduling node; by injecting the necessary traits into the ironic instance, the computing service will only schedule the instance to the bare metal node with all necessary traits (for example: the trait of the scheduling node has HW_CPU_X86_VMX trait, and the flavor adds HW_CPU_X86_VMX, it can be scheduled to this node for necessary traits).",
|
||||||
"The trait of the scheduled node needs to correspond to the trait of the flavor used by the ironic instance; by injecting the necessary traits into the ironic instance, the computing service will only schedule the instance to the bare metal node with all the necessary traits (for example, the ironic instance which use the flavor that has HW_CPU_X86_VMX as a necessary trait, can be scheduled to the node which has the trait of HW_CPU_X86_VMX).": "The trait of the scheduled node needs to correspond to the trait of the flavor used by the ironic instance; by injecting the necessary traits into the ironic instance, the computing service will only schedule the instance to the bare metal node with all the necessary traits (for example, the ironic instance which use the flavor that has HW_CPU_X86_VMX as a necessary trait, can be scheduled to the node which has the trait of HW_CPU_X86_VMX).",
|
"The trait of the scheduled node needs to correspond to the trait of the flavor used by the ironic instance; by injecting the necessary traits into the ironic instance, the computing service will only schedule the instance to the bare metal node with all the necessary traits (for example, the ironic instance which use the flavor that has HW_CPU_X86_VMX as a necessary trait, can be scheduled to the node which has the trait of HW_CPU_X86_VMX).": "The trait of the scheduled node needs to correspond to the trait of the flavor used by the ironic instance; by injecting the necessary traits into the ironic instance, the computing service will only schedule the instance to the bare metal node with all the necessary traits (for example, the ironic instance which use the flavor that has HW_CPU_X86_VMX as a necessary trait, can be scheduled to the node which has the trait of HW_CPU_X86_VMX).",
|
||||||
|
"The user has been disabled, please contact the administrator": "The user has been disabled, please contact the administrator",
|
||||||
"The user needs to ensure that the input is a shell script that can run completely and normally.": "The user needs to ensure that the input is a shell script that can run completely and normally.",
|
"The user needs to ensure that the input is a shell script that can run completely and normally.": "The user needs to ensure that the input is a shell script that can run completely and normally.",
|
||||||
"The volume associated with the backup is not available, unable to restore.": "The volume associated with the backup is not available, unable to restore.",
|
"The volume associated with the backup is not available, unable to restore.": "The volume associated with the backup is not available, unable to restore.",
|
||||||
"The volume type needs to set \"multiattach\" in the metadata to support shared volume attributes.": "The volume type needs to set \"multiattach\" in the metadata to support shared volume attributes.",
|
"The volume type needs to set \"multiattach\" in the metadata to support shared volume attributes.": "The volume type needs to set \"multiattach\" in the metadata to support shared volume attributes.",
|
||||||
|
@ -236,7 +236,6 @@
|
|||||||
"Clear Gateway": "",
|
"Clear Gateway": "",
|
||||||
"Click here for filters.": "筛选",
|
"Click here for filters.": "筛选",
|
||||||
"Click to Upload": "点击上传文件",
|
"Click to Upload": "点击上传文件",
|
||||||
"Click to see": "点击查看",
|
|
||||||
"Click to show detail": "点击查看详情",
|
"Click to show detail": "点击查看详情",
|
||||||
"Clone Volume": "克隆云硬盘",
|
"Clone Volume": "克隆云硬盘",
|
||||||
"Clone volume": "克隆云硬盘",
|
"Clone volume": "克隆云硬盘",
|
||||||
@ -1159,7 +1158,6 @@
|
|||||||
"Please select!": "请选择!",
|
"Please select!": "请选择!",
|
||||||
"Please set CPU && Ram first.": "请先设置CPU、内存。",
|
"Please set CPU && Ram first.": "请先设置CPU、内存。",
|
||||||
"Please set MUNA": "请设置NUMA节点",
|
"Please set MUNA": "请设置NUMA节点",
|
||||||
"Please set expiration time": "请设置到期时间",
|
|
||||||
"Pleasse input a valid ip!": "请输入正确的IP地址",
|
"Pleasse input a valid ip!": "请输入正确的IP地址",
|
||||||
"Pleasse select a network!": "请选择网络!",
|
"Pleasse select a network!": "请选择网络!",
|
||||||
"Pleasse select a subnet!": "请选择子网!",
|
"Pleasse select a subnet!": "请选择子网!",
|
||||||
@ -1509,7 +1507,6 @@
|
|||||||
"The current operation requires the instance to be shut down:": "当前操作需要云主机在关机状态下进行:",
|
"The current operation requires the instance to be shut down:": "当前操作需要云主机在关机状态下进行:",
|
||||||
"The description can be up to 255 characters long.": "描述最长为255字符",
|
"The description can be up to 255 characters long.": "描述最长为255字符",
|
||||||
"The entire inspection process takes 5 to 10 minutes, so you need to be patient. After the registration is completed, the node configuration status will return to the manageable status.": "检查的整个过程需要耗费 5 到 10 分钟时间,您需要耐心等待。在完成注册后,节点配置状态会重新回到可管理状态。",
|
"The entire inspection process takes 5 to 10 minutes, so you need to be patient. After the registration is completed, the node configuration status will return to the manageable status.": "检查的整个过程需要耗费 5 到 10 分钟时间,您需要耐心等待。在完成注册后,节点配置状态会重新回到可管理状态。",
|
||||||
"The expiration time needs to be greater than the current time.": "到期时间需要大于当前时间。",
|
|
||||||
"The feasible configuration of cloud-init or cloudbase-init service in the image is not synced to image's properties, so the Login Name is unknown.": "镜像中的cloud-init或cloudbase-init服务的预制配置未同步至镜像属性, 登录名未知",
|
"The feasible configuration of cloud-init or cloudbase-init service in the image is not synced to image's properties, so the Login Name is unknown.": "镜像中的cloud-init或cloudbase-init服务的预制配置未同步至镜像属性, 登录名未知",
|
||||||
"The instance": "云主机",
|
"The instance": "云主机",
|
||||||
"The instance architecture diagram mainly shows the overall architecture composition of the instance. If you need to view the network topology of the instance, please go to: ": "云主机架构图主要展示云主机的总体架构组成。如果需要查看云主机的网络拓扑,请转到:",
|
"The instance architecture diagram mainly shows the overall architecture composition of the instance. If you need to view the network topology of the instance, please go to: ": "云主机架构图主要展示云主机的总体架构组成。如果需要查看云主机的网络拓扑,请转到:",
|
||||||
@ -1549,6 +1546,7 @@
|
|||||||
"The timeout period of waiting for the return of the health check request, the check timeout will be judged as a check failure": "等待健康检查请求返回的超时时间,检查超时将会被判定为一次检查失败",
|
"The timeout period of waiting for the return of the health check request, the check timeout will be judged as a check failure": "等待健康检查请求返回的超时时间,检查超时将会被判定为一次检查失败",
|
||||||
"The trait name of the flavor needs to correspond to the trait of the scheduling node; by injecting the necessary traits into the ironic instance, the computing service will only schedule the instance to the bare metal node with all necessary traits (for example: the trait of the scheduling node has HW_CPU_X86_VMX trait, and the flavor adds HW_CPU_X86_VMX, it can be scheduled to this node for necessary traits).": "云主机类型的特性名称需要与调度节点的特性对应;通过给裸机实例注入必需特性,计算服务将只调度实例到具有所有必需特性的裸金属节点(比如:调度节点的有 HW_CPU_X86_VMX的特性,云主机类型添加HW_CPU_X86_VMX为必需特性,可以调度到此节点)。",
|
"The trait name of the flavor needs to correspond to the trait of the scheduling node; by injecting the necessary traits into the ironic instance, the computing service will only schedule the instance to the bare metal node with all necessary traits (for example: the trait of the scheduling node has HW_CPU_X86_VMX trait, and the flavor adds HW_CPU_X86_VMX, it can be scheduled to this node for necessary traits).": "云主机类型的特性名称需要与调度节点的特性对应;通过给裸机实例注入必需特性,计算服务将只调度实例到具有所有必需特性的裸金属节点(比如:调度节点的有 HW_CPU_X86_VMX的特性,云主机类型添加HW_CPU_X86_VMX为必需特性,可以调度到此节点)。",
|
||||||
"The trait of the scheduled node needs to correspond to the trait of the flavor used by the ironic instance; by injecting the necessary traits into the ironic instance, the computing service will only schedule the instance to the bare metal node with all the necessary traits (for example, the ironic instance which use the flavor that has HW_CPU_X86_VMX as a necessary trait, can be scheduled to the node which has the trait of HW_CPU_X86_VMX).": "被调度节点的特性需要与裸机实例使用的云主机类型的特性对应;通过给裸机实例注入必需特性,计算服务将只调度实例到具有所有必需特性的裸金属节点(比如:调度节点的有 HW_CPU_X86_VMX的特性, 云主机类型添加HW_CPU_X86_VMX为必要特性,可以调度到此节点)。",
|
"The trait of the scheduled node needs to correspond to the trait of the flavor used by the ironic instance; by injecting the necessary traits into the ironic instance, the computing service will only schedule the instance to the bare metal node with all the necessary traits (for example, the ironic instance which use the flavor that has HW_CPU_X86_VMX as a necessary trait, can be scheduled to the node which has the trait of HW_CPU_X86_VMX).": "被调度节点的特性需要与裸机实例使用的云主机类型的特性对应;通过给裸机实例注入必需特性,计算服务将只调度实例到具有所有必需特性的裸金属节点(比如:调度节点的有 HW_CPU_X86_VMX的特性, 云主机类型添加HW_CPU_X86_VMX为必要特性,可以调度到此节点)。",
|
||||||
|
"The user has been disabled, please contact the administrator": "",
|
||||||
"The user needs to ensure that the input is a shell script that can run completely and normally.": "请确保输入的是能完整正常运行的 shell 脚本。",
|
"The user needs to ensure that the input is a shell script that can run completely and normally.": "请确保输入的是能完整正常运行的 shell 脚本。",
|
||||||
"The volume associated with the backup is not available, unable to restore.": "云硬盘不处于可用状态,不支持恢复备份操作。",
|
"The volume associated with the backup is not available, unable to restore.": "云硬盘不处于可用状态,不支持恢复备份操作。",
|
||||||
"The volume type needs to set \"multiattach\" in the metadata to support shared volume attributes.": "云硬盘类型需在元数据中设置\"multiattach\",才可支持共享盘属性。",
|
"The volume type needs to set \"multiattach\" in the metadata to support shared volume attributes.": "云硬盘类型需在元数据中设置\"multiattach\",才可支持共享盘属性。",
|
||||||
|
@ -20,6 +20,7 @@ import { InfoCircleFilled } from '@ant-design/icons';
|
|||||||
import SimpleForm from 'components/SimpleForm';
|
import SimpleForm from 'components/SimpleForm';
|
||||||
import globalSkylineStore from 'stores/skyline/skyline';
|
import globalSkylineStore from 'stores/skyline/skyline';
|
||||||
import i18n from 'core/i18n';
|
import i18n from 'core/i18n';
|
||||||
|
import { isEmpty } from 'lodash';
|
||||||
import styles from './index.less';
|
import styles from './index.less';
|
||||||
|
|
||||||
@inject('rootStore')
|
@inject('rootStore')
|
||||||
@ -189,13 +190,15 @@ export default class Login extends Component {
|
|||||||
this.setState({
|
this.setState({
|
||||||
loading: true,
|
loading: true,
|
||||||
});
|
});
|
||||||
this.rootStore.login(values).then(
|
const { domain, password, region, username } = values;
|
||||||
|
const body = { domain, password, region, username };
|
||||||
|
this.rootStore.login(body).then(
|
||||||
() => {
|
() => {
|
||||||
this.setState({
|
this.setState({
|
||||||
loading: false,
|
loading: false,
|
||||||
error: false,
|
error: false,
|
||||||
});
|
});
|
||||||
if (globals.user) {
|
if (this.rootStore.user && !isEmpty(this.rootStore.user)) {
|
||||||
this.rootStore.routing.push(this.nextPage);
|
this.rootStore.routing.push(this.nextPage);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -205,7 +208,7 @@ export default class Login extends Component {
|
|||||||
});
|
});
|
||||||
const {
|
const {
|
||||||
data: { detail },
|
data: { detail },
|
||||||
} = error;
|
} = error.response;
|
||||||
if (
|
if (
|
||||||
detail.indexOf(
|
detail.indexOf(
|
||||||
'The password is expired and needs to be changed for user'
|
'The password is expired and needs to be changed for user'
|
||||||
@ -240,13 +243,16 @@ export default class Login extends Component {
|
|||||||
|
|
||||||
getErrorMessage() {
|
getErrorMessage() {
|
||||||
const { message } = this.state;
|
const { message } = this.state;
|
||||||
if (message.indexOf('The account is locked for user') >= 0) {
|
if (message.includes('The account is locked for user')) {
|
||||||
return t(
|
return t(
|
||||||
'Frequent login failure will cause the account to be temporarily locked, please operate after 5 minutes'
|
'Frequent login failure will cause the account to be temporarily locked, please operate after 5 minutes'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if (message.includes('The account is disabled for user')) {
|
||||||
|
return t('The user has been disabled, please contact the administrator');
|
||||||
|
}
|
||||||
if (
|
if (
|
||||||
message.indexOf('You are not authorized for any projects or domains') >= 0
|
message.includes('You are not authorized for any projects or domains')
|
||||||
) {
|
) {
|
||||||
return t(
|
return t(
|
||||||
'If you are not authorized to access any project, or if the project you are involved in has been deleted or disabled, contact the platform administrator to reassign the project'
|
'If you are not authorized to access any project, or if the project you are involved in has been deleted or disabled, contact the platform administrator to reassign the project'
|
||||||
|
@ -23,7 +23,8 @@ import styles from '../style.less';
|
|||||||
@observer
|
@observer
|
||||||
class ResourceStatistic extends Component {
|
class ResourceStatistic extends Component {
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
const { project: { id: project_id } = {} } = globals.user || {};
|
const { user } = this.props.rootStore || {};
|
||||||
|
const { project: { id: project_id } = {} } = user || {};
|
||||||
this.props.store.getResourceStatisticData(project_id);
|
this.props.store.getResourceStatisticData(project_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,7 +16,7 @@ import { observer, inject } from 'mobx-react';
|
|||||||
import Base from 'containers/List';
|
import Base from 'containers/List';
|
||||||
import globalIronicStore from 'stores/ironic/ironic';
|
import globalIronicStore from 'stores/ironic/ironic';
|
||||||
import { powerState, provisioningState } from 'resources/ironic';
|
import { powerState, provisioningState } from 'resources/ironic';
|
||||||
import { ironicOriginEndpoint } from 'utils/constants';
|
import { ironicOriginEndpoint } from 'client/client/constants';
|
||||||
import actionConfigs from './actions';
|
import actionConfigs from './actions';
|
||||||
|
|
||||||
@inject('rootStore')
|
@inject('rootStore')
|
||||||
|
@ -16,8 +16,6 @@ import { inject, observer } from 'mobx-react';
|
|||||||
import { HypervisorStore } from 'stores/nova/hypervisor';
|
import { HypervisorStore } from 'stores/nova/hypervisor';
|
||||||
import Base from 'containers/TabDetail';
|
import Base from 'containers/TabDetail';
|
||||||
import Members from 'pages/compute/containers/Instance';
|
import Members from 'pages/compute/containers/Instance';
|
||||||
import Link from 'react-router-dom/Link';
|
|
||||||
import React from 'react';
|
|
||||||
|
|
||||||
@inject('rootStore')
|
@inject('rootStore')
|
||||||
@observer
|
@observer
|
||||||
@ -55,15 +53,6 @@ export default class HypervisorDetail extends Base {
|
|||||||
render: (value, record) =>
|
render: (value, record) =>
|
||||||
`${record.memory_mb_used} / ${record.memory_mb}`,
|
`${record.memory_mb_used} / ${record.memory_mb}`,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
title: t('Used Local Storage (GB)'),
|
|
||||||
dataIndex: 'storage_percent',
|
|
||||||
render: () => (
|
|
||||||
<Link to="/monitor-center/storage-cluster-admin">
|
|
||||||
{t('Click to see')}
|
|
||||||
</Link>
|
|
||||||
),
|
|
||||||
},
|
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,10 +33,6 @@ export default class SystemStep extends Base {
|
|||||||
return 'SystemStep';
|
return 'SystemStep';
|
||||||
}
|
}
|
||||||
|
|
||||||
get hasAdminRole() {
|
|
||||||
return globals.user.hasAdminRole;
|
|
||||||
}
|
|
||||||
|
|
||||||
get keypairs() {
|
get keypairs() {
|
||||||
return (this.keyPairStore.list.data || []).map((it) => ({
|
return (this.keyPairStore.list.data || []).map((it) => ({
|
||||||
...it,
|
...it,
|
||||||
|
@ -22,7 +22,7 @@ import globalProjectStore from 'stores/keystone/project';
|
|||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
import { isEmpty, isFinite } from 'lodash';
|
import { isEmpty, isFinite } from 'lodash';
|
||||||
import { getUserData, canCreateIronicByLicense } from 'resources/instance';
|
import { getUserData, canCreateIronicByLicense } from 'resources/instance';
|
||||||
import { ironicOriginEndpoint } from 'utils/constants';
|
import { ironicOriginEndpoint } from 'client/client/constants';
|
||||||
import styles from './index.less';
|
import styles from './index.less';
|
||||||
import ConfirmStep from './ConfirmStep';
|
import ConfirmStep from './ConfirmStep';
|
||||||
import SystemStep from './SystemStep';
|
import SystemStep from './SystemStep';
|
||||||
@ -68,9 +68,8 @@ export default class CreateIronic extends StepAction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async getQuota() {
|
async getQuota() {
|
||||||
const { project: { id: project_id } = {} } = globals.user || {};
|
|
||||||
await this.projectStore.fetchProjectQuota({
|
await this.projectStore.fetchProjectQuota({
|
||||||
project_id,
|
project_id: this.currentProjectId,
|
||||||
});
|
});
|
||||||
this.onCountChange(1);
|
this.onCountChange(1);
|
||||||
}
|
}
|
||||||
|
@ -44,10 +44,6 @@ export default class SystemStep extends Base {
|
|||||||
return 'SystemStep';
|
return 'SystemStep';
|
||||||
}
|
}
|
||||||
|
|
||||||
get hasAdminRole() {
|
|
||||||
return globals.user.hasAdminRole;
|
|
||||||
}
|
|
||||||
|
|
||||||
get keypairs() {
|
get keypairs() {
|
||||||
return (this.keyPairStore.list.data || []).map((it) => ({
|
return (this.keyPairStore.list.data || []).map((it) => ({
|
||||||
...it,
|
...it,
|
||||||
|
@ -63,9 +63,8 @@ class StepCreate extends StepAction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async getQuota() {
|
async getQuota() {
|
||||||
const { project: { id: project_id } = {} } = globals.user || {};
|
|
||||||
await this.projectStore.fetchProjectQuota({
|
await this.projectStore.fetchProjectQuota({
|
||||||
project_id,
|
project_id: this.currentProjectId,
|
||||||
});
|
});
|
||||||
this.onCountChange(1);
|
this.onCountChange(1);
|
||||||
}
|
}
|
||||||
|
@ -36,26 +36,15 @@ export default class PortForwarding extends Base {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateFetchParamsByPage = (params) => {
|
updateFetchParams = (params) => {
|
||||||
const { id, ...rest } = params;
|
const { id, all_projects, ...rest } = params;
|
||||||
return {
|
return {
|
||||||
fipID: id,
|
fipID: id,
|
||||||
|
fipInfo: this.props.detail,
|
||||||
...rest,
|
...rest,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
fetchDataByPage = async (params) => {
|
|
||||||
await this.store.getFipAlreadyUsedPorts(params);
|
|
||||||
this.updateList({
|
|
||||||
data: this.store.list.data.map((i) => {
|
|
||||||
i.fip = this.props.detail;
|
|
||||||
i.floating_ip_address = this.props.detail.floating_ip_address;
|
|
||||||
return i;
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
this.list.silent = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
get actionConfigs() {
|
get actionConfigs() {
|
||||||
return this.isAdminPage
|
return this.isAdminPage
|
||||||
? actionConfigs.actionConfigsAdmin
|
? actionConfigs.actionConfigsAdmin
|
||||||
|
@ -147,7 +147,11 @@ export default class FloatingIps extends Base {
|
|||||||
title: t('Associated Resource'),
|
title: t('Associated Resource'),
|
||||||
dataIndex: 'resource_name',
|
dataIndex: 'resource_name',
|
||||||
render: (resource_name, record) => {
|
render: (resource_name, record) => {
|
||||||
if (!resource_name && record.port_forwardings.length !== 0) {
|
if (
|
||||||
|
!resource_name &&
|
||||||
|
record.port_forwardings &&
|
||||||
|
record.port_forwardings.length !== 0
|
||||||
|
) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{t('{number} port forwarding rules', {
|
{t('{number} port forwarding rules', {
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
import { inject, observer } from 'mobx-react';
|
import { inject, observer } from 'mobx-react';
|
||||||
import Base from 'containers/List';
|
import Base from 'containers/List';
|
||||||
import { LbaasStore } from 'stores/octavia/loadbalancer';
|
import { LbaasStore } from 'stores/octavia/loadbalancer';
|
||||||
import { lbEndpoint } from 'utils/constants';
|
import { lbEndpoint } from 'client/client/constants';
|
||||||
import { actionConfigs, adminActions } from './actions';
|
import { actionConfigs, adminActions } from './actions';
|
||||||
|
|
||||||
@inject('rootStore')
|
@inject('rootStore')
|
||||||
|
@ -30,10 +30,6 @@ export default class QoSPolicy extends Base {
|
|||||||
return 'get_policy';
|
return 'get_policy';
|
||||||
}
|
}
|
||||||
|
|
||||||
get module() {
|
|
||||||
return 'qos_policies';
|
|
||||||
}
|
|
||||||
|
|
||||||
get name() {
|
get name() {
|
||||||
return t('QoS policies');
|
return t('QoS policies');
|
||||||
}
|
}
|
||||||
|
@ -35,10 +35,6 @@ export default class QoSPolicy extends Base {
|
|||||||
return 'get_policy';
|
return 'get_policy';
|
||||||
}
|
}
|
||||||
|
|
||||||
get module() {
|
|
||||||
return 'qos_policies';
|
|
||||||
}
|
|
||||||
|
|
||||||
get name() {
|
get name() {
|
||||||
return t('QoS policies');
|
return t('QoS policies');
|
||||||
}
|
}
|
||||||
|
@ -35,10 +35,6 @@ export default class QoSPolicy extends Base {
|
|||||||
return 'get_policy';
|
return 'get_policy';
|
||||||
}
|
}
|
||||||
|
|
||||||
get module() {
|
|
||||||
return 'qos_policies';
|
|
||||||
}
|
|
||||||
|
|
||||||
get name() {
|
get name() {
|
||||||
return t('QoS policies');
|
return t('QoS policies');
|
||||||
}
|
}
|
||||||
|
@ -68,7 +68,7 @@ export default class AssociateFip extends ModalAction {
|
|||||||
} = this.item;
|
} = this.item;
|
||||||
this.floatingIpStore.fetchList({
|
this.floatingIpStore.fetchList({
|
||||||
floating_network_id: network_id,
|
floating_network_id: network_id,
|
||||||
project_id: globals.user.project.id,
|
project_id: this.currentProjectId,
|
||||||
status: 'DOWN',
|
status: 'DOWN',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
import { observer, inject } from 'mobx-react';
|
import { observer, inject } from 'mobx-react';
|
||||||
import Base from 'containers/TabList';
|
import Base from 'containers/TabList';
|
||||||
import { vpnEndpoint } from 'utils/constants';
|
import { vpnEndpoint } from 'client/client/constants';
|
||||||
import VPNGateway from './VPNGateway';
|
import VPNGateway from './VPNGateway';
|
||||||
import EndPointGroup from './EndpointGroup';
|
import EndPointGroup from './EndpointGroup';
|
||||||
import IKEPolicy from './IKEPolicy';
|
import IKEPolicy from './IKEPolicy';
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ImageType from 'components/ImageType';
|
import ImageType from 'components/ImageType';
|
||||||
import { get } from 'lodash';
|
import { get } from 'lodash';
|
||||||
|
import globalRootStore from 'stores/root';
|
||||||
|
|
||||||
export const imageStatus = {
|
export const imageStatus = {
|
||||||
active: t('Active'),
|
active: t('Active'),
|
||||||
@ -99,21 +100,14 @@ export const imageProperties = {
|
|||||||
export const transitionStatusList = ['saving', 'queued', 'pending_delete'];
|
export const transitionStatusList = ['saving', 'queued', 'pending_delete'];
|
||||||
|
|
||||||
export const isOwnerOrAdmin = (item) => {
|
export const isOwnerOrAdmin = (item) => {
|
||||||
const {
|
if (globalRootStore.projectId === item.owner) {
|
||||||
project: { id },
|
|
||||||
hasAdminRole,
|
|
||||||
} = globals.user;
|
|
||||||
if (id === item.owner) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return hasAdminRole;
|
return globalRootStore.hasAdminRole;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const isOwner = (item) => {
|
export const isOwner = (item) => {
|
||||||
const {
|
if (globalRootStore.projectId === item.owner) {
|
||||||
project: { id },
|
|
||||||
} = globals.user;
|
|
||||||
if (id === item.owner) {
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -13,10 +13,8 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import moment from 'moment';
|
|
||||||
import ImageType from 'components/ImageType';
|
import ImageType from 'components/ImageType';
|
||||||
import globalRootStore from 'stores/root';
|
import globalRootStore from 'stores/root';
|
||||||
import { getLocalTimeStr, timeFormatStr } from 'utils/time';
|
|
||||||
|
|
||||||
import lockSvg from 'src/asset/image/lock.svg';
|
import lockSvg from 'src/asset/image/lock.svg';
|
||||||
import unlockSvg from 'src/asset/image/unlock.svg';
|
import unlockSvg from 'src/asset/image/unlock.svg';
|
||||||
@ -263,53 +261,6 @@ export const getUserData = (password, userData) => {
|
|||||||
return onlyUserData.replace(/USER_DATA/g, userData);
|
return onlyUserData.replace(/USER_DATA/g, userData);
|
||||||
};
|
};
|
||||||
|
|
||||||
function range(start, end) {
|
|
||||||
const result = [];
|
|
||||||
for (let i = start; i < end; i++) {
|
|
||||||
result.push(i);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const getExpireDateFormItem = (autoRelease) => ({
|
|
||||||
name: 'expiredTime',
|
|
||||||
label: t('Expired Time'),
|
|
||||||
type: 'date-picker',
|
|
||||||
hidden: !autoRelease,
|
|
||||||
required: autoRelease,
|
|
||||||
format: timeFormatStr.YMDHm,
|
|
||||||
showTime: {
|
|
||||||
defaultValue: getLocalTimeStr('00:00:00', 'HH:mm'),
|
|
||||||
// minuteStep: 60,
|
|
||||||
},
|
|
||||||
showNow: false,
|
|
||||||
disabledDate: (current) => current && current < moment().startOf('day'),
|
|
||||||
disabledTime: (date) => {
|
|
||||||
const currentDay = moment();
|
|
||||||
const currentHour = moment().hour();
|
|
||||||
const currentMinute = moment().minute();
|
|
||||||
const disabledMap = {};
|
|
||||||
if (moment(date).isSame(currentDay, 'day')) {
|
|
||||||
disabledMap.disabledHours = () => range(0, currentHour);
|
|
||||||
if (moment(date).isSame(currentDay, 'hour')) {
|
|
||||||
disabledMap.disabledMinutes = () => range(0, currentMinute + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return disabledMap;
|
|
||||||
},
|
|
||||||
validator: (rule, value) => {
|
|
||||||
if (!value) {
|
|
||||||
return Promise.reject(t('Please set expiration time'));
|
|
||||||
}
|
|
||||||
if (moment(value) < moment()) {
|
|
||||||
return Promise.reject(
|
|
||||||
t('The expiration time needs to be greater than the current time.')
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return Promise.resolve();
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export const getIpInitValue = (subnet) => {
|
export const getIpInitValue = (subnet) => {
|
||||||
if (!subnet) {
|
if (!subnet) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -95,3 +95,5 @@ export const getAnchorData = (num, y) => {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const isExternalNetwork = (network) => !!network['router:external'];
|
||||||
|
@ -13,12 +13,13 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { isArray, isObject, isFunction, isString, has } from 'lodash';
|
import { isArray, isObject, isFunction, isString, has } from 'lodash';
|
||||||
|
import globalRootStore from 'stores/root';
|
||||||
|
|
||||||
export const checkPolicyRule = (rule, actionName) => {
|
export const checkPolicyRule = (rule, actionName) => {
|
||||||
if (!rule) {
|
if (!rule) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
const item = globals.policies.find((it) => it.rule === rule);
|
const item = globalRootStore.policies.find((it) => it.rule === rule);
|
||||||
if (!item) {
|
if (!item) {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.log('policy rule not exit', rule, actionName);
|
console.log('policy rule not exit', rule, actionName);
|
||||||
@ -37,7 +38,7 @@ const checkPolicyRules = (rules, every, actionName) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const systemRoleIsReader = () => {
|
export const systemRoleIsReader = () => {
|
||||||
const { user: { roles = [] } = {} } = globals || {};
|
const { roles = [] } = globalRootStore.user || {};
|
||||||
const readerRole = 'system_reader';
|
const readerRole = 'system_reader';
|
||||||
const adminRoles = ['system_admin', 'admin'];
|
const adminRoles = ['system_admin', 'admin'];
|
||||||
const hasReaderRole = roles.some((it) => it.name === readerRole);
|
const hasReaderRole = roles.some((it) => it.name === readerRole);
|
||||||
@ -55,9 +56,11 @@ const checkItemPolicy = ({
|
|||||||
isAdminPage,
|
isAdminPage,
|
||||||
enableSystemReader,
|
enableSystemReader,
|
||||||
}) => {
|
}) => {
|
||||||
if (globals.policies.length === 0) {
|
if (globalRootStore.policies.length === 0) {
|
||||||
// TODO: change to false
|
return false;
|
||||||
return true;
|
}
|
||||||
|
if (isAdminPage && !enableSystemReader && systemRoleIsReader()) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
if (isAdminPage && !enableSystemReader && systemRoleIsReader()) {
|
if (isAdminPage && !enableSystemReader && systemRoleIsReader()) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -12,11 +12,12 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { get, isArray } from 'lodash';
|
import { get } from 'lodash';
|
||||||
import { action, observable } from 'mobx';
|
import { action, observable } from 'mobx';
|
||||||
import { keystoneBase } from 'utils/constants';
|
import client from 'client';
|
||||||
import List from './base-list';
|
import List from './base-list';
|
||||||
import globalProjectMapStore from './project';
|
import globalProjectMapStore from './project';
|
||||||
|
import globalRootStore from './root';
|
||||||
|
|
||||||
export default class BaseStore {
|
export default class BaseStore {
|
||||||
list = new List();
|
list = new List();
|
||||||
@ -30,16 +31,16 @@ export default class BaseStore {
|
|||||||
@observable
|
@observable
|
||||||
isSubmitting = false;
|
isSubmitting = false;
|
||||||
|
|
||||||
get module() {
|
get client() {
|
||||||
return '';
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
get apiVersion() {
|
get skylineClient() {
|
||||||
return '';
|
return client.skyline;
|
||||||
}
|
}
|
||||||
|
|
||||||
get responseKey() {
|
get responseKey() {
|
||||||
return '';
|
return this.client.responseKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
get listResponseKey() {
|
get listResponseKey() {
|
||||||
@ -50,6 +51,22 @@ export default class BaseStore {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get currentUser() {
|
||||||
|
return globalRootStore.user || {};
|
||||||
|
}
|
||||||
|
|
||||||
|
get currentProjectId() {
|
||||||
|
return globalRootStore.projectId;
|
||||||
|
}
|
||||||
|
|
||||||
|
get hasAdminRole() {
|
||||||
|
return globalRootStore.hasAdminRole;
|
||||||
|
}
|
||||||
|
|
||||||
|
get enableBilling() {
|
||||||
|
return globalRootStore.enableBilling;
|
||||||
|
}
|
||||||
|
|
||||||
get mapper() {
|
get mapper() {
|
||||||
// update response items;
|
// update response items;
|
||||||
return (data) => data;
|
return (data) => data;
|
||||||
@ -112,7 +129,7 @@ export default class BaseStore {
|
|||||||
|
|
||||||
get paramsFuncPage() {
|
get paramsFuncPage() {
|
||||||
return (params) => {
|
return (params) => {
|
||||||
const { current, ...rest } = params;
|
const { current, withPrice, ...rest } = params;
|
||||||
return rest;
|
return rest;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -126,14 +143,39 @@ export default class BaseStore {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
get currentProject() {
|
|
||||||
return globals.user.project.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
get markerKey() {
|
get markerKey() {
|
||||||
return 'id';
|
return 'id';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get listWithDetail() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
get isSubResource() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
getFatherResourceId = (params) => params.id;
|
||||||
|
|
||||||
|
detailFetchByClient(resourceParams, params) {
|
||||||
|
const { id } = resourceParams;
|
||||||
|
if (!this.isSubResource) {
|
||||||
|
return this.client.show(id, params);
|
||||||
|
}
|
||||||
|
const fatherId = this.getFatherResourceId(resourceParams);
|
||||||
|
return this.client.show(fatherId, id, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
listFetchByClient(params, originParams) {
|
||||||
|
if (!this.isSubResource) {
|
||||||
|
return this.listWithDetail
|
||||||
|
? this.client.listDetail(params)
|
||||||
|
: this.client.list(params);
|
||||||
|
}
|
||||||
|
const fatherId = this.getFatherResourceId(originParams);
|
||||||
|
return this.client.list(fatherId, params);
|
||||||
|
}
|
||||||
|
|
||||||
getItemProjectId(item) {
|
getItemProjectId(item) {
|
||||||
return (
|
return (
|
||||||
item.project_id ||
|
item.project_id ||
|
||||||
@ -153,21 +195,13 @@ export default class BaseStore {
|
|||||||
const itemProject = globalProjectMapStore.getItemProjectId(item);
|
const itemProject = globalProjectMapStore.getItemProjectId(item);
|
||||||
const { shared, visibility, is_public } = item;
|
const { shared, visibility, is_public } = item;
|
||||||
return (
|
return (
|
||||||
itemProject === this.currentProject ||
|
itemProject === this.currentProjectId ||
|
||||||
is_public ||
|
is_public ||
|
||||||
shared ||
|
shared ||
|
||||||
visibility === 'public'
|
visibility === 'public'
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
getListUrl = () => `${this.apiVersion}/${this.module}`;
|
|
||||||
|
|
||||||
getListDetailUrl = () => '';
|
|
||||||
|
|
||||||
getListPageUrl = () => '';
|
|
||||||
|
|
||||||
getDetailUrl = ({ id }) => `${this.getListUrl()}/${id}`;
|
|
||||||
|
|
||||||
@action
|
@action
|
||||||
setModule(module) {
|
setModule(module) {
|
||||||
this.module = module;
|
this.module = module;
|
||||||
@ -188,12 +222,6 @@ export default class BaseStore {
|
|||||||
return promise;
|
return promise;
|
||||||
};
|
};
|
||||||
|
|
||||||
async fetchProjectDetail({ id }) {
|
|
||||||
return request.get(`${keystoneBase()}/projects/${id}`, {}, null, () =>
|
|
||||||
Promise.resolve('error')
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// eslint-disable-next-line no-unused-vars
|
// eslint-disable-next-line no-unused-vars
|
||||||
async listDidFetch(items, allProjects, filters) {
|
async listDidFetch(items, allProjects, filters) {
|
||||||
return items;
|
return items;
|
||||||
@ -208,7 +236,7 @@ export default class BaseStore {
|
|||||||
if (!this.needGetProject) {
|
if (!this.needGetProject) {
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
if (!all_projects || !globals.user.hasAdminRole) {
|
if (!all_projects || !this.hasAdminRole) {
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
const projectIds = [];
|
const projectIds = [];
|
||||||
@ -240,28 +268,33 @@ export default class BaseStore {
|
|||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
|
|
||||||
async requestListByMarker(url, params, limit, marker) {
|
updateMarkerParams = (limit, marker) => {
|
||||||
|
return {
|
||||||
|
limit,
|
||||||
|
marker,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
async requestListByMarker(params, limit, marker) {
|
||||||
|
const markerParams = this.updateMarkerParams(limit, marker);
|
||||||
const newParams = {
|
const newParams = {
|
||||||
...params,
|
...params,
|
||||||
limit,
|
...markerParams,
|
||||||
};
|
};
|
||||||
if (marker) {
|
return this.listFetchByClient(newParams);
|
||||||
newParams.marker = marker;
|
|
||||||
}
|
|
||||||
return request.get(url, newParams);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async requestListAllByLimit(url, params, limit) {
|
async requestListAllByLimit(params, limit) {
|
||||||
let marker = '';
|
let marker = '';
|
||||||
let hasNext = true;
|
let hasNext = true;
|
||||||
let datas = [];
|
let datas = [];
|
||||||
while (hasNext) {
|
while (hasNext) {
|
||||||
// eslint-disable-next-line no-await-in-loop
|
// eslint-disable-next-line no-await-in-loop
|
||||||
const result = await this.requestListByMarker(url, params, limit, marker);
|
const result = await this.requestListByMarker(params, limit, marker);
|
||||||
const data = this.getListDataFromResult(result);
|
const data = this.getListDataFromResult(result);
|
||||||
datas = [...datas, ...data];
|
datas = [...datas, ...data];
|
||||||
if (data.length >= limit) {
|
if (data.length >= limit) {
|
||||||
marker = this.parseMarker(data);
|
marker = this.parseMarker(data, result, datas);
|
||||||
if (!marker) {
|
if (!marker) {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.log('parse marker error!');
|
console.log('parse marker error!');
|
||||||
@ -274,21 +307,21 @@ export default class BaseStore {
|
|||||||
return datas;
|
return datas;
|
||||||
}
|
}
|
||||||
|
|
||||||
async requestListAll(url, params) {
|
async requestListAll(params, originParams) {
|
||||||
const result = await request.get(url, params);
|
const result = await this.listFetchByClient(params, originParams);
|
||||||
return this.getListDataFromResult(result);
|
return this.getListDataFromResult(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
async requestList(url, params) {
|
async requestList(params, originParams) {
|
||||||
const datas = !this.fetchListByLimit
|
const datas = !this.fetchListByLimit
|
||||||
? await this.requestListAll(url, params)
|
? await this.requestListAll(params, originParams)
|
||||||
: await this.requestListAllByLimit(url, params, 100);
|
: await this.requestListAllByLimit(params, 100);
|
||||||
return datas;
|
return datas;
|
||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line no-unused-vars
|
// eslint-disable-next-line no-unused-vars
|
||||||
async requestListByPage(url, params, page, filters) {
|
async requestListByPage(params, page, originParams) {
|
||||||
const datas = await request.get(url, params);
|
const datas = await this.listFetchByClient(params, originParams);
|
||||||
return datas;
|
return datas;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -319,19 +352,7 @@ export default class BaseStore {
|
|||||||
params.all_projects = true;
|
params.all_projects = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let url = `${this.getListDetailUrl() || this.getListUrl()}?`;
|
const allData = await this.requestList(params, {});
|
||||||
let othersStr = '';
|
|
||||||
Object.keys(params).forEach((item) => {
|
|
||||||
if (isArray(params[item])) {
|
|
||||||
params[item].forEach((i) => {
|
|
||||||
othersStr += `${item}=${i}&`;
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
othersStr += `${item}=${params[item]}&`;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
url += othersStr.substring(0, othersStr.length - 1);
|
|
||||||
const allData = await this.requestList(url);
|
|
||||||
return allData;
|
return allData;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -355,9 +376,7 @@ export default class BaseStore {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
const newParams = this.paramsFunc(params);
|
const newParams = this.paramsFunc(params);
|
||||||
const url = this.getListDetailUrl(filters) || this.getListUrl(filters);
|
const allData = await this.requestList(newParams, filters);
|
||||||
const newUrl = this.updateUrl(url, params);
|
|
||||||
const allData = await this.requestList(newUrl, newParams, filters);
|
|
||||||
const allDataNew = allData.map((it) =>
|
const allDataNew = allData.map((it) =>
|
||||||
this.mapperBeforeFetchProject(it, filters)
|
this.mapperBeforeFetchProject(it, filters)
|
||||||
);
|
);
|
||||||
@ -393,15 +412,15 @@ export default class BaseStore {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// eslint-disable-next-line no-unused-vars
|
// eslint-disable-next-line no-unused-vars
|
||||||
parseMarker(datas, result) {
|
parseMarker(datas, result, allDatas) {
|
||||||
return datas.length === 0
|
return datas.length === 0
|
||||||
? ''
|
? ''
|
||||||
: get(datas[datas.length - 1], this.markerKey);
|
: get(datas[datas.length - 1], this.markerKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
updateMarker(datas, page, result) {
|
updateMarker(datas, page, result, allDatas) {
|
||||||
const marker = this.parseMarker(datas, result);
|
const marker = this.parseMarker(datas, result, allDatas);
|
||||||
if (page === 1) {
|
if (page === 1) {
|
||||||
this.list.markers = [marker];
|
this.list.markers = [marker];
|
||||||
} else {
|
} else {
|
||||||
@ -423,6 +442,9 @@ export default class BaseStore {
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
|
getOtherInfo = (result) => {};
|
||||||
|
|
||||||
@action
|
@action
|
||||||
async fetchListByPage({
|
async fetchListByPage({
|
||||||
limit = 10,
|
limit = 10,
|
||||||
@ -448,20 +470,10 @@ export default class BaseStore {
|
|||||||
if (marker) {
|
if (marker) {
|
||||||
params.marker = marker;
|
params.marker = marker;
|
||||||
}
|
}
|
||||||
const url =
|
|
||||||
this.getListPageUrl(filters) ||
|
|
||||||
this.getListDetailUrl(filters) ||
|
|
||||||
this.getListUrl(filters);
|
|
||||||
const newUrl = this.updateUrl(url, params);
|
|
||||||
const newParams = this.paramsFuncPage(params, all_projects);
|
const newParams = this.paramsFuncPage(params, all_projects);
|
||||||
const result = await this.requestListByPage(
|
const result = await this.requestListByPage(newParams, page, filters);
|
||||||
newUrl,
|
|
||||||
newParams,
|
|
||||||
page,
|
|
||||||
filters
|
|
||||||
);
|
|
||||||
const allData = this.getListDataFromResult(result);
|
const allData = this.getListDataFromResult(result);
|
||||||
this.updateMarker(allData, page, result);
|
this.updateMarker(allData, page, result, allData);
|
||||||
const allDataNew = allData.map(this.mapperBeforeFetchProject);
|
const allDataNew = allData.map(this.mapperBeforeFetchProject);
|
||||||
let newData = await this.listDidFetchProject(allDataNew, all_projects);
|
let newData = await this.listDidFetchProject(allDataNew, all_projects);
|
||||||
newData = await this.listDidFetch(newData, all_projects, filters);
|
newData = await this.listDidFetch(newData, all_projects, filters);
|
||||||
@ -482,6 +494,7 @@ export default class BaseStore {
|
|||||||
count = retCount;
|
count = retCount;
|
||||||
total = retTotal;
|
total = retTotal;
|
||||||
}
|
}
|
||||||
|
const others = this.getOtherInfo(result);
|
||||||
this.list.update({
|
this.list.update({
|
||||||
data: newData,
|
data: newData,
|
||||||
limit: Number(limit) || 10,
|
limit: Number(limit) || 10,
|
||||||
@ -493,54 +506,7 @@ export default class BaseStore {
|
|||||||
isLoading: false,
|
isLoading: false,
|
||||||
total: count || total,
|
total: count || total,
|
||||||
...(this.list.silent ? {} : { selectedRowKeys: [] }),
|
...(this.list.silent ? {} : { selectedRowKeys: [] }),
|
||||||
});
|
...others,
|
||||||
|
|
||||||
return newData;
|
|
||||||
}
|
|
||||||
|
|
||||||
@action
|
|
||||||
async fetchListWithoutDetail({
|
|
||||||
limit,
|
|
||||||
page,
|
|
||||||
sortKey,
|
|
||||||
sortOrder,
|
|
||||||
conditions,
|
|
||||||
timeFilter,
|
|
||||||
...filters
|
|
||||||
} = {}) {
|
|
||||||
this.list.isLoading = true;
|
|
||||||
// todo: no page, no limit, fetch all
|
|
||||||
const { tab, all_projects, ...rest } = filters;
|
|
||||||
const params = { ...rest };
|
|
||||||
if (all_projects) {
|
|
||||||
if (!this.listFilterByProject) {
|
|
||||||
params.all_projects = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const newParams = this.paramsFunc(params, all_projects);
|
|
||||||
const allData = await this.requestList(this.getListUrl(), newParams);
|
|
||||||
const allDataNew = allData.map(this.mapperBeforeFetchProject);
|
|
||||||
const data = allDataNew.filter((item) => {
|
|
||||||
if (!this.listFilterByProject) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return this.itemInCurrentProject(item, all_projects);
|
|
||||||
});
|
|
||||||
// const items = data.map(this.mapper);
|
|
||||||
let newData = await this.listDidFetchProject(data, all_projects);
|
|
||||||
newData = await this.listDidFetch(newData, all_projects, filters);
|
|
||||||
newData = newData.map(this.mapper);
|
|
||||||
this.list.update({
|
|
||||||
data: newData,
|
|
||||||
total: newData.length || 0,
|
|
||||||
limit: Number(limit) || 10,
|
|
||||||
page: Number(page) || 1,
|
|
||||||
sortKey,
|
|
||||||
sortOrder,
|
|
||||||
filters,
|
|
||||||
timeFilter,
|
|
||||||
isLoading: false,
|
|
||||||
...(this.list.silent ? {} : { selectedRowKeys: [] }),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return newData;
|
return newData;
|
||||||
@ -551,8 +517,8 @@ export default class BaseStore {
|
|||||||
if (!silent) {
|
if (!silent) {
|
||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
}
|
}
|
||||||
const result = await request.get(
|
const result = await this.detailFetchByClient(
|
||||||
this.getDetailUrl(rest),
|
rest,
|
||||||
this.getDetailParams({ all_projects })
|
this.getDetailParams({ all_projects })
|
||||||
);
|
);
|
||||||
const originData = get(result, this.responseKey) || result;
|
const originData = get(result, this.responseKey) || result;
|
||||||
@ -579,37 +545,30 @@ export default class BaseStore {
|
|||||||
create(data) {
|
create(data) {
|
||||||
const body = {};
|
const body = {};
|
||||||
body[this.responseKey] = data;
|
body[this.responseKey] = data;
|
||||||
return this.submitting(request.post(this.getListUrl(), body));
|
return this.submitting(this.client.create(body));
|
||||||
}
|
|
||||||
|
|
||||||
@action
|
|
||||||
update({ id }, newObject, sleepTime) {
|
|
||||||
return this.submitting(
|
|
||||||
request.post(
|
|
||||||
`${this.getDetailUrl({ id })}/action`,
|
|
||||||
newObject,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
sleepTime
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
edit({ id }, newObject) {
|
edit({ id }, newObject) {
|
||||||
const body = {};
|
const body = {};
|
||||||
body[this.responseKey] = newObject;
|
body[this.responseKey] = newObject;
|
||||||
return this.submitting(request.put(this.getDetailUrl({ id }), body));
|
return this.submitting(this.client.update(id, body));
|
||||||
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
update({ id }, newObject) {
|
||||||
|
const body = {};
|
||||||
|
body[this.responseKey] = newObject;
|
||||||
|
return this.submitting(this.client.update(id, body));
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
patch({ id }, newObject) {
|
patch({ id }, newObject) {
|
||||||
return this.submitting(request.patch(this.getDetailUrl({ id }), newObject));
|
return this.submitting(this.client.patch(id, newObject));
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
delete = ({ id }) =>
|
delete = ({ id }) => this.submitting(this.client.delete(id));
|
||||||
this.submitting(request.delete(this.getDetailUrl({ id })));
|
|
||||||
|
|
||||||
@action
|
@action
|
||||||
batchDelete(rowKeys) {
|
batchDelete(rowKeys) {
|
||||||
@ -617,17 +576,13 @@ export default class BaseStore {
|
|||||||
Promise.all(
|
Promise.all(
|
||||||
rowKeys.map((name) => {
|
rowKeys.map((name) => {
|
||||||
const item = this.list.data.find((_item) => _item.name === name);
|
const item = this.list.data.find((_item) => _item.name === name);
|
||||||
return request.delete(this.getDetailUrl(item));
|
const { id } = item;
|
||||||
|
return this.client.delete(id);
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
reject = (res) => {
|
|
||||||
this.isSubmitting = false;
|
|
||||||
window.onunhandledrejection(res);
|
|
||||||
};
|
|
||||||
|
|
||||||
@action
|
@action
|
||||||
clearData() {
|
clearData() {
|
||||||
this.list.reset();
|
this.list.reset();
|
||||||
|
@ -13,28 +13,19 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { action } from 'mobx';
|
import { action } from 'mobx';
|
||||||
import { cinderBase } from 'utils/constants';
|
import client from 'client';
|
||||||
import Base from '../base';
|
import Base from '../base';
|
||||||
import { VolumeStore } from './volume';
|
import { VolumeStore } from './volume';
|
||||||
|
|
||||||
export class BackupStore extends Base {
|
export class BackupStore extends Base {
|
||||||
get module() {
|
get client() {
|
||||||
if (!globals.user) {
|
return client.cinder.backups;
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return `${globals.user.project.id}/backups`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get apiVersion() {
|
get listWithDetail() {
|
||||||
return cinderBase();
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
get responseKey() {
|
|
||||||
return 'backup';
|
|
||||||
}
|
|
||||||
|
|
||||||
getListDetailUrl = () => `${this.apiVersion}/${this.module}/detail`;
|
|
||||||
|
|
||||||
updateParamsSortPage = (params, sortKey, sortOrder) => {
|
updateParamsSortPage = (params, sortKey, sortOrder) => {
|
||||||
if (sortKey && sortOrder) {
|
if (sortKey && sortOrder) {
|
||||||
params.sort = `${sortKey}:${sortOrder === 'descend' ? 'desc' : 'asc'}`;
|
params.sort = `${sortKey}:${sortOrder === 'descend' ? 'desc' : 'asc'}`;
|
||||||
@ -65,9 +56,7 @@ export class BackupStore extends Base {
|
|||||||
@action
|
@action
|
||||||
restore(id, data) {
|
restore(id, data) {
|
||||||
const body = { restore: data || {} };
|
const body = { restore: data || {} };
|
||||||
return this.submitting(
|
return this.submitting(this.client.restore(id, body));
|
||||||
request.post(`${this.getDetailUrl({ id })}/restore`, body)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const globalBackupStore = new BackupStore();
|
const globalBackupStore = new BackupStore();
|
||||||
|
@ -13,43 +13,21 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { action } from 'mobx';
|
import { action } from 'mobx';
|
||||||
import { cinderBase } from 'utils/constants';
|
import client from 'client';
|
||||||
import Base from '../base';
|
import Base from '../base';
|
||||||
|
|
||||||
export class ExtraSpecStore extends Base {
|
export class ExtraSpecStore extends Base {
|
||||||
get module() {
|
get client() {
|
||||||
if (!globals.user) {
|
return client.cinder.types.extraSpecs;
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return `${globals.user.project.id}/types`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get apiVersion() {
|
get isSubResource() {
|
||||||
return cinderBase();
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
get responseKey() {
|
getFatherResourceId = (params) => params.id;
|
||||||
return 'extra_spec';
|
|
||||||
}
|
|
||||||
|
|
||||||
getExtraSpecsUrl = ({ id }) =>
|
getListDataFromResult = (result) => {
|
||||||
`${this.apiVersion}/${this.module}/${id}/extra_specs`;
|
|
||||||
|
|
||||||
@action
|
|
||||||
async fetchList({
|
|
||||||
id,
|
|
||||||
limit,
|
|
||||||
page,
|
|
||||||
sortKey,
|
|
||||||
sortOrder,
|
|
||||||
conditions,
|
|
||||||
...filters
|
|
||||||
} = {}) {
|
|
||||||
this.list.isLoading = true;
|
|
||||||
// todo: no page, no limit, fetch all
|
|
||||||
const params = { ...filters };
|
|
||||||
|
|
||||||
const result = await request.get(this.getExtraSpecsUrl({ id }), params);
|
|
||||||
const { extra_specs } = result;
|
const { extra_specs } = result;
|
||||||
const data = [];
|
const data = [];
|
||||||
Object.keys(extra_specs).forEach((key) => {
|
Object.keys(extra_specs).forEach((key) => {
|
||||||
@ -60,36 +38,20 @@ export class ExtraSpecStore extends Base {
|
|||||||
value: extra_specs[key],
|
value: extra_specs[key],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
const items = data.map(this.mapper);
|
|
||||||
|
|
||||||
this.list.update({
|
|
||||||
data,
|
|
||||||
total: items.length || 0,
|
|
||||||
limit: Number(limit) || 10,
|
|
||||||
page: Number(page) || 1,
|
|
||||||
sortKey,
|
|
||||||
sortOrder,
|
|
||||||
filters,
|
|
||||||
isLoading: false,
|
|
||||||
...(this.list.silent ? {} : { selectedRowKeys: [] }),
|
|
||||||
});
|
|
||||||
this.urlId = id;
|
|
||||||
return data;
|
return data;
|
||||||
}
|
};
|
||||||
|
|
||||||
@action
|
@action
|
||||||
createOrUpdate(id, data) {
|
createOrUpdate(id, data) {
|
||||||
const body = {
|
const body = {
|
||||||
extra_specs: data,
|
extra_specs: data,
|
||||||
};
|
};
|
||||||
return this.submitting(request.post(this.getExtraSpecsUrl({ id }), body));
|
return this.submitting(this.client.create(id, body));
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
delete = ({ id, keyname }) => {
|
delete = ({ id, keyname }) => {
|
||||||
return this.submitting(
|
return this.submitting(this.client.delete(id, keyname));
|
||||||
request.delete(`${this.getExtraSpecsUrl({ id })}/${keyname}`)
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
const globalExtraSpecStore = new ExtraSpecStore();
|
const globalExtraSpecStore = new ExtraSpecStore();
|
||||||
|
@ -12,27 +12,26 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { cinderBase } from 'utils/constants';
|
|
||||||
import { isNumber } from 'lodash';
|
import { isNumber } from 'lodash';
|
||||||
|
import client from 'client';
|
||||||
import Base from '../base';
|
import Base from '../base';
|
||||||
|
|
||||||
export class PoolStore extends Base {
|
export class PoolStore extends Base {
|
||||||
get module() {
|
get client() {
|
||||||
return 'scheduler-stats/get_pools';
|
return client.cinder.pools;
|
||||||
}
|
|
||||||
|
|
||||||
get apiVersion() {
|
|
||||||
return cinderBase();
|
|
||||||
}
|
|
||||||
|
|
||||||
get responseKey() {
|
|
||||||
return 'pool';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get listFilterByProject() {
|
get listFilterByProject() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get paramsFunc() {
|
||||||
|
return (params) => ({
|
||||||
|
...params,
|
||||||
|
detail: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
get mapper() {
|
get mapper() {
|
||||||
return (data) => {
|
return (data) => {
|
||||||
const { name, capabilities = {} } = data;
|
const { name, capabilities = {} } = data;
|
||||||
@ -46,9 +45,6 @@ export class PoolStore extends Base {
|
|||||||
return newItem;
|
return newItem;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
getListUrl = () =>
|
|
||||||
`${this.apiVersion}/${globals.user.project.id}/${this.module}?detail=true`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const globalPoolStore = new PoolStore();
|
const globalPoolStore = new PoolStore();
|
||||||
|
@ -13,42 +13,20 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { action } from 'mobx';
|
import { action } from 'mobx';
|
||||||
import { cinderBase } from 'utils/constants';
|
import client from 'client';
|
||||||
import Base from '../base';
|
import Base from '../base';
|
||||||
|
|
||||||
export class QosSpecKeyStore extends Base {
|
export class QosSpecKeyStore extends Base {
|
||||||
get module() {
|
get client() {
|
||||||
if (!globals.user) {
|
return client.cinder.qosSpecs;
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return `${globals.user.project.id}/qos-specs`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get apiVersion() {
|
listFetchByClient(params) {
|
||||||
return cinderBase();
|
const { id } = params;
|
||||||
|
return this.client.show(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
get responseKey() {
|
getListDataFromResult = (result) => {
|
||||||
return 'qos_specs';
|
|
||||||
}
|
|
||||||
|
|
||||||
getListUrl = ({ id }) => `${this.apiVersion}/${this.module}/${id}`;
|
|
||||||
|
|
||||||
@action
|
|
||||||
async fetchList({
|
|
||||||
id,
|
|
||||||
limit,
|
|
||||||
page,
|
|
||||||
sortKey,
|
|
||||||
sortOrder,
|
|
||||||
conditions,
|
|
||||||
...filters
|
|
||||||
} = {}) {
|
|
||||||
this.list.isLoading = true;
|
|
||||||
// todo: no page, no limit, fetch all
|
|
||||||
const params = { ...filters };
|
|
||||||
|
|
||||||
const result = await request.get(this.getListUrl({ id }), params);
|
|
||||||
const { specs = {} } = result.qos_specs || {};
|
const { specs = {} } = result.qos_specs || {};
|
||||||
const data = [];
|
const data = [];
|
||||||
Object.keys(specs).forEach((key) => {
|
Object.keys(specs).forEach((key) => {
|
||||||
@ -59,35 +37,21 @@ export class QosSpecKeyStore extends Base {
|
|||||||
value: specs[key],
|
value: specs[key],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
const items = data.map(this.mapper);
|
|
||||||
|
|
||||||
this.list.update({
|
|
||||||
data,
|
|
||||||
total: items.length || 0,
|
|
||||||
limit: Number(limit) || 10,
|
|
||||||
page: Number(page) || 1,
|
|
||||||
sortKey,
|
|
||||||
sortOrder,
|
|
||||||
filters,
|
|
||||||
isLoading: false,
|
|
||||||
...(this.list.silent ? {} : { selectedRowKeys: [] }),
|
|
||||||
});
|
|
||||||
this.urlId = id;
|
|
||||||
return data;
|
return data;
|
||||||
}
|
};
|
||||||
|
|
||||||
@action
|
@action
|
||||||
createOrUpdate(id, data) {
|
createOrUpdate(id, data) {
|
||||||
const body = {};
|
const body = {};
|
||||||
body[this.responseKey] = data;
|
body.qos_specs = data;
|
||||||
return this.submitting(request.put(this.getListUrl({ id }), body));
|
return this.submitting(this.client.update(id, body));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
@action
|
@action
|
||||||
delete = ({ id, keyname }) =>
|
delete = ({ id, keyname }) =>
|
||||||
this.submitting(
|
this.submitting(
|
||||||
request.put(`${this.getListUrl({ id })}/delete_keys`, {
|
this.client.deleteKeys(id, {
|
||||||
keys: [keyname],
|
keys: [keyname],
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
@ -13,25 +13,12 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { action } from 'mobx';
|
import { action } from 'mobx';
|
||||||
import { cinderBase } from 'utils/constants';
|
import client from 'client';
|
||||||
import Base from '../base';
|
import Base from '../base';
|
||||||
|
|
||||||
const qs = require('qs');
|
|
||||||
|
|
||||||
export class QosSpecStore extends Base {
|
export class QosSpecStore extends Base {
|
||||||
get module() {
|
get client() {
|
||||||
if (!globals.user) {
|
return client.cinder.qosSpecs;
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return `${globals.user.project.id}/qos-specs`;
|
|
||||||
}
|
|
||||||
|
|
||||||
get apiVersion() {
|
|
||||||
return cinderBase();
|
|
||||||
}
|
|
||||||
|
|
||||||
get responseKey() {
|
|
||||||
return 'qos_spec';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
@ -39,13 +26,13 @@ export class QosSpecStore extends Base {
|
|||||||
const body = {};
|
const body = {};
|
||||||
const { values } = data;
|
const { values } = data;
|
||||||
body[`${this.responseKey}s`] = values;
|
body[`${this.responseKey}s`] = values;
|
||||||
return this.submitting(request.post(this.getListUrl(), body));
|
return this.submitting(this.client.create(body));
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
editConsumer({ id, consumer }) {
|
editConsumer({ id, consumer }) {
|
||||||
return this.submitting(
|
return this.submitting(
|
||||||
request.put(this.getDetailUrl({ id }), {
|
this.client.update(id, {
|
||||||
qos_specs: {
|
qos_specs: {
|
||||||
consumer,
|
consumer,
|
||||||
},
|
},
|
||||||
@ -66,18 +53,12 @@ export class QosSpecStore extends Base {
|
|||||||
|
|
||||||
@action
|
@action
|
||||||
associate(id, data) {
|
associate(id, data) {
|
||||||
const query = qs.stringify(data);
|
return this.submitting(this.client.associate(id, data));
|
||||||
return this.submitting(
|
|
||||||
request.get(`${this.getDetailUrl({ id })}/associate?${query}`)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
disassociate(id, data) {
|
disassociate(id, data) {
|
||||||
const query = qs.stringify(data);
|
return this.submitting(this.client.disassociate(id, data));
|
||||||
return this.submitting(
|
|
||||||
request.get(`${this.getDetailUrl({ id })}/disassociate?${query}`)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,40 +12,23 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { cinderBase } from 'utils/constants';
|
|
||||||
import { action } from 'mobx';
|
import { action } from 'mobx';
|
||||||
|
import client from 'client';
|
||||||
import Base from '../base';
|
import Base from '../base';
|
||||||
|
|
||||||
export class ServiceStore extends Base {
|
export class ServiceStore extends Base {
|
||||||
get module() {
|
get client() {
|
||||||
return 'os-services';
|
return client.cinder.services;
|
||||||
}
|
|
||||||
|
|
||||||
get apiVersion() {
|
|
||||||
return cinderBase();
|
|
||||||
}
|
|
||||||
|
|
||||||
get responseKey() {
|
|
||||||
return 'service';
|
|
||||||
}
|
|
||||||
|
|
||||||
getListUrl = () =>
|
|
||||||
`${this.apiVersion}/${globals.user.project.id}/${this.module}`;
|
|
||||||
|
|
||||||
@action
|
|
||||||
operate(actionName, body) {
|
|
||||||
const url = `${this.getListUrl()}/${actionName}`;
|
|
||||||
return this.submitting(request.put(url, body));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
enable(body) {
|
enable(body) {
|
||||||
return this.operate('enable', body);
|
return this.submitting(this.client.enable(body));
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
disable(body) {
|
disable(body) {
|
||||||
return this.operate('disable-log-reason', body);
|
return this.submitting(this.client.reason(body));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,44 +12,30 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { action, observable } from 'mobx';
|
import { action } from 'mobx';
|
||||||
import { cinderBase, skylineBase } from 'utils/constants';
|
import client from 'client';
|
||||||
import Base from '../base';
|
import Base from '../base';
|
||||||
|
|
||||||
export class SnapshotStore extends Base {
|
export class SnapshotStore extends Base {
|
||||||
@observable
|
get client() {
|
||||||
allSnapshotList = [];
|
return client.cinder.snapshots;
|
||||||
|
|
||||||
get module() {
|
|
||||||
if (!globals.user) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return `${globals.user.project.id}/snapshots`;
|
|
||||||
}
|
|
||||||
|
|
||||||
get apiVersion() {
|
|
||||||
return cinderBase();
|
|
||||||
}
|
|
||||||
|
|
||||||
get responseKey() {
|
|
||||||
return 'snapshot';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get listResponseKey() {
|
get listResponseKey() {
|
||||||
return 'volume_snapshots';
|
return 'volume_snapshots';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
listFetchByClient(params) {
|
||||||
|
return this.skylineClient.extension.volumeSnapshots(params);
|
||||||
|
}
|
||||||
|
|
||||||
get paramsFunc() {
|
get paramsFunc() {
|
||||||
return (params) => {
|
return (params) => {
|
||||||
const { id, ...rest } = params;
|
const { id, withPrice, ...rest } = params;
|
||||||
return rest;
|
return rest;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
getListPageUrl = () => `${skylineBase()}/extension/volume_snapshots`;
|
|
||||||
|
|
||||||
getListDetailUrl = () => `${skylineBase()}/extension/volume_snapshots`;
|
|
||||||
|
|
||||||
async listDidFetch(items, allProjects, filters) {
|
async listDidFetch(items, allProjects, filters) {
|
||||||
if (items.length === 0) {
|
if (items.length === 0) {
|
||||||
return items;
|
return items;
|
||||||
@ -61,10 +47,7 @@ export class SnapshotStore extends Base {
|
|||||||
|
|
||||||
async detailDidFetch(item) {
|
async detailDidFetch(item) {
|
||||||
const { volume_id } = item;
|
const { volume_id } = item;
|
||||||
const volumeUrl = `${cinderBase()}/${
|
const { volume } = await client.cinder.volumes.show(volume_id);
|
||||||
globals.user.project.id
|
|
||||||
}/volumes/${volume_id}`;
|
|
||||||
const { volume } = await request.get(volumeUrl);
|
|
||||||
item.volume = volume;
|
item.volume = volume;
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
@ -76,19 +59,10 @@ export class SnapshotStore extends Base {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@action
|
|
||||||
fetchAllList() {
|
|
||||||
return request.get(this.getListUrl()).then((res) => {
|
|
||||||
const list = res.snapshots || [];
|
|
||||||
this.allSnapshotList = list;
|
|
||||||
return list;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@action
|
@action
|
||||||
update(id, data) {
|
update(id, data) {
|
||||||
const body = { [this.responseKey]: data };
|
const body = { [this.responseKey]: data };
|
||||||
return this.submitting(request.put(this.getDetailUrl({ id }), body));
|
return this.submitting(this.client.update(id, body));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const globalSnapshotStore = new SnapshotStore();
|
const globalSnapshotStore = new SnapshotStore();
|
||||||
|
@ -13,26 +13,19 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { action, observable } from 'mobx';
|
import { action, observable } from 'mobx';
|
||||||
import { cinderBase } from 'utils/constants';
|
import client from 'client';
|
||||||
|
import { uniq } from 'lodash';
|
||||||
import Base from '../base';
|
import Base from '../base';
|
||||||
|
|
||||||
export class VolumeTypeStore extends Base {
|
export class VolumeTypeStore extends Base {
|
||||||
@observable
|
@observable
|
||||||
access = [];
|
access = [];
|
||||||
|
|
||||||
get module() {
|
@observable
|
||||||
if (!globals.user) {
|
projectVolumeTypes = [];
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return `${globals.user.project.id}/types`;
|
|
||||||
}
|
|
||||||
|
|
||||||
get apiVersion() {
|
get client() {
|
||||||
return cinderBase();
|
return client.cinder.types;
|
||||||
}
|
|
||||||
|
|
||||||
get responseKey() {
|
|
||||||
return 'volume_type';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get listFilterByProject() {
|
get listFilterByProject() {
|
||||||
@ -41,32 +34,58 @@ export class VolumeTypeStore extends Base {
|
|||||||
|
|
||||||
get paramsFuncPage() {
|
get paramsFuncPage() {
|
||||||
return (params) => {
|
return (params) => {
|
||||||
const { current, showEncryption, ...rest } = params;
|
const {
|
||||||
|
current,
|
||||||
|
showEncryption,
|
||||||
|
showQoS,
|
||||||
|
withPrice,
|
||||||
|
resourceType,
|
||||||
|
...rest
|
||||||
|
} = params;
|
||||||
return rest;
|
return rest;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get paramsFunc() {
|
||||||
|
return this.paramsFuncPage;
|
||||||
|
}
|
||||||
|
|
||||||
get mapper() {
|
get mapper() {
|
||||||
return (data) => {
|
return (data) => {
|
||||||
const { extra_specs: { multiattach = 'False' } = {} } = data;
|
const { extra_specs: { multiattach = 'False' } = {} } = data;
|
||||||
return {
|
return {
|
||||||
...data,
|
...data,
|
||||||
multiattach: multiattach === '<is> True',
|
multiattach: multiattach === '<is> True',
|
||||||
|
enableBilling: this.enableBilling,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async listDidFetch(items, allProjects, filters) {
|
async listDidFetch(items, allProjects, filters) {
|
||||||
const { showEncryption } = filters;
|
const { showEncryption, showQoS } = filters;
|
||||||
if (items.length === 0) {
|
if (items.length === 0) {
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
|
if (showQoS) {
|
||||||
|
const qosIds = uniq(
|
||||||
|
items.filter((it) => !!it.qos_specs_id).map((it) => it.qos_specs_id)
|
||||||
|
);
|
||||||
|
if (qosIds.length) {
|
||||||
|
const qosReqs = qosIds.map((id) => client.cinder.qosSpecs.show(id));
|
||||||
|
const qosResults = await Promise.all(qosReqs);
|
||||||
|
const qosItems = qosResults.map((it) => it.qos_specs);
|
||||||
|
items.forEach((it) => {
|
||||||
|
if (it.qos_specs_id) {
|
||||||
|
it.qos_specs = qosItems.find((qos) => qos.id === it.qos_specs_id);
|
||||||
|
it.qos_specs_name = (it.qos_specs || {}).name;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
if (!showEncryption) {
|
if (!showEncryption) {
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
const promiseList = items.map((i) =>
|
const promiseList = items.map((i) => this.client.encryption.list(i.id));
|
||||||
request.get(`${this.getDetailUrl({ id: i.id })}/encryption`)
|
|
||||||
);
|
|
||||||
const encryptionList = await Promise.all(promiseList);
|
const encryptionList = await Promise.all(promiseList);
|
||||||
const result = items.map((i) => {
|
const result = items.map((i) => {
|
||||||
const { id } = i;
|
const { id } = i;
|
||||||
@ -81,7 +100,7 @@ export class VolumeTypeStore extends Base {
|
|||||||
|
|
||||||
async detailDidFetch(item) {
|
async detailDidFetch(item) {
|
||||||
const { id } = item || {};
|
const { id } = item || {};
|
||||||
const result = await request.get(`${this.getDetailUrl({ id })}/encryption`);
|
const result = await this.client.encryption.list(id);
|
||||||
item.encryption = result;
|
item.encryption = result;
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
@ -90,7 +109,7 @@ export class VolumeTypeStore extends Base {
|
|||||||
update(id, data) {
|
update(id, data) {
|
||||||
const body = {};
|
const body = {};
|
||||||
body[this.responseKey] = data;
|
body[this.responseKey] = data;
|
||||||
return this.submitting(request.put(this.getDetailUrl({ id }), body));
|
return this.submitting(this.client.update(id, body));
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
@ -98,16 +117,12 @@ export class VolumeTypeStore extends Base {
|
|||||||
const body = {
|
const body = {
|
||||||
encryption: data,
|
encryption: data,
|
||||||
};
|
};
|
||||||
return this.submitting(
|
return this.submitting(this.client.encryption.create(id, body));
|
||||||
request.post(`${this.getDetailUrl({ id })}/encryption`, body)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
deleteEncryption(id, encryption_id) {
|
deleteEncryption(id, encryption_id) {
|
||||||
return this.submitting(
|
return this.submitting(this.client.encryption.delete(id, encryption_id));
|
||||||
request.delete(`${this.getDetailUrl({ id })}/encryption/${encryption_id}`)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
@ -115,17 +130,16 @@ export class VolumeTypeStore extends Base {
|
|||||||
const body = {};
|
const body = {};
|
||||||
body[this.responseKey] = data;
|
body[this.responseKey] = data;
|
||||||
if (projectIds.length === 0) {
|
if (projectIds.length === 0) {
|
||||||
return this.submitting(request.post(this.getListUrl(), body));
|
return this.submitting(this.client.create(body));
|
||||||
}
|
}
|
||||||
this.isSubmitting = true;
|
this.isSubmitting = true;
|
||||||
const result = await request.post(this.getListUrl(), body);
|
const result = await this.client.create(body);
|
||||||
const { id } = result[this.responseKey];
|
const { id } = result[this.responseKey];
|
||||||
return this.addProjectAccess(id, projectIds);
|
return this.addProjectAccess(id, projectIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
addProjectAccess(id, projectIds = []) {
|
addProjectAccess(id, projectIds = []) {
|
||||||
const actionUrl = `${this.getDetailUrl({ id })}/action`;
|
|
||||||
return this.submitting(
|
return this.submitting(
|
||||||
Promise.all(
|
Promise.all(
|
||||||
projectIds.map((it) => {
|
projectIds.map((it) => {
|
||||||
@ -134,7 +148,7 @@ export class VolumeTypeStore extends Base {
|
|||||||
project: it,
|
project: it,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
return request.post(actionUrl, actionBody);
|
return this.client.action(id, actionBody);
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@ -142,7 +156,6 @@ export class VolumeTypeStore extends Base {
|
|||||||
|
|
||||||
@action
|
@action
|
||||||
removeProjectAccess(id, projectIds = []) {
|
removeProjectAccess(id, projectIds = []) {
|
||||||
const actionUrl = `${this.getDetailUrl({ id })}/action`;
|
|
||||||
return this.submitting(
|
return this.submitting(
|
||||||
Promise.all(
|
Promise.all(
|
||||||
projectIds.map((it) => {
|
projectIds.map((it) => {
|
||||||
@ -151,7 +164,7 @@ export class VolumeTypeStore extends Base {
|
|||||||
project: it,
|
project: it,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
return request.post(actionUrl, actionBody);
|
return this.client.action(id, actionBody);
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@ -159,8 +172,7 @@ export class VolumeTypeStore extends Base {
|
|||||||
|
|
||||||
@action
|
@action
|
||||||
async fetchProjectAccess(id) {
|
async fetchProjectAccess(id) {
|
||||||
const url = `${this.getDetailUrl({ id })}/os-volume-type-access`;
|
const result = await this.client.getAccess(id);
|
||||||
const result = await request.get(url);
|
|
||||||
this.access = result.volume_type_access;
|
this.access = result.volume_type_access;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,6 +188,30 @@ export class VolumeTypeStore extends Base {
|
|||||||
await this.removeProjectAccess(id, dels);
|
await this.removeProjectAccess(id, dels);
|
||||||
return this.addProjectAccess(id, adds);
|
return this.addProjectAccess(id, adds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
async fetchProjectVolumeTypes(projectId) {
|
||||||
|
const result = await this.client.list({ is_public: 'None' });
|
||||||
|
const { volume_types: types } = result;
|
||||||
|
const privateTypes = types.filter((it) => !it.is_public);
|
||||||
|
if (!privateTypes.length) {
|
||||||
|
this.projectVolumeTypes = types;
|
||||||
|
return types;
|
||||||
|
}
|
||||||
|
const projectTypes = types.filter((it) => it.public);
|
||||||
|
const reqs = privateTypes.map((it) => this.client.getAccess(it.id));
|
||||||
|
const accessResults = await Promise.all(reqs);
|
||||||
|
accessResults.forEach((it) => {
|
||||||
|
const { volume_type_access: access } = it;
|
||||||
|
const item = access.find((a) => a.project_id === projectId);
|
||||||
|
if (item) {
|
||||||
|
const type = types.find((t) => t.id === item.volume_type_id);
|
||||||
|
projectTypes.push(type);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.projectVolumeTypes = projectTypes;
|
||||||
|
return projectTypes;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
const globalVolumeTypeStore = new VolumeTypeStore();
|
const globalVolumeTypeStore = new VolumeTypeStore();
|
||||||
export default globalVolumeTypeStore;
|
export default globalVolumeTypeStore;
|
||||||
|
@ -13,8 +13,9 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { action, observable } from 'mobx';
|
import { action, observable } from 'mobx';
|
||||||
import { cinderBase, skylineBase } from 'utils/constants';
|
|
||||||
import { isOsDisk } from 'resources/volume';
|
import { isOsDisk } from 'resources/volume';
|
||||||
|
import { renderFilterMap } from 'utils/index';
|
||||||
|
import client from 'client';
|
||||||
import Base from '../base';
|
import Base from '../base';
|
||||||
import globalVolumeTypeStore from './volume-type';
|
import globalVolumeTypeStore from './volume-type';
|
||||||
|
|
||||||
@ -31,32 +32,32 @@ export class VolumeStore extends Base {
|
|||||||
@observable
|
@observable
|
||||||
quotaSet = {};
|
quotaSet = {};
|
||||||
|
|
||||||
get module() {
|
get client() {
|
||||||
if (!globals.user) {
|
return client.cinder.volumes;
|
||||||
return null;
|
}
|
||||||
|
|
||||||
|
get transferClient() {
|
||||||
|
return client.cinder.volumeTransfers;
|
||||||
|
}
|
||||||
|
|
||||||
|
listFetchByClient(params, originParams) {
|
||||||
|
const { recycle } = originParams;
|
||||||
|
if (recycle) {
|
||||||
|
return this.client.listDetail(params);
|
||||||
}
|
}
|
||||||
return `${globals.user.project.id}/volumes`;
|
return this.skylineClient.extension.volumes(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
get apiVersion() {
|
|
||||||
return cinderBase();
|
|
||||||
}
|
|
||||||
|
|
||||||
get responseKey() {
|
|
||||||
return 'volume';
|
|
||||||
}
|
|
||||||
|
|
||||||
getListDetailUrl = () => `${skylineBase()}/extension/volumes`;
|
|
||||||
|
|
||||||
getListPageUrl = () => `${skylineBase()}/extension/volumes`;
|
|
||||||
|
|
||||||
getListDetailUrlOpenstack = () => `${this.apiVersion}/${this.module}/detail`;
|
|
||||||
|
|
||||||
get mapper() {
|
get mapper() {
|
||||||
return (volume) => ({
|
return (volume) => ({
|
||||||
...volume,
|
...volume,
|
||||||
disk_tag: isOsDisk(volume) ? 'os_disk' : 'data_disk',
|
disk_tag: isOsDisk(volume) ? 'os_disk' : 'data_disk',
|
||||||
description: volume.description || (volume.origin_data || {}).description,
|
description: volume.description || (volume.origin_data || {}).description,
|
||||||
|
delete_interval:
|
||||||
|
volume.metadata && volume.metadata.delete_interval
|
||||||
|
? new Date(renderFilterMap.toLocalTime(volume.updated_at)).getTime() +
|
||||||
|
Number(volume.metadata.delete_interval) * 1000
|
||||||
|
: null,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,16 +69,32 @@ export class VolumeStore extends Base {
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateParamsSortPage = (params, sortKey, sortOrder) => {
|
updateParamsSortPage = (params, sortKey, sortOrder) => {
|
||||||
|
const { recycle } = params;
|
||||||
if (sortKey && sortOrder) {
|
if (sortKey && sortOrder) {
|
||||||
params.sort_keys = sortKey;
|
const dirs = sortOrder === 'descend' ? 'desc' : 'asc';
|
||||||
params.sort_dirs = sortOrder === 'descend' ? 'desc' : 'asc';
|
if (recycle) {
|
||||||
|
params.sort = `${sortKey}:${dirs}`;
|
||||||
|
} else {
|
||||||
|
params.sort_keys = sortKey;
|
||||||
|
params.sort_dirs = sortOrder === 'descend' ? 'desc' : 'asc';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
async listDidFetch(items, _, filters) {
|
async listDidFetch(items, _, filters) {
|
||||||
|
const { withPrice } = filters;
|
||||||
if (items.length === 0) {
|
if (items.length === 0) {
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
|
if (withPrice) {
|
||||||
|
const volumeTypes = await globalVolumeTypeStore.fetchList({ withPrice });
|
||||||
|
items.forEach((item) => {
|
||||||
|
const { size, volume_type } = item;
|
||||||
|
const volumeType = volumeTypes.find((it) => it.name === volume_type);
|
||||||
|
const cost = volumeType ? (volumeType.priceCost * size).toFixed(2) : 0;
|
||||||
|
item.cost = cost;
|
||||||
|
});
|
||||||
|
}
|
||||||
const { serverId } = filters;
|
const { serverId } = filters;
|
||||||
return !serverId
|
return !serverId
|
||||||
? items
|
? items
|
||||||
@ -88,54 +105,41 @@ export class VolumeStore extends Base {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async detailDidFetch(item, all_projects) {
|
async detailDidFetch(item, all_projects, { withPrice }) {
|
||||||
const { id } = item;
|
const { id } = item;
|
||||||
try {
|
try {
|
||||||
const result = await this.fetchList({ uuid: id, all_projects });
|
const result = await this.fetchList({ uuid: id, all_projects });
|
||||||
item.itemInList = result[0];
|
item.itemInList = result[0];
|
||||||
item.attachmentsContrib = result[0].attachments;
|
item.attachmentsContrib = result[0].attachments;
|
||||||
} catch (e) {}
|
} catch (e) {}
|
||||||
|
if (withPrice) {
|
||||||
|
const volumeTypes = await globalVolumeTypeStore.fetchList({ withPrice });
|
||||||
|
const { size, volume_type } = item;
|
||||||
|
const volumeType = volumeTypes.find((it) => it.name === volume_type);
|
||||||
|
const cost = volumeType ? (volumeType.priceCost * size).toFixed(2) : 0;
|
||||||
|
item.cost = cost;
|
||||||
|
}
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
|
||||||
async fetchCinderService() {
|
|
||||||
return this.submitting(
|
|
||||||
request
|
|
||||||
.get(
|
|
||||||
`${this.apiVersion}/${globals.user.project.id}/os-services?binary=cinder-volume`
|
|
||||||
)
|
|
||||||
.then((data) => {
|
|
||||||
this.cinderServiceOptions = (data.services || [])
|
|
||||||
.filter((item) => item.status === 'enabled')
|
|
||||||
.map((s) => ({
|
|
||||||
value: s.host,
|
|
||||||
lable: s.host,
|
|
||||||
}));
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@action
|
@action
|
||||||
async fetchQuota() {
|
async fetchQuota() {
|
||||||
const url = `${this.apiVersion}/${this.currentProject}/os-quota-sets/${this.currentProject}?usage=True`;
|
const result = await client.cinder.quotaSets.show(this.currentProjectId, {
|
||||||
const result = await request.get(url);
|
usage: 'True',
|
||||||
|
});
|
||||||
this.quotaSet = result.quota_set;
|
this.quotaSet = result.quota_set;
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
async fetchAvailabilityZoneList() {
|
async fetchAvailabilityZoneList() {
|
||||||
const url = `${this.apiVersion}/${globals.user.project.id}/os-availability-zone`;
|
const result = await client.cinder.azones.list();
|
||||||
const result = await request.get(url);
|
|
||||||
this.availabilityZones = result.availabilityZoneInfo;
|
this.availabilityZones = result.availabilityZoneInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
async operation(id, data, key) {
|
async operation(id, data, key) {
|
||||||
const body = { [key]: data };
|
const body = { [key]: data };
|
||||||
return this.submitting(
|
return this.submitting(this.client.action(id, body));
|
||||||
request.post(`${this.getDetailUrl({ id })}/action`, body)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
@ -150,7 +154,7 @@ export class VolumeStore extends Base {
|
|||||||
|
|
||||||
@action
|
@action
|
||||||
revert(id, data) {
|
revert(id, data) {
|
||||||
return this.operation(id, data, 'revert');
|
return this.operation(id, data, 'revert_any');
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
@ -171,45 +175,36 @@ export class VolumeStore extends Base {
|
|||||||
@action
|
@action
|
||||||
update(id, data) {
|
update(id, data) {
|
||||||
const body = { [this.responseKey]: data };
|
const body = { [this.responseKey]: data };
|
||||||
return this.submitting(request.put(this.getDetailUrl({ id }), body));
|
return this.submitting(this.client.update(id, body));
|
||||||
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
softDelete(id, data) {
|
||||||
|
return this.operation(id, data, 'os-recycle');
|
||||||
|
}
|
||||||
|
|
||||||
|
restore(id) {
|
||||||
|
return this.operation(id, {}, 'os-restore-recycle');
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
createTransfer(data) {
|
createTransfer(data) {
|
||||||
const body = { transfer: data };
|
const body = { transfer: data };
|
||||||
return this.submitting(
|
return this.submitting(this.transferClient.create(body));
|
||||||
request.post(
|
|
||||||
`${this.apiVersion}/${globals.user.project.id}/volume-transfers`,
|
|
||||||
body
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
cancelTransfer({ id }) {
|
cancelTransfer({ id }) {
|
||||||
return this.submitting(
|
return this.submitting(this.transferClient.list()).then((resData) => {
|
||||||
request.get(
|
|
||||||
`${this.apiVersion}/${globals.user.project.id}/volume-transfers`
|
|
||||||
)
|
|
||||||
).then((resData) => {
|
|
||||||
const findObj = (resData.transfers || []).find((s) => s.volume_id === id);
|
const findObj = (resData.transfers || []).find((s) => s.volume_id === id);
|
||||||
return this.submitting(
|
return this.submitting(this.transferClient.delete(findObj.id));
|
||||||
request.delete(
|
|
||||||
`${this.apiVersion}/${globals.user.project.id}/volume-transfers/${findObj.id}`
|
|
||||||
)
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
acceptVolumeTransfer(transfer_id, data) {
|
acceptVolumeTransfer(transfer_id, data) {
|
||||||
const body = { accept: data };
|
const body = { accept: data };
|
||||||
return this.submitting(
|
return this.submitting(this.transferClient.accept(transfer_id, body));
|
||||||
request.post(
|
|
||||||
`${this.apiVersion}/${globals.user.project.id}/volume-transfers/${transfer_id}/accept`,
|
|
||||||
body
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
@ -225,3 +220,5 @@ export class VolumeStore extends Base {
|
|||||||
|
|
||||||
const globalVolumeStore = new VolumeStore();
|
const globalVolumeStore = new VolumeStore();
|
||||||
export default globalVolumeStore;
|
export default globalVolumeStore;
|
||||||
|
|
||||||
|
export const globalRecycleVolumeStore = new VolumeStore();
|
||||||
|
@ -12,32 +12,18 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { glanceBase } from 'utils/constants';
|
|
||||||
import { action, observable } from 'mobx';
|
import { action, observable } from 'mobx';
|
||||||
|
import client from 'client';
|
||||||
import Base from '../base';
|
import Base from '../base';
|
||||||
// import { getArrayBuffer } from 'utils/file';
|
|
||||||
|
|
||||||
export class ImageStore extends Base {
|
export class ImageStore extends Base {
|
||||||
@observable
|
@observable
|
||||||
members = [];
|
members = [];
|
||||||
|
|
||||||
get module() {
|
get client() {
|
||||||
return 'images';
|
return client.glance.images;
|
||||||
}
|
}
|
||||||
|
|
||||||
get apiVersion() {
|
|
||||||
return glanceBase();
|
|
||||||
}
|
|
||||||
|
|
||||||
get responseKey() {
|
|
||||||
return 'image';
|
|
||||||
}
|
|
||||||
|
|
||||||
// get listFilterByProject() {
|
|
||||||
// // use it for nuetron apois
|
|
||||||
// return true;
|
|
||||||
// }
|
|
||||||
|
|
||||||
get fetchListByLimit() {
|
get fetchListByLimit() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -46,9 +32,16 @@ export class ImageStore extends Base {
|
|||||||
return this.paramsFuncPage;
|
return this.paramsFuncPage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateParamsSortPage = (params, sortKey, sortOrder) => {
|
||||||
|
if (sortKey && sortOrder) {
|
||||||
|
params.sort_key = sortKey;
|
||||||
|
params.sort_dir = sortOrder === 'descend' ? 'desc' : 'asc';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
get paramsFuncPage() {
|
get paramsFuncPage() {
|
||||||
return (params) => {
|
return (params) => {
|
||||||
const { current, all_projects, ...rest } = params;
|
const { current, all_projects, withPrice, ...rest } = params;
|
||||||
return {
|
return {
|
||||||
...rest,
|
...rest,
|
||||||
// image_type: 'image',
|
// image_type: 'image',
|
||||||
@ -73,50 +66,32 @@ export class ImageStore extends Base {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
async uploadImage(imageId, file) {
|
async uploadImage(imageId, file, conf) {
|
||||||
const url = `${this.getListUrl()}/${imageId}/file`;
|
return this.client.uploadFile(imageId, file, conf);
|
||||||
// const body = await getArrayBuffer(file);
|
|
||||||
const body = file;
|
|
||||||
const headers = {
|
|
||||||
'content-type': 'application/octet-stream',
|
|
||||||
};
|
|
||||||
|
|
||||||
const options = {
|
|
||||||
headers,
|
|
||||||
};
|
|
||||||
return request.put(url, body, options);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
async create(data, file, members) {
|
async create(data, file, members, conf) {
|
||||||
this.isSubmitting = true;
|
this.isSubmitting = true;
|
||||||
const image = await request.post(this.getListUrl(), data);
|
const image = await this.client.create(data);
|
||||||
const { id } = image;
|
const { id } = image;
|
||||||
// return this.submitting(this.uploadImage(id, file));
|
// return this.submitting(this.uploadImage(id, file));
|
||||||
if (members.length > 0) {
|
if (members.length > 0) {
|
||||||
await Promise.all(members.map((it) => this.createMember(id, it)));
|
await Promise.all(members.map((it) => this.createMember(id, it)));
|
||||||
}
|
}
|
||||||
await this.uploadImage(id, file);
|
await this.uploadImage(id, file, conf);
|
||||||
this.isSubmitting = false;
|
this.isSubmitting = false;
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
async update({ id }, newbody) {
|
async update({ id }, newbody) {
|
||||||
const url = this.getDetailUrl({ id });
|
return this.client.patch(id, newbody);
|
||||||
const headers = {
|
|
||||||
'content-type': 'application/openstack-images-v2.1-json-patch',
|
|
||||||
};
|
|
||||||
const options = {
|
|
||||||
headers,
|
|
||||||
};
|
|
||||||
return request.patch(url, newbody, options);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
async getMembers(id) {
|
async getMembers(id) {
|
||||||
const url = `${this.getDetailUrl({ id })}/members`;
|
const result = await this.client.members.list(id);
|
||||||
const result = await request.get(url);
|
|
||||||
const { members = [] } = result || {};
|
const { members = [] } = result || {};
|
||||||
this.members = members;
|
this.members = members;
|
||||||
return members;
|
return members;
|
||||||
@ -124,27 +99,24 @@ export class ImageStore extends Base {
|
|||||||
|
|
||||||
@action
|
@action
|
||||||
async createMember(id, member) {
|
async createMember(id, member) {
|
||||||
const url = `${this.getDetailUrl({ id })}/members`;
|
|
||||||
const body = {
|
const body = {
|
||||||
member,
|
member,
|
||||||
};
|
};
|
||||||
await request.post(url, body);
|
await this.client.members.create(id, body);
|
||||||
return this.updateMemberStatus(id, member, 'accepted');
|
return this.updateMemberStatus(id, member, 'accepted');
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
async updateMemberStatus(id, member, status) {
|
async updateMemberStatus(id, member, status) {
|
||||||
const url = `${this.getDetailUrl({ id })}/members/${member}`;
|
|
||||||
const body = {
|
const body = {
|
||||||
status,
|
status,
|
||||||
};
|
};
|
||||||
return request.put(url, body);
|
return this.client.members.update(id, member, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
async deleteMember(id, member) {
|
async deleteMember(id, member) {
|
||||||
const url = `${this.getDetailUrl({ id })}/members/${member}`;
|
return this.client.members.delete(id, member);
|
||||||
return request.delete(url);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
|
@ -12,20 +12,12 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { glanceBase, cinderBase, novaBase } from 'utils/constants';
|
import client from 'client';
|
||||||
import Base from '../base';
|
import Base from '../base';
|
||||||
|
|
||||||
export class InstanceSnapshotStore extends Base {
|
export class InstanceSnapshotStore extends Base {
|
||||||
get module() {
|
get client() {
|
||||||
return 'images';
|
return client.glance.images;
|
||||||
}
|
|
||||||
|
|
||||||
get apiVersion() {
|
|
||||||
return glanceBase();
|
|
||||||
}
|
|
||||||
|
|
||||||
get responseKey() {
|
|
||||||
return 'image';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get listFilterByProject() {
|
get listFilterByProject() {
|
||||||
@ -49,18 +41,26 @@ export class InstanceSnapshotStore extends Base {
|
|||||||
|
|
||||||
get paramsFuncPage() {
|
get paramsFuncPage() {
|
||||||
return (params, all_projects) => {
|
return (params, all_projects) => {
|
||||||
const { id, current, ...rest } = params;
|
const { id, current, owner, ...rest } = params;
|
||||||
const newParams = {
|
const newParams = {
|
||||||
...rest,
|
...rest,
|
||||||
// image_type: 'snapshot',
|
image_type: 'snapshot',
|
||||||
};
|
};
|
||||||
if (!all_projects) {
|
if (owner) {
|
||||||
newParams.owner = this.currentProject;
|
newParams.owner = owner;
|
||||||
|
} else if (!all_projects) {
|
||||||
|
newParams.owner = this.currentProjectId;
|
||||||
}
|
}
|
||||||
return newParams;
|
return newParams;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getCountForPage(params) {
|
||||||
|
const { limit, marker, ...rest } = params;
|
||||||
|
const result = await this.client.count(rest);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
get mapperBeforeFetchProject() {
|
get mapperBeforeFetchProject() {
|
||||||
return (data) => ({
|
return (data) => ({
|
||||||
...data,
|
...data,
|
||||||
@ -76,13 +76,11 @@ export class InstanceSnapshotStore extends Base {
|
|||||||
if (!id) {
|
if (!id) {
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
const snapshotsUrl = `${cinderBase()}/${globals.user.project.id}/snapshots`;
|
|
||||||
const volumesUrl = `${novaBase()}/servers/${id}/os-volume_attachments`;
|
|
||||||
const volumeParams = {};
|
const volumeParams = {};
|
||||||
const snapshotParams = { all_tenants: allProjects };
|
const snapshotParams = { all_tenants: allProjects };
|
||||||
const results = await Promise.all([
|
const results = await Promise.all([
|
||||||
request.get(snapshotsUrl, snapshotParams),
|
client.cinder.snapshots.list(snapshotParams),
|
||||||
request.get(volumesUrl, volumeParams),
|
client.nova.servers.volumeAttachments.list(id, volumeParams),
|
||||||
]);
|
]);
|
||||||
const snapshotsAll = results[0].snapshots;
|
const snapshotsAll = results[0].snapshots;
|
||||||
const volumesAll = results[1].volumeAttachments;
|
const volumesAll = results[1].volumeAttachments;
|
||||||
@ -121,16 +119,11 @@ export class InstanceSnapshotStore extends Base {
|
|||||||
if (snapshot) {
|
if (snapshot) {
|
||||||
const { snapshot_id: snapshotId } = snapshot;
|
const { snapshot_id: snapshotId } = snapshot;
|
||||||
item.snapshotId = snapshotId;
|
item.snapshotId = snapshotId;
|
||||||
const currentProject = globals.user.project.id;
|
const snapshotResult = await client.cinder.snapshots.show(snapshotId);
|
||||||
const snapshotsUrl = `${cinderBase()}/${currentProject}/snapshots/${snapshotId}`;
|
|
||||||
const snapshotResult = await request.get(snapshotsUrl);
|
|
||||||
const snapshotDetail = snapshotResult.snapshot;
|
const snapshotDetail = snapshotResult.snapshot;
|
||||||
item.snapshotDetail = snapshotDetail;
|
item.snapshotDetail = snapshotDetail;
|
||||||
const { volume_id: volumeId } = snapshotDetail;
|
const { volume_id: volumeId } = snapshotDetail;
|
||||||
const volumeUrl = `${cinderBase()}/${
|
const volumeResult = await client.cinder.volumes.show(volumeId);
|
||||||
globals.user.project.id
|
|
||||||
}/volumes/${volumeId}`;
|
|
||||||
const volumeResult = await await request.get(volumeUrl);
|
|
||||||
const volumeDetail = volumeResult.volume;
|
const volumeDetail = volumeResult.volume;
|
||||||
item.volumeDetail = volumeDetail;
|
item.volumeDetail = volumeDetail;
|
||||||
instanceId =
|
instanceId =
|
||||||
@ -142,10 +135,10 @@ export class InstanceSnapshotStore extends Base {
|
|||||||
const { instance_uuid } = item;
|
const { instance_uuid } = item;
|
||||||
instanceId = instance_uuid;
|
instanceId = instance_uuid;
|
||||||
}
|
}
|
||||||
|
let instanceResult = {};
|
||||||
try {
|
try {
|
||||||
if (instanceId) {
|
if (instanceId) {
|
||||||
const instanceUrl = `${novaBase()}/servers/${instanceId}`;
|
instanceResult = await client.nova.servers.show(instanceId);
|
||||||
const instanceResult = await request.get(instanceUrl);
|
|
||||||
const { server: { name } = {} } = instanceResult;
|
const { server: { name } = {} } = instanceResult;
|
||||||
instanceName = name;
|
instanceName = name;
|
||||||
}
|
}
|
||||||
@ -154,6 +147,7 @@ export class InstanceSnapshotStore extends Base {
|
|||||||
server_id: instanceId,
|
server_id: instanceId,
|
||||||
server_name: instanceName,
|
server_name: instanceName,
|
||||||
};
|
};
|
||||||
|
item.instanceDetail = instanceResult.server || {};
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,24 +12,23 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { glanceBase } from 'utils/constants';
|
|
||||||
import { action, observable } from 'mobx';
|
import { action, observable } from 'mobx';
|
||||||
|
import client from 'client';
|
||||||
import Base from '../base';
|
import Base from '../base';
|
||||||
|
|
||||||
export class MetadataStore extends Base {
|
export class MetadataStore extends Base {
|
||||||
@observable
|
@observable
|
||||||
resourceTypes = [];
|
resourceTypes = [];
|
||||||
|
|
||||||
get module() {
|
@observable
|
||||||
return 'metadefs/namespaces';
|
resourceTypeLoading = false;
|
||||||
|
|
||||||
|
get client() {
|
||||||
|
return client.glance.namespaces;
|
||||||
}
|
}
|
||||||
|
|
||||||
get apiVersion() {
|
get resourceTypeClient() {
|
||||||
return glanceBase();
|
return client.glance.resourceTypes;
|
||||||
}
|
|
||||||
|
|
||||||
get responseKey() {
|
|
||||||
return 'namespace';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get needGetProject() {
|
get needGetProject() {
|
||||||
@ -44,9 +43,7 @@ export class MetadataStore extends Base {
|
|||||||
const results = await Promise.all(
|
const results = await Promise.all(
|
||||||
items.map((it) => {
|
items.map((it) => {
|
||||||
const { namespace } = it;
|
const { namespace } = it;
|
||||||
return request.get(this.getDetailUrl({ id: namespace }), {
|
return this.client.show(namespace, { resource_type: resource_types });
|
||||||
resource_type: resource_types,
|
|
||||||
});
|
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
items.forEach((it, index) => {
|
items.forEach((it, index) => {
|
||||||
@ -95,7 +92,7 @@ export class MetadataStore extends Base {
|
|||||||
@action
|
@action
|
||||||
async fetchDetail({ id }) {
|
async fetchDetail({ id }) {
|
||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
const result = await request.get(this.getDetailUrl({ id }));
|
const result = await this.client.show(id);
|
||||||
this.detail = result;
|
this.detail = result;
|
||||||
this.isLoading = false;
|
this.isLoading = false;
|
||||||
return result;
|
return result;
|
||||||
@ -103,20 +100,18 @@ export class MetadataStore extends Base {
|
|||||||
|
|
||||||
@action
|
@action
|
||||||
edit({ id }, newObject) {
|
edit({ id }, newObject) {
|
||||||
return this.submitting(
|
return this.submitting(this.client.update(id, newObject));
|
||||||
request.put(`${this.getDetailUrl({ id })}`, newObject)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
create(newObject) {
|
create(newObject) {
|
||||||
return this.submitting(request.post(`${this.getListUrl()}`, newObject));
|
return this.submitting(this.client.create(newObject));
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
async fetchResourceTypes(item) {
|
async fetchResourceTypes(item) {
|
||||||
const url = `${this.apiVersion}/metadefs/resource_types`;
|
this.resourceTypeLoading = true;
|
||||||
const result = await request.get(url);
|
const result = await this.resourceTypeClient.list();
|
||||||
const { resource_type_associations: associations = [] } = item || {};
|
const { resource_type_associations: associations = [] } = item || {};
|
||||||
const { resource_types: resourceTypes = [] } = result;
|
const { resource_types: resourceTypes = [] } = result;
|
||||||
const mapper = {};
|
const mapper = {};
|
||||||
@ -130,6 +125,7 @@ export class MetadataStore extends Base {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.resourceTypes = resourceTypes;
|
this.resourceTypes = resourceTypes;
|
||||||
|
this.resourceTypeLoading = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
@ -137,11 +133,9 @@ export class MetadataStore extends Base {
|
|||||||
this.isSubmitting = true;
|
this.isSubmitting = true;
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
dels.map((it) => {
|
dels.map((it) => {
|
||||||
const delUrl = `${this.apiVersion}/${this.module}/${namespace}/resource_types/${it.name}`;
|
return this.client.resourceTypes.delete(namespace, it.name);
|
||||||
return request.delete(delUrl);
|
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
const addUrl = `${this.apiVersion}/${this.module}/${namespace}/resource_types`;
|
|
||||||
return this.submitting(
|
return this.submitting(
|
||||||
Promise.all(
|
Promise.all(
|
||||||
adds.map((it) => {
|
adds.map((it) => {
|
||||||
@ -149,7 +143,7 @@ export class MetadataStore extends Base {
|
|||||||
name: it.name,
|
name: it.name,
|
||||||
prefix: it.prefix,
|
prefix: it.prefix,
|
||||||
};
|
};
|
||||||
return request.post(addUrl, body);
|
return this.client.resourceTypes.create(namespace, body);
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
@ -12,27 +12,22 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { heatBase } from 'utils/constants';
|
import client from 'client';
|
||||||
import Base from '../base';
|
import Base from '../base';
|
||||||
|
|
||||||
export class StackEventStore extends Base {
|
export class StackEventStore extends Base {
|
||||||
get module() {
|
get client() {
|
||||||
if (!globals.user) {
|
return client.heat.stacks;
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return `${globals.user.project.id}/stacks`;
|
|
||||||
}
|
|
||||||
|
|
||||||
get apiVersion() {
|
|
||||||
return heatBase();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get responseKey() {
|
get responseKey() {
|
||||||
return 'event';
|
return 'event';
|
||||||
}
|
}
|
||||||
|
|
||||||
getListUrl = ({ id, name }) =>
|
listFetchByClient(params, originParams) {
|
||||||
`${this.apiVersion}/${this.module}/${name}/${id}/events`;
|
const { id, name } = originParams;
|
||||||
|
return this.client.events({ id, name }, params);
|
||||||
|
}
|
||||||
|
|
||||||
get paramsFunc() {
|
get paramsFunc() {
|
||||||
return () => {};
|
return () => {};
|
||||||
|
@ -12,27 +12,22 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { heatBase } from 'utils/constants';
|
import client from 'client';
|
||||||
import Base from '../base';
|
import Base from '../base';
|
||||||
|
|
||||||
export class StackResourceStore extends Base {
|
export class StackResourceStore extends Base {
|
||||||
get module() {
|
get client() {
|
||||||
if (!globals.user) {
|
return client.heat.stacks;
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return `${globals.user.project.id}/stacks`;
|
|
||||||
}
|
|
||||||
|
|
||||||
get apiVersion() {
|
|
||||||
return heatBase();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get responseKey() {
|
get responseKey() {
|
||||||
return 'resource';
|
return 'resource';
|
||||||
}
|
}
|
||||||
|
|
||||||
getListUrl = ({ id, name }) =>
|
listFetchByClient(params, originParams) {
|
||||||
`${this.apiVersion}/${this.module}/${name}/${id}/resources`;
|
const { id, name } = originParams;
|
||||||
|
return this.client.resources({ id, name }, params);
|
||||||
|
}
|
||||||
|
|
||||||
get paramsFunc() {
|
get paramsFunc() {
|
||||||
return () => {};
|
return () => {};
|
||||||
|
@ -12,24 +12,13 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { heatBase } from 'utils/constants';
|
import client from 'client';
|
||||||
import Base from '../base';
|
import Base from '../base';
|
||||||
|
|
||||||
export class HeatServiceStore extends Base {
|
export class HeatServiceStore extends Base {
|
||||||
get module() {
|
get client() {
|
||||||
return 'services';
|
return client.heat.services;
|
||||||
}
|
}
|
||||||
|
|
||||||
get apiVersion() {
|
|
||||||
return heatBase();
|
|
||||||
}
|
|
||||||
|
|
||||||
get responseKey() {
|
|
||||||
return 'service';
|
|
||||||
}
|
|
||||||
|
|
||||||
getListUrl = () =>
|
|
||||||
`${this.apiVersion}/${globals.user.project.id}/${this.module}`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const globalHeatServiceStore = new HeatServiceStore();
|
const globalHeatServiceStore = new HeatServiceStore();
|
||||||
|
@ -13,26 +13,20 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { action, observable } from 'mobx';
|
import { action, observable } from 'mobx';
|
||||||
import { heatBase } from 'utils/constants';
|
import client from 'client';
|
||||||
import Base from '../base';
|
import Base from '../base';
|
||||||
|
|
||||||
export class StackStore extends Base {
|
export class StackStore extends Base {
|
||||||
@observable
|
@observable
|
||||||
template = {};
|
template = null;
|
||||||
|
|
||||||
get module() {
|
get client() {
|
||||||
if (!globals.user) {
|
return client.heat.stacks;
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return `${globals.user.project.id}/stacks`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get apiVersion() {
|
detailFetchByClient(resourceParams) {
|
||||||
return heatBase();
|
const { id, name } = resourceParams;
|
||||||
}
|
return this.client.show({ id, name });
|
||||||
|
|
||||||
get responseKey() {
|
|
||||||
return 'stack';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
updateParamsSortPage = (params, sortKey, sortOrder) => {
|
updateParamsSortPage = (params, sortKey, sortOrder) => {
|
||||||
@ -42,8 +36,6 @@ export class StackStore extends Base {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
getDetailUrl = ({ id, name }) => `${this.getListUrl()}/${name}/${id}`;
|
|
||||||
|
|
||||||
get paramsFuncPage() {
|
get paramsFuncPage() {
|
||||||
return (params) => {
|
return (params) => {
|
||||||
const { current, all_projects, ...rest } = params;
|
const { current, all_projects, ...rest } = params;
|
||||||
@ -54,7 +46,7 @@ export class StackStore extends Base {
|
|||||||
if (all_projects) {
|
if (all_projects) {
|
||||||
newParams.global_tenant = true;
|
newParams.global_tenant = true;
|
||||||
} else {
|
} else {
|
||||||
newParams.tenant = globals.user.project.id;
|
newParams.tenant = this.currentProjectId;
|
||||||
}
|
}
|
||||||
return newParams;
|
return newParams;
|
||||||
};
|
};
|
||||||
@ -76,28 +68,25 @@ export class StackStore extends Base {
|
|||||||
|
|
||||||
@action
|
@action
|
||||||
create(body) {
|
create(body) {
|
||||||
return this.submitting(request.post(this.getListUrl(), body));
|
return this.submitting(this.client.create(body));
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
edit({ id, name }, body) {
|
edit({ id, name }, body) {
|
||||||
return this.submitting(request.put(this.getDetailUrl({ id, name }), body));
|
return this.submitting(this.client.update({ id, name }, body));
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
delete = ({ id, name }) =>
|
delete = ({ id, name }) => this.submitting(this.client.delete({ id, name }));
|
||||||
this.submitting(request.delete(this.getDetailUrl({ id, name })));
|
|
||||||
|
|
||||||
@action
|
@action
|
||||||
abandon = ({ id, name }) => {
|
abandon = ({ id, name }) => {
|
||||||
const url = `${this.getDetailUrl({ id, name })}/abandon`;
|
return this.submitting(this.client.abandon({ id, name }));
|
||||||
return this.submitting(request.delete(url));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@action
|
@action
|
||||||
getTemplate = async ({ id, name }) => {
|
getTemplate = async ({ id, name }) => {
|
||||||
const url = `${this.getDetailUrl({ id, name })}/template`;
|
const result = await this.client.template({ id, name });
|
||||||
const result = await request.get(url);
|
|
||||||
this.template = result;
|
this.template = result;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
43
src/stores/index.jsx
Normal file
43
src/stores/index.jsx
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import globalFloatingIpsStore from './neutron/floatingIp';
|
||||||
|
import globalImageStore from './glance/image';
|
||||||
|
import globalServerStore from './nova/instance';
|
||||||
|
import globalInstanceSnapshotStore from './glance/instance-snapshot';
|
||||||
|
import globalKeypairStore from './nova/keypair';
|
||||||
|
import globalNetworkStore from './neutron/network';
|
||||||
|
import globalPortForwardingStore from './neutron/port-forwarding';
|
||||||
|
import globalQoSPolicyStore from './neutron/qos-policy';
|
||||||
|
import globalRecycleBinStore from './skyline/recycle-server';
|
||||||
|
import globalSecurityGroupStore from './neutron/security-group';
|
||||||
|
import globalSecurityGroupRuleStore from './neutron/security-rule';
|
||||||
|
import globalServerGroupStore from './nova/server-group';
|
||||||
|
import globalSnapshotStore from './cinder/snapshot';
|
||||||
|
import globalStaticRouteStore from './neutron/static-route';
|
||||||
|
import globalSubnetStore from './neutron/subnet';
|
||||||
|
import globalVirtualAdapterStore from './neutron/virtual-adapter';
|
||||||
|
import globalVolumeStore from './cinder/volume';
|
||||||
|
import globalComputeHostStore from './nova/compute-host';
|
||||||
|
import globalHypervisorStore from './nova/hypervisor';
|
||||||
|
import globalStackStore from './heat/stack';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
globalFloatingIpsStore,
|
||||||
|
globalImageStore,
|
||||||
|
globalServerStore,
|
||||||
|
globalInstanceSnapshotStore,
|
||||||
|
globalKeypairStore,
|
||||||
|
globalNetworkStore,
|
||||||
|
globalPortForwardingStore,
|
||||||
|
globalQoSPolicyStore,
|
||||||
|
globalRecycleBinStore,
|
||||||
|
globalSecurityGroupStore,
|
||||||
|
globalSecurityGroupRuleStore,
|
||||||
|
globalServerGroupStore,
|
||||||
|
globalSnapshotStore,
|
||||||
|
globalStaticRouteStore,
|
||||||
|
globalSubnetStore,
|
||||||
|
globalVirtualAdapterStore,
|
||||||
|
globalVolumeStore,
|
||||||
|
globalComputeHostStore,
|
||||||
|
globalHypervisorStore,
|
||||||
|
globalStackStore,
|
||||||
|
};
|
@ -13,7 +13,7 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { action, observable } from 'mobx';
|
import { action, observable } from 'mobx';
|
||||||
import { ironicBase, placementBase } from 'utils/constants';
|
import client from 'client';
|
||||||
import Base from '../base';
|
import Base from '../base';
|
||||||
|
|
||||||
export class IronicStore extends Base {
|
export class IronicStore extends Base {
|
||||||
@ -26,20 +26,18 @@ export class IronicStore extends Base {
|
|||||||
@observable
|
@observable
|
||||||
traits = [];
|
traits = [];
|
||||||
|
|
||||||
get module() {
|
get client() {
|
||||||
return 'nodes';
|
return client.ironic.nodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
get apiVersion() {
|
get portClient() {
|
||||||
return ironicBase();
|
return client.ironic.ports;
|
||||||
}
|
}
|
||||||
|
|
||||||
get responseKey() {
|
get listWithDetail() {
|
||||||
return 'node';
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
getListDetailUrl = () => `${this.getListUrl()}/detail`;
|
|
||||||
|
|
||||||
async detailDidFetch(item, all_projects, params) {
|
async detailDidFetch(item, all_projects, params) {
|
||||||
if (params.onlyDetail) {
|
if (params.onlyDetail) {
|
||||||
return item;
|
return item;
|
||||||
@ -48,9 +46,9 @@ export class IronicStore extends Base {
|
|||||||
const newItem = { ...item };
|
const newItem = { ...item };
|
||||||
const [bootDevice, states, validate, ports] = await Promise.all([
|
const [bootDevice, states, validate, ports] = await Promise.all([
|
||||||
this.getBootDevice(id),
|
this.getBootDevice(id),
|
||||||
request.get(`${this.getDetailUrl({ id })}/states`),
|
this.client.states.list(id),
|
||||||
request.get(`${this.getDetailUrl({ id })}/validate`),
|
this.client.validate.list(id),
|
||||||
request.get(`${this.getDetailUrl({ id })}/ports`),
|
this.client.ports.list(id),
|
||||||
]);
|
]);
|
||||||
newItem.bootDevice = bootDevice;
|
newItem.bootDevice = bootDevice;
|
||||||
newItem.states = states;
|
newItem.states = states;
|
||||||
@ -63,8 +61,7 @@ export class IronicStore extends Base {
|
|||||||
if (items.length === 0) {
|
if (items.length === 0) {
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
const url = `${this.apiVersion}/ports/detail`;
|
const result = await this.portClient.listDetail();
|
||||||
const result = await request.get(url);
|
|
||||||
const { ports } = result;
|
const { ports } = result;
|
||||||
items.forEach((it) => {
|
items.forEach((it) => {
|
||||||
const nodePorts = ports.filter((port) => port.node_uuid === it.uuid);
|
const nodePorts = ports.filter((port) => port.node_uuid === it.uuid);
|
||||||
@ -75,33 +72,30 @@ export class IronicStore extends Base {
|
|||||||
|
|
||||||
@action
|
@action
|
||||||
changeProvision(id, body) {
|
changeProvision(id, body) {
|
||||||
const url = `${this.getDetailUrl({ id })}/states/provision`;
|
return this.submitting(this.client.updateStatesProvision(id, body));
|
||||||
return this.submitting(request.put(url, body));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
changePower(id, body) {
|
changePower(id, body) {
|
||||||
const url = `${this.getDetailUrl({ id })}/states/power`;
|
return this.submitting(this.client.UpdateStatesPower(id, body));
|
||||||
return this.submitting(request.put(url, body));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
setMaintenance(id, body) {
|
setMaintenance(id, body) {
|
||||||
const url = `${this.getDetailUrl({ id })}/maintenance`;
|
return this.submitting(this.client.updateMaintenance(id, body));
|
||||||
return this.submitting(request.put(url, body));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
clearMaintenance(id) {
|
clearMaintenance(id) {
|
||||||
const url = `${this.getDetailUrl({ id })}/maintenance`;
|
return this.submitting(this.client.deleteMaintenance(id));
|
||||||
return this.submitting(request.delete(url));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
async getBootDevice(id) {
|
async getBootDevice(id) {
|
||||||
const url = `${this.getDetailUrl({ id })}/management/boot_device`;
|
|
||||||
try {
|
try {
|
||||||
const result = await this.submitting(request.get(url));
|
const result = await this.submitting(
|
||||||
|
this.client.getManagementBootDevice(id)
|
||||||
|
);
|
||||||
this.bootDevice = result;
|
this.bootDevice = result;
|
||||||
return result;
|
return result;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -113,39 +107,38 @@ export class IronicStore extends Base {
|
|||||||
|
|
||||||
@action
|
@action
|
||||||
async getSupportedBootDevice(id) {
|
async getSupportedBootDevice(id) {
|
||||||
const url = `${this.getDetailUrl({ id })}/management/boot_device/supported`;
|
const result = await this.submitting(
|
||||||
const result = await this.submitting(request.get(url));
|
this.client.getManagementBootDeviceSupported(id)
|
||||||
|
);
|
||||||
this.supportedBootDevices = result.supported_boot_devices || [];
|
this.supportedBootDevices = result.supported_boot_devices || [];
|
||||||
return this.supportedBootDevices;
|
return this.supportedBootDevices;
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
setBootDevice(id, body) {
|
setBootDevice(id, body) {
|
||||||
const url = `${this.getDetailUrl({ id })}/management/boot_device`;
|
return this.submitting(this.client.upateManagementBootDevice(id, body));
|
||||||
return this.submitting(request.put(url, body));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
async create(body) {
|
async create(body) {
|
||||||
const { traits = [], ...rest } = body;
|
const { traits = [], ...rest } = body;
|
||||||
if (traits.length === 0) {
|
if (traits.length === 0) {
|
||||||
return this.submitting(request.post(this.getListUrl(), rest));
|
return this.submitting(this.client.create(rest));
|
||||||
}
|
}
|
||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
const result = await request.post(this.getListUrl(), rest);
|
const result = await this.client.create(rest);
|
||||||
const { uuid } = result;
|
const { uuid } = result;
|
||||||
return this.updateTraits(uuid, traits);
|
return this.updateTraits(uuid, traits);
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
edit({ id }, body) {
|
edit({ id }, body) {
|
||||||
return this.submitting(request.patch(`${this.getDetailUrl({ id })}`, body));
|
return this.submitting(this.client.patch(id, body));
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
async getTraits() {
|
async getTraits() {
|
||||||
const url = `${placementBase()}/traits`;
|
const result = await client.placement.traits.list();
|
||||||
const result = await request.get(url);
|
|
||||||
const { traits = [] } = result;
|
const { traits = [] } = result;
|
||||||
traits.sort();
|
traits.sort();
|
||||||
this.traits = traits;
|
this.traits = traits;
|
||||||
@ -153,11 +146,10 @@ export class IronicStore extends Base {
|
|||||||
|
|
||||||
@action
|
@action
|
||||||
updateTraits(id, traits) {
|
updateTraits(id, traits) {
|
||||||
const url = `${this.getDetailUrl({ id })}/traits`;
|
|
||||||
const body = {
|
const body = {
|
||||||
traits,
|
traits,
|
||||||
};
|
};
|
||||||
return this.submitting(request.put(url, body));
|
return this.submitting(this.client.updateTraits(id, body));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,38 +12,32 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { ironicBase } from 'utils/constants';
|
|
||||||
import { action } from 'mobx';
|
import { action } from 'mobx';
|
||||||
|
import client from 'client';
|
||||||
import Base from '../base';
|
import Base from '../base';
|
||||||
|
|
||||||
export class IronicPortGroupStore extends Base {
|
export class IronicPortGroupStore extends Base {
|
||||||
get module() {
|
get client() {
|
||||||
return 'portgroups';
|
return client.ironic.nodes.portgroups;
|
||||||
}
|
}
|
||||||
|
|
||||||
get apiVersion() {
|
listFetchByClient(params, originParams) {
|
||||||
return ironicBase();
|
const { id } = originParams;
|
||||||
|
return this.client.listDetail(id, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
get responseKey() {
|
|
||||||
return 'portgroup';
|
|
||||||
}
|
|
||||||
|
|
||||||
getListDetailUrl = ({ id }) =>
|
|
||||||
`${this.apiVersion}/nodes/${id}/${this.module}/detail`;
|
|
||||||
|
|
||||||
get paramsFunc() {
|
get paramsFunc() {
|
||||||
return () => {};
|
return () => {};
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
create(data) {
|
create(data) {
|
||||||
return this.submitting(request.post(this.getListUrl(), data));
|
return this.submitting(client.ironic.portgroups.create(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
edit({ id }, body) {
|
edit({ id }, body) {
|
||||||
return this.submitting(request.patch(`${this.getDetailUrl({ id })}`, body));
|
return this.submitting(client.ironic.portgroups.patch(id, body));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,38 +12,32 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { ironicBase } from 'utils/constants';
|
|
||||||
import { action } from 'mobx';
|
import { action } from 'mobx';
|
||||||
|
import client from 'client';
|
||||||
import Base from '../base';
|
import Base from '../base';
|
||||||
|
|
||||||
export class IronicPortStore extends Base {
|
export class IronicPortStore extends Base {
|
||||||
get module() {
|
get client() {
|
||||||
return 'ports';
|
return client.ironic.ports;
|
||||||
}
|
}
|
||||||
|
|
||||||
get apiVersion() {
|
listFetchByClient(params, originParams) {
|
||||||
return ironicBase();
|
const { id } = originParams;
|
||||||
|
return client.ironic.nodes.ports.listDetail(id, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
get responseKey() {
|
|
||||||
return 'port';
|
|
||||||
}
|
|
||||||
|
|
||||||
getListDetailUrl = ({ id }) =>
|
|
||||||
`${this.apiVersion}/nodes/${id}/${this.module}/detail`;
|
|
||||||
|
|
||||||
get paramsFunc() {
|
get paramsFunc() {
|
||||||
return () => {};
|
return () => {};
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
create(data) {
|
create(data) {
|
||||||
return this.submitting(request.post(this.getListUrl(), data));
|
return this.submitting(this.client.create(data));
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
edit({ id }, body) {
|
edit({ id }, body) {
|
||||||
return this.submitting(request.patch(`${this.getDetailUrl({ id })}`, body));
|
return this.submitting(this.client.patch(id, body));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,20 +12,16 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { keystoneBase } from 'utils/constants';
|
import client from 'client';
|
||||||
import Base from '../base';
|
import Base from '../base';
|
||||||
|
|
||||||
export class AuthCatalogStore extends Base {
|
export class AuthCatalogStore extends Base {
|
||||||
get module() {
|
get client() {
|
||||||
return 'auth/catalog';
|
return client.keystone.catalog;
|
||||||
}
|
|
||||||
|
|
||||||
get apiVersion() {
|
|
||||||
return keystoneBase();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get listResponseKey() {
|
get listResponseKey() {
|
||||||
return 'catalog';
|
return this.responseKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
get mapper() {
|
get mapper() {
|
||||||
|
@ -13,9 +13,8 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { action, observable } from 'mobx';
|
import { action, observable } from 'mobx';
|
||||||
import request from 'utils/request';
|
|
||||||
import { keystoneBase } from 'utils/constants';
|
|
||||||
import { get } from 'lodash';
|
import { get } from 'lodash';
|
||||||
|
import client from 'client';
|
||||||
import Base from '../base';
|
import Base from '../base';
|
||||||
|
|
||||||
export class DomainStore extends Base {
|
export class DomainStore extends Base {
|
||||||
@ -28,20 +27,14 @@ export class DomainStore extends Base {
|
|||||||
@observable
|
@observable
|
||||||
adminRoleId = '';
|
adminRoleId = '';
|
||||||
|
|
||||||
get module() {
|
get client() {
|
||||||
return 'domains';
|
return client.keystone.domains;
|
||||||
}
|
}
|
||||||
|
|
||||||
get apiVersion() {
|
get userClient() {
|
||||||
return keystoneBase();
|
return client.keystone.users;
|
||||||
}
|
}
|
||||||
|
|
||||||
get responseKey() {
|
|
||||||
return 'domain';
|
|
||||||
}
|
|
||||||
|
|
||||||
getResourceUrl = () => keystoneBase();
|
|
||||||
|
|
||||||
@action
|
@action
|
||||||
async fetchList({
|
async fetchList({
|
||||||
limit,
|
limit,
|
||||||
@ -55,33 +48,32 @@ export class DomainStore extends Base {
|
|||||||
// todo: no page, no limit, fetch all
|
// todo: no page, no limit, fetch all
|
||||||
// const params = { ...filters };
|
// const params = { ...filters };
|
||||||
|
|
||||||
await Promise.all([
|
await Promise.all([this.client.list(), this.userClient.list()]).then(
|
||||||
request.get(`${this.apiVersion}/domains`),
|
([domainsResult, usersResult]) => {
|
||||||
request.get(`${this.apiVersion}/users`),
|
const { domains } = domainsResult;
|
||||||
]).then(([domainsResult, usersResult]) => {
|
// eslint-disable-next-line array-callback-return
|
||||||
const { domains } = domainsResult;
|
domains.map((domain) => {
|
||||||
// eslint-disable-next-line array-callback-return
|
const domainUsers = usersResult.users.filter(
|
||||||
domains.map((domain) => {
|
(it) => it.domain_id === domain.id
|
||||||
const domainUsers = usersResult.users.filter(
|
);
|
||||||
(it) => it.domain_id === domain.id
|
domain.user_num = domainUsers.length;
|
||||||
);
|
});
|
||||||
domain.user_num = domainUsers.length;
|
|
||||||
});
|
|
||||||
|
|
||||||
// const { domains: items } = domainsResult;
|
// const { domains: items } = domainsResult;
|
||||||
this.list.update({
|
this.list.update({
|
||||||
data: domains,
|
data: domains,
|
||||||
total: domains.length || 0,
|
total: domains.length || 0,
|
||||||
limit: Number(limit) || 10,
|
limit: Number(limit) || 10,
|
||||||
page: Number(page) || 1,
|
page: Number(page) || 1,
|
||||||
sortKey,
|
sortKey,
|
||||||
sortOrder,
|
sortOrder,
|
||||||
filters,
|
filters,
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
...(this.list.silent ? {} : { selectedRowKeys: [] }),
|
...(this.list.silent ? {} : { selectedRowKeys: [] }),
|
||||||
});
|
});
|
||||||
return domains;
|
return domains;
|
||||||
});
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
@ -89,74 +81,67 @@ export class DomainStore extends Base {
|
|||||||
if (!silent) {
|
if (!silent) {
|
||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
}
|
}
|
||||||
await Promise.all([
|
await Promise.all([this.client.show(id), this.userClient.list()]).then(
|
||||||
request.get(this.getDetailUrl({ id })),
|
([result, usersResult]) => {
|
||||||
request.get(`${this.apiVersion}/users`),
|
const domain = this.mapper(get(result, this.responseKey) || result);
|
||||||
]).then(([result, usersResult]) => {
|
domain.domain_administrator = [];
|
||||||
const domain = this.mapper(get(result, this.responseKey) || result);
|
const domainUsers = usersResult.users.filter(
|
||||||
domain.domain_administrator = [];
|
(it) => it.domain_id === domain.id
|
||||||
const domainUsers = usersResult.users.filter(
|
);
|
||||||
(it) => it.domain_id === domain.id
|
domain.user_num = domainUsers.length;
|
||||||
);
|
this.domainUsers = domainUsers;
|
||||||
domain.user_num = domainUsers.length;
|
this.detail = domain;
|
||||||
this.domainUsers = domainUsers;
|
this.isLoading = false;
|
||||||
this.detail = domain;
|
return domain;
|
||||||
this.isLoading = false;
|
}
|
||||||
return domain;
|
);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
async fetchDomain() {
|
async fetchDomain() {
|
||||||
const doaminsResult = await request.get(`${this.getResourceUrl()}/domains`);
|
const doaminsResult = await this.client.list();
|
||||||
this.domains = doaminsResult.domains;
|
this.domains = doaminsResult.domains;
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
async update({ id, body }) {
|
async update({ id, body }) {
|
||||||
const url = `${this.apiVersion}/${id}`;
|
|
||||||
this.isSubmitting = true;
|
this.isSubmitting = true;
|
||||||
const resData = await request.put(url, body, null, (res) => res.data);
|
const resData = await this.client.update(id, body);
|
||||||
this.isSubmitting = false;
|
this.isSubmitting = false;
|
||||||
return resData;
|
return resData;
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
async edit({ id, description }) {
|
async edit({ id, description }) {
|
||||||
const url = `${this.apiVersion}/domains/${id}`;
|
|
||||||
const reqBody = {
|
const reqBody = {
|
||||||
domain: { description },
|
domain: { description },
|
||||||
};
|
};
|
||||||
return this.submitting(request.patch(url, reqBody));
|
return this.submitting(this.client.patch(id, reqBody));
|
||||||
}
|
}
|
||||||
|
|
||||||
async setDomainAdmin({ id, user_id, role_id }) {
|
async setDomainAdmin({ id, user_id, role_id }) {
|
||||||
const url = `${this.apiVersion}/domains/${id}/users/${user_id}/roles/${role_id}`;
|
return this.submitting(this.client.users.roles.put(id, user_id, role_id));
|
||||||
return this.submitting(request.put(url));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async deleteDomainAdmin({ id, user_id, role_id }) {
|
async deleteDomainAdmin({ id, user_id, role_id }) {
|
||||||
const url = `${this.apiVersion}/domains/${id}/users/${user_id}/roles/${role_id}`;
|
const result = await this.client.users.roles.delete(id, user_id, role_id);
|
||||||
const result = await request.delete(url);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
async forbidden({ id }) {
|
async forbidden({ id }) {
|
||||||
const url = `${this.apiVersion}/domains/${id}`;
|
|
||||||
const reqBody = {
|
const reqBody = {
|
||||||
domain: { enabled: false },
|
domain: { enabled: false },
|
||||||
};
|
};
|
||||||
return this.submitting(request.patch(url, reqBody));
|
return this.submitting(this.client.patch(id, reqBody));
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
async enable({ id }) {
|
async enable({ id }) {
|
||||||
const url = `${this.apiVersion}/domains/${id}`;
|
|
||||||
const reqBody = {
|
const reqBody = {
|
||||||
domain: { enabled: true },
|
domain: { enabled: true },
|
||||||
};
|
};
|
||||||
return this.submitting(request.patch(url, reqBody));
|
return this.submitting(this.client.patch(id, reqBody));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,14 +14,8 @@
|
|||||||
|
|
||||||
import { action, observable } from 'mobx';
|
import { action, observable } from 'mobx';
|
||||||
import { getGBValue } from 'utils/index';
|
import { getGBValue } from 'utils/index';
|
||||||
import request from 'utils/request';
|
import { get, isNil, isEmpty } from 'lodash';
|
||||||
import {
|
import client from 'client';
|
||||||
keystoneBase,
|
|
||||||
novaBase,
|
|
||||||
cinderBase,
|
|
||||||
neutronBase,
|
|
||||||
} from 'utils/constants';
|
|
||||||
import { get } from 'lodash';
|
|
||||||
import Base from '../base';
|
import Base from '../base';
|
||||||
|
|
||||||
export class ProjectStore extends Base {
|
export class ProjectStore extends Base {
|
||||||
@ -40,18 +34,20 @@ export class ProjectStore extends Base {
|
|||||||
@observable
|
@observable
|
||||||
projectsOnly = [];
|
projectsOnly = [];
|
||||||
|
|
||||||
getResourceUrl = () => keystoneBase();
|
get client() {
|
||||||
|
return client.keystone.projects;
|
||||||
get module() {
|
|
||||||
return 'projects';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get apiVersion() {
|
get roleAssignmentClient() {
|
||||||
return keystoneBase();
|
return client.keystone.roleAssignments;
|
||||||
}
|
}
|
||||||
|
|
||||||
get responseKey() {
|
get roleClient() {
|
||||||
return 'project';
|
return client.keystone.roles;
|
||||||
|
}
|
||||||
|
|
||||||
|
get userClient() {
|
||||||
|
return client.keystone.users;
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
@ -66,16 +62,23 @@ export class ProjectStore extends Base {
|
|||||||
this.list.isLoading = true;
|
this.list.isLoading = true;
|
||||||
// todo: no page, no limit, fetch all
|
// todo: no page, no limit, fetch all
|
||||||
// const params = { ...filters };
|
// const params = { ...filters };
|
||||||
|
const { tags } = filters;
|
||||||
|
|
||||||
const [roleAssignmentsReault, projectsResult, roleResult] =
|
const [roleAssignmentsReault, projectsResult, roleResult] =
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
request.get(`${this.apiVersion}/role_assignments`),
|
this.roleAssignmentClient.list(),
|
||||||
request.get(`${this.apiVersion}/projects`),
|
this.client.list(tags ? { tags } : {}),
|
||||||
request.get(`${this.apiVersion}/roles`),
|
this.roleClient.list(),
|
||||||
]);
|
]);
|
||||||
const { projects } = projectsResult;
|
const { projects } = projectsResult;
|
||||||
const { roles } = roleResult;
|
const { roles } = roleResult;
|
||||||
const projectRoleId = roles.map((it) => it.id);
|
const projectRoles = roles.filter(
|
||||||
|
(it) =>
|
||||||
|
(it.name.indexOf('project_') !== -1 &&
|
||||||
|
it.name.indexOf('_project_') === -1) ||
|
||||||
|
it.name === 'admin'
|
||||||
|
);
|
||||||
|
const projectRoleId = projectRoles.map((it) => it.id);
|
||||||
projects.map((project) => {
|
projects.map((project) => {
|
||||||
const userMapRole = {}; // all user include system role and project role: { user_id: [roles_id] }
|
const userMapRole = {}; // all user include system role and project role: { user_id: [roles_id] }
|
||||||
const projectGroups = {};
|
const projectGroups = {};
|
||||||
@ -169,25 +172,23 @@ export class ProjectStore extends Base {
|
|||||||
|
|
||||||
@action
|
@action
|
||||||
async enable({ id }) {
|
async enable({ id }) {
|
||||||
const url = `${this.apiVersion}/projects/${id}`;
|
|
||||||
const reqBody = {
|
const reqBody = {
|
||||||
project: { enabled: true },
|
project: { enabled: true },
|
||||||
};
|
};
|
||||||
return this.submitting(request.patch(url, reqBody));
|
return this.submitting(this.client.patch(id, reqBody));
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
async forbidden({ id }) {
|
async forbidden({ id }) {
|
||||||
const url = `${this.apiVersion}/projects/${id}`;
|
|
||||||
const reqBody = {
|
const reqBody = {
|
||||||
project: { enabled: false },
|
project: { enabled: false },
|
||||||
};
|
};
|
||||||
return this.submitting(request.patch(url, reqBody));
|
return this.submitting(this.client.patch(id, reqBody));
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
async fetchDomain() {
|
async fetchDomain() {
|
||||||
const doaminsResult = await request.get(`${this.getResourceUrl()}/domains`);
|
const doaminsResult = await this.skylineClient.domains();
|
||||||
this.domains = doaminsResult.domains;
|
this.domains = doaminsResult.domains;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,9 +197,7 @@ export class ProjectStore extends Base {
|
|||||||
const reqBody = {
|
const reqBody = {
|
||||||
project: data,
|
project: data,
|
||||||
};
|
};
|
||||||
return this.submitting(
|
return this.submitting(this.client.create(reqBody));
|
||||||
request.post(`${this.getResourceUrl()}/projects`, reqBody)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
@ -208,12 +207,18 @@ export class ProjectStore extends Base {
|
|||||||
}
|
}
|
||||||
const [roleAssignmentsReault, projectResult, roleResult] =
|
const [roleAssignmentsReault, projectResult, roleResult] =
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
request.get(`${this.apiVersion}/role_assignments`),
|
this.roleAssignmentClient.list(),
|
||||||
request.get(`${this.apiVersion}/projects/${id}`),
|
this.client.show(id),
|
||||||
request.get(`${this.apiVersion}/roles`),
|
this.roleClient.list(),
|
||||||
]);
|
]);
|
||||||
const { roles } = roleResult;
|
const { roles } = roleResult;
|
||||||
const projectRoleId = roles.map((it) => it.id);
|
const projectRoles = roles.filter(
|
||||||
|
(it) =>
|
||||||
|
(it.name.indexOf('project_') !== -1 &&
|
||||||
|
it.name.indexOf('_project_') === -1) ||
|
||||||
|
it.name === 'admin'
|
||||||
|
);
|
||||||
|
const projectRoleId = projectRoles.map((it) => it.id);
|
||||||
const { project } = projectResult;
|
const { project } = projectResult;
|
||||||
const userMapRole = {};
|
const userMapRole = {};
|
||||||
const projectGroups = {};
|
const projectGroups = {};
|
||||||
@ -232,30 +237,26 @@ export class ProjectStore extends Base {
|
|||||||
project.groups = projectGroups;
|
project.groups = projectGroups;
|
||||||
project.user_num = Object.keys(userMapRole).length;
|
project.user_num = Object.keys(userMapRole).length;
|
||||||
project.group_num = Object.keys(projectGroups).length;
|
project.group_num = Object.keys(projectGroups).length;
|
||||||
this.detail = project;
|
const newItem = await this.detailDidFetch(project);
|
||||||
|
this.detail = newItem;
|
||||||
this.isLoading = false;
|
this.isLoading = false;
|
||||||
return project;
|
return newItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
async edit({ id, description, name }) {
|
async edit({ id, description, name }) {
|
||||||
const url = `${this.apiVersion}/projects/${id}`;
|
|
||||||
const reqBody = {
|
const reqBody = {
|
||||||
project: { description, name },
|
project: { description, name },
|
||||||
};
|
};
|
||||||
return this.submitting(request.patch(url, reqBody));
|
return this.submitting(this.client.patch(id, reqBody));
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
async fetchProjectQuota({ project_id }) {
|
async fetchProjectQuota({ project_id }) {
|
||||||
const [novaResult, cinderResult, neutronResult] = await Promise.all([
|
const [novaResult, cinderResult, neutronResult] = await Promise.all([
|
||||||
request.get(`${novaBase()}/os-quota-sets/${project_id}/detail`),
|
client.nova.quotaSets.detail(project_id),
|
||||||
request.get(
|
client.cinder.quotaSets.show(project_id, { usage: 'True' }),
|
||||||
`${cinderBase()}/${
|
client.neutron.quotas.details(project_id),
|
||||||
globals.user.project.id
|
|
||||||
}/os-quota-sets/${project_id}?usage=True`
|
|
||||||
),
|
|
||||||
request.get(`${neutronBase()}/quotas/${project_id}/details`),
|
|
||||||
]);
|
]);
|
||||||
this.isSubmitting = false;
|
this.isSubmitting = false;
|
||||||
const { quota_set: novaQuota } = novaResult;
|
const { quota_set: novaQuota } = novaResult;
|
||||||
@ -276,6 +277,15 @@ export class ProjectStore extends Base {
|
|||||||
this.quota = quota;
|
this.quota = quota;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
omitNil = (obj) => {
|
||||||
|
return Object.keys(obj).reduce((acc, v) => {
|
||||||
|
if (!isNil(obj[v])) {
|
||||||
|
acc[v] = obj[v];
|
||||||
|
}
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
};
|
||||||
|
|
||||||
@action
|
@action
|
||||||
async updateProjectQuota({ project_id, data }) {
|
async updateProjectQuota({ project_id, data }) {
|
||||||
this.isSubmitting = true;
|
this.isSubmitting = true;
|
||||||
@ -285,6 +295,7 @@ export class ProjectStore extends Base {
|
|||||||
ram,
|
ram,
|
||||||
volumes,
|
volumes,
|
||||||
gigabytes,
|
gigabytes,
|
||||||
|
firewall_group,
|
||||||
security_group_rule,
|
security_group_rule,
|
||||||
server_groups,
|
server_groups,
|
||||||
snapshots,
|
snapshots,
|
||||||
@ -301,59 +312,61 @@ export class ProjectStore extends Base {
|
|||||||
...others
|
...others
|
||||||
} = data;
|
} = data;
|
||||||
let ramGb = ram;
|
let ramGb = ram;
|
||||||
if (ram !== -1) {
|
if (ram && ram !== -1) {
|
||||||
ramGb = ram * 1024;
|
ramGb = ram * 1024;
|
||||||
}
|
}
|
||||||
const novaReqBody = {
|
const novaReqBody = {
|
||||||
quota_set: {
|
quota_set: this.omitNil({
|
||||||
instances,
|
instances,
|
||||||
cores,
|
cores,
|
||||||
ram: ramGb,
|
ram: ramGb,
|
||||||
server_groups,
|
server_groups,
|
||||||
server_group_members,
|
server_group_members,
|
||||||
key_pairs,
|
key_pairs,
|
||||||
},
|
}),
|
||||||
};
|
};
|
||||||
const cinderReqBody = {
|
const cinderReqBody = {
|
||||||
quota_set: {
|
quota_set: this.omitNil({
|
||||||
volumes,
|
volumes,
|
||||||
gigabytes,
|
gigabytes,
|
||||||
backup_gigabytes,
|
backup_gigabytes,
|
||||||
snapshots,
|
snapshots,
|
||||||
backups,
|
backups,
|
||||||
...others,
|
...others,
|
||||||
},
|
}),
|
||||||
};
|
};
|
||||||
|
const firewallValue = firewall_group ? { firewall_group } : {};
|
||||||
const neutronReqBody = {
|
const neutronReqBody = {
|
||||||
quota: {
|
quota: this.omitNil({
|
||||||
network,
|
network,
|
||||||
router,
|
router,
|
||||||
subnet,
|
subnet,
|
||||||
floatingip,
|
floatingip,
|
||||||
security_group,
|
security_group,
|
||||||
security_group_rule,
|
security_group_rule,
|
||||||
|
...firewallValue,
|
||||||
port,
|
port,
|
||||||
},
|
}),
|
||||||
};
|
};
|
||||||
const result = await Promise.all([
|
const reqs = [];
|
||||||
request.put(`${novaBase()}/os-quota-sets/${project_id}`, novaReqBody),
|
if (!isEmpty(novaReqBody.quota_set)) {
|
||||||
request.put(
|
reqs.push(client.nova.quotaSets.update(project_id, novaReqBody));
|
||||||
`${cinderBase()}/${
|
}
|
||||||
globals.user.project.id
|
if (!isEmpty(cinderReqBody.quota_set)) {
|
||||||
}/os-quota-sets/${project_id}`,
|
reqs.push(client.cinder.quotaSets.update(project_id, cinderReqBody));
|
||||||
cinderReqBody
|
}
|
||||||
),
|
if (!isEmpty(neutronReqBody.quota)) {
|
||||||
request.put(`${neutronBase()}/quotas/${project_id}`, neutronReqBody),
|
reqs.push(client.neutron.quotas.update(project_id, neutronReqBody));
|
||||||
]);
|
}
|
||||||
|
|
||||||
|
const result = await Promise.all(reqs);
|
||||||
this.isSubmitting = false;
|
this.isSubmitting = false;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
async getUserRoleList({ id, user_id }) {
|
async getUserRoleList({ id, user_id }) {
|
||||||
const url = `${this.apiVersion}/projects/${id}/users/${user_id}/roles/`;
|
const result = await this.client.users.roles.list(id, user_id);
|
||||||
this.isSubmitting = true;
|
|
||||||
const result = await request.get(url);
|
|
||||||
this.userRoleList = result.roles;
|
this.userRoleList = result.roles;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -362,43 +375,37 @@ export class ProjectStore extends Base {
|
|||||||
const body = {};
|
const body = {};
|
||||||
body[this.responseKey] = data;
|
body[this.responseKey] = data;
|
||||||
this.isSubmitting = true;
|
this.isSubmitting = true;
|
||||||
const result = await request.post(this.getListUrl(), body);
|
const result = await this.client.create(body);
|
||||||
this.isSubmitting = false;
|
this.isSubmitting = false;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
async assignUserRole({ id, user_id, role_id }) {
|
async assignUserRole({ id, user_id, role_id }) {
|
||||||
const url = `${this.apiVersion}/projects/${id}/users/${user_id}/roles/${role_id}`;
|
const result = await this.client.users.roles.update(id, user_id, role_id);
|
||||||
const result = request.put(url);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
async removeUserRole({ id, user_id, role_id }) {
|
async removeUserRole({ id, user_id, role_id }) {
|
||||||
const url = `${this.apiVersion}/projects/${id}/users/${user_id}/roles/${role_id}`;
|
const result = await this.client.users.roles.delete(id, user_id, role_id);
|
||||||
const result = request.delete(url);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
async getGroupRoleList({ id, group_id }) {
|
async getGroupRoleList({ id, group_id }) {
|
||||||
const url = `${this.apiVersion}/projects/${id}/groups/${group_id}/roles/`;
|
const result = await this.client.groups.roles.list(id, group_id);
|
||||||
this.isSubmitting = true;
|
|
||||||
const result = await request.get(url);
|
|
||||||
this.groupRoleList = result.roles;
|
this.groupRoleList = result.roles;
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
async assignGroupRole({ id, group_id, role_id }) {
|
async assignGroupRole({ id, group_id, role_id }) {
|
||||||
const url = `${this.apiVersion}/projects/${id}/groups/${group_id}/roles/${role_id}`;
|
const result = await this.client.groups.roles.update(id, group_id, role_id);
|
||||||
const result = request.put(url);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
async removeGroupRole({ id, group_id, role_id }) {
|
async removeGroupRole({ id, group_id, role_id }) {
|
||||||
const url = `${this.apiVersion}/projects/${id}/groups/${group_id}/roles/${role_id}`;
|
const result = await this.client.groups.roles.delete(id, group_id, role_id);
|
||||||
const result = request.delete(url);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -415,10 +422,10 @@ export class ProjectStore extends Base {
|
|||||||
const { userId } = filters;
|
const { userId } = filters;
|
||||||
const [roleAssignmentsReault, projectsResult, roleResult, groupResult] =
|
const [roleAssignmentsReault, projectsResult, roleResult, groupResult] =
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
request.get(`${this.apiVersion}/role_assignments`),
|
this.roleAssignmentClient.list(),
|
||||||
request.get(`${this.apiVersion}/users/${userId}/projects`),
|
this.userClient.projects.list(userId),
|
||||||
request.get(`${this.apiVersion}/roles`),
|
this.roleClient.list(),
|
||||||
request.get(`${this.apiVersion}/users/${userId}/groups`),
|
this.userClient.groups.list(userId),
|
||||||
]);
|
]);
|
||||||
const projects = get(projectsResult, this.listResponseKey, []);
|
const projects = get(projectsResult, this.listResponseKey, []);
|
||||||
projects.map((project) => {
|
projects.map((project) => {
|
||||||
@ -485,9 +492,9 @@ export class ProjectStore extends Base {
|
|||||||
const { groupId } = filters;
|
const { groupId } = filters;
|
||||||
const [roleAssignmentsReault, projectsResult, roleResult] =
|
const [roleAssignmentsReault, projectsResult, roleResult] =
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
request.get(`${this.apiVersion}/role_assignments`),
|
this.roleAssignmentClient.list(),
|
||||||
request.get(`${this.apiVersion}/projects`),
|
this.client.list(),
|
||||||
request.get(`${this.apiVersion}/roles`),
|
this.roleClient.list(),
|
||||||
]);
|
]);
|
||||||
const projects = get(projectsResult, this.listResponseKey, []);
|
const projects = get(projectsResult, this.listResponseKey, []);
|
||||||
projects.map((project) => {
|
projects.map((project) => {
|
||||||
@ -534,8 +541,10 @@ export class ProjectStore extends Base {
|
|||||||
@action
|
@action
|
||||||
async fetchProjectListOnly() {
|
async fetchProjectListOnly() {
|
||||||
this.list.isLoading = true;
|
this.list.isLoading = true;
|
||||||
const result = await request.get(`${this.apiVersion}/${this.module}`);
|
const result = await this.client.list();
|
||||||
this.projectsOnly = get(result, this.listResponseKey, []);
|
this.projectsOnly = get(result, this.listResponseKey, []);
|
||||||
|
this.list.isLoading = false;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,21 +12,13 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { keystoneBase } from 'utils/constants';
|
|
||||||
import { action, observable } from 'mobx';
|
import { action, observable } from 'mobx';
|
||||||
|
import client from 'client';
|
||||||
import Base from '../base';
|
import Base from '../base';
|
||||||
|
|
||||||
export class RoleStore extends Base {
|
export class RoleStore extends Base {
|
||||||
get module() {
|
get client() {
|
||||||
return 'roles';
|
return client.keystone.roles;
|
||||||
}
|
|
||||||
|
|
||||||
get apiVersion() {
|
|
||||||
return keystoneBase();
|
|
||||||
}
|
|
||||||
|
|
||||||
get responseKey() {
|
|
||||||
return 'role';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@observable
|
@observable
|
||||||
@ -34,9 +26,7 @@ export class RoleStore extends Base {
|
|||||||
|
|
||||||
@action
|
@action
|
||||||
async fetchImpliedRoles({ id }) {
|
async fetchImpliedRoles({ id }) {
|
||||||
const rolesResult = await request.get(
|
const rolesResult = await this.client.implies.list(id);
|
||||||
`${this.getDetailUrl({ id })}/implies/`
|
|
||||||
);
|
|
||||||
const {
|
const {
|
||||||
role_inference: { implies },
|
role_inference: { implies },
|
||||||
} = rolesResult;
|
} = rolesResult;
|
||||||
|
@ -12,40 +12,28 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { keystoneBase } from 'utils/constants';
|
|
||||||
import { action } from 'mobx';
|
import { action } from 'mobx';
|
||||||
|
import client from 'client';
|
||||||
import Base from '../base';
|
import Base from '../base';
|
||||||
|
|
||||||
export class TagStore extends Base {
|
export class TagStore extends Base {
|
||||||
get module() {
|
get client() {
|
||||||
return 'tags';
|
return client.keystone.projects.tags;
|
||||||
}
|
}
|
||||||
|
|
||||||
get apiVersion() {
|
listFetchByClient(params, originParams) {
|
||||||
return keystoneBase();
|
const { project_id } = originParams;
|
||||||
}
|
return this.client.list(project_id, params);
|
||||||
|
|
||||||
get responseKey() {
|
|
||||||
return 'tag';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get paramsFunc() {
|
get paramsFunc() {
|
||||||
return () => null;
|
return () => null;
|
||||||
}
|
}
|
||||||
|
|
||||||
getListUrl = ({ project_id }) =>
|
|
||||||
`${this.apiVersion}/projects/${project_id}/${this.module}`;
|
|
||||||
|
|
||||||
@action
|
@action
|
||||||
update({ project_id }, newObject, sleepTime) {
|
update({ project_id }, newObject) {
|
||||||
return this.submitting(
|
return this.submitting(
|
||||||
request.put(
|
client.keystone.projects.updateTags(project_id, newObject)
|
||||||
`${this.getListUrl({ project_id })}`,
|
|
||||||
newObject,
|
|
||||||
null,
|
|
||||||
null,
|
|
||||||
sleepTime
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,9 +13,8 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { action, observable } from 'mobx';
|
import { action, observable } from 'mobx';
|
||||||
import { keystoneBase } from 'utils/constants';
|
|
||||||
import request from 'utils/request';
|
|
||||||
import { get } from 'lodash';
|
import { get } from 'lodash';
|
||||||
|
import client from 'client';
|
||||||
import Base from '../base';
|
import Base from '../base';
|
||||||
import globalProjectStore from './project';
|
import globalProjectStore from './project';
|
||||||
|
|
||||||
@ -32,16 +31,32 @@ export class GroupStore extends Base {
|
|||||||
@observable
|
@observable
|
||||||
groupUsers = [];
|
groupUsers = [];
|
||||||
|
|
||||||
get module() {
|
get client() {
|
||||||
return 'groups';
|
return client.keystone.groups;
|
||||||
}
|
}
|
||||||
|
|
||||||
get apiVersion() {
|
get domainClient() {
|
||||||
return keystoneBase();
|
return client.keystone.domains;
|
||||||
}
|
}
|
||||||
|
|
||||||
get responseKey() {
|
get systemGroupClient() {
|
||||||
return 'group';
|
return client.keystone.systemGroups;
|
||||||
|
}
|
||||||
|
|
||||||
|
get roleClient() {
|
||||||
|
return client.keystone.roles;
|
||||||
|
}
|
||||||
|
|
||||||
|
get roleAssignmentClient() {
|
||||||
|
return client.keystone.roleAssignments;
|
||||||
|
}
|
||||||
|
|
||||||
|
get userClient() {
|
||||||
|
return client.keystone.users;
|
||||||
|
}
|
||||||
|
|
||||||
|
get projectClient() {
|
||||||
|
return client.keystone.projects;
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
@ -51,7 +66,7 @@ export class GroupStore extends Base {
|
|||||||
|
|
||||||
body[this.responseKey] = other;
|
body[this.responseKey] = other;
|
||||||
this.isSubmitting = true;
|
this.isSubmitting = true;
|
||||||
const result = await request.post(this.getListUrl(), body);
|
const result = await this.client.create(body);
|
||||||
const {
|
const {
|
||||||
group: { id: group_id },
|
group: { id: group_id },
|
||||||
} = result;
|
} = result;
|
||||||
@ -83,7 +98,7 @@ export class GroupStore extends Base {
|
|||||||
|
|
||||||
@action
|
@action
|
||||||
async fetchDomain() {
|
async fetchDomain() {
|
||||||
const doaminsResult = await request.get(`${this.apiVersion}/domains`);
|
const doaminsResult = await this.domainClient.list();
|
||||||
this.domains = doaminsResult.domains;
|
this.domains = doaminsResult.domains;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,12 +114,11 @@ export class GroupStore extends Base {
|
|||||||
|
|
||||||
@action
|
@action
|
||||||
async edit({ id, description, name }) {
|
async edit({ id, description, name }) {
|
||||||
const url = `${this.apiVersion}/groups/${id}`;
|
|
||||||
this.isSubmitting = true;
|
this.isSubmitting = true;
|
||||||
const reqBody = {
|
const reqBody = {
|
||||||
group: { description, name },
|
group: { description, name },
|
||||||
};
|
};
|
||||||
const result = await request.patch(url, reqBody);
|
const result = await this.client.patch(id, reqBody);
|
||||||
this.isSubmitting = false;
|
this.isSubmitting = false;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -112,51 +126,38 @@ export class GroupStore extends Base {
|
|||||||
@action
|
@action
|
||||||
async fetchSystemRole({ id }) {
|
async fetchSystemRole({ id }) {
|
||||||
this.systemRoles = [];
|
this.systemRoles = [];
|
||||||
const rolesResult = await request.get(
|
const rolesResult = await this.systemGroupClient.roles.list(id);
|
||||||
`${this.apiVersion}/system/groups/${id}/roles`
|
|
||||||
);
|
|
||||||
this.systemRoles = rolesResult.roles;
|
this.systemRoles = rolesResult.roles;
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
async assignSystemRole({ id, role_id }) {
|
async assignSystemRole({ id, role_id }) {
|
||||||
const result = request.put(
|
return this.systemGroupClient.roles.update(id, role_id);
|
||||||
`${this.apiVersion}/system/groups/${id}/roles/${role_id}`
|
|
||||||
);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
async deleteSystemRole({ id, role_id }) {
|
async deleteSystemRole({ id, role_id }) {
|
||||||
const result = request.delete(
|
return this.systemGroupClient.roles.delete(id, role_id);
|
||||||
`${this.apiVersion}/system/groups/${id}/roles/${role_id}`
|
|
||||||
);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
async fetchDomainRole({ id, domain_id }) {
|
async fetchDomainRole({ id, domain_id }) {
|
||||||
this.domainRoles = [];
|
this.domainRoles = [];
|
||||||
const rolesResult = await request.get(
|
const rolesResult = await this.domainClient.groups.roles.list(
|
||||||
`${this.apiVersion}/domains/${domain_id}/groups/${id}/roles`
|
domain_id,
|
||||||
|
id
|
||||||
);
|
);
|
||||||
this.domainRoles = rolesResult.roles;
|
this.domainRoles = rolesResult.roles;
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
async assignDomainRole({ id, role_id, domain_id }) {
|
async assignDomainRole({ id, role_id, domain_id }) {
|
||||||
const result = request.put(
|
return this.domainClient.groups.roles.update(domain_id, id, role_id);
|
||||||
`${this.apiVersion}/domains/${domain_id}/groups/${id}/roles/${role_id}`
|
|
||||||
);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
async deleteDomainRole({ id, role_id, domain_id }) {
|
async deleteDomainRole({ id, role_id, domain_id }) {
|
||||||
const result = request.delete(
|
return this.domainClient.groups.roles.delete(domain_id, id, role_id);
|
||||||
`${this.apiVersion}/domains/${domain_id}/groups/${id}/roles/${role_id}`
|
|
||||||
);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
@ -172,8 +173,8 @@ export class GroupStore extends Base {
|
|||||||
const { projectId } = filters;
|
const { projectId } = filters;
|
||||||
const params = {};
|
const params = {};
|
||||||
const [roleAssignmentsReault, result] = await Promise.all([
|
const [roleAssignmentsReault, result] = await Promise.all([
|
||||||
request.get(`${this.apiVersion}/role_assignments`),
|
this.roleAssignmentClient.list(),
|
||||||
request.get(this.getListUrl(), params),
|
this.client.list(params),
|
||||||
]);
|
]);
|
||||||
const projectGroupIds = [];
|
const projectGroupIds = [];
|
||||||
roleAssignmentsReault.role_assignments.forEach((roleAssignment) => {
|
roleAssignmentsReault.role_assignments.forEach((roleAssignment) => {
|
||||||
@ -191,33 +192,38 @@ export class GroupStore extends Base {
|
|||||||
data = data.filter((it) => projectGroupIds.indexOf(it.id) >= 0);
|
data = data.filter((it) => projectGroupIds.indexOf(it.id) >= 0);
|
||||||
// const items = data.map(this.mapper);
|
// const items = data.map(this.mapper);
|
||||||
// const newData = await this.listDidFetch(items);
|
// const newData = await this.listDidFetch(items);
|
||||||
Promise.all(
|
Promise.all(data.map((it) => this.client.users.list(it.id))).then(
|
||||||
data.map((it) => request.get(`${this.apiVersion}/groups/${it.id}/users`))
|
(rest) => {
|
||||||
).then((rest) => {
|
const addUserItem = data.map((it, index) => {
|
||||||
const addUserItem = data.map((it, index) => {
|
const { users } = rest[index];
|
||||||
const { users } = rest[index];
|
const userIds = users.map((user) => user.id);
|
||||||
const userIds = users.map((user) => user.id);
|
const userInfo = users.map((user) => ({
|
||||||
it.users = userIds;
|
id: user.id,
|
||||||
it.user_num = users.length;
|
name: user.name,
|
||||||
return it;
|
}));
|
||||||
});
|
it.users = userIds;
|
||||||
const items = addUserItem.map((item) =>
|
it.user_num = users.length;
|
||||||
this.mapperProject(roleAssignmentsReault, item)
|
it.user_info = userInfo;
|
||||||
);
|
return it;
|
||||||
this.list.update({
|
});
|
||||||
data: items,
|
const items = addUserItem.map((item) =>
|
||||||
total: items.length || 0,
|
this.mapperProject(roleAssignmentsReault, item)
|
||||||
limit: Number(limit) || 10,
|
);
|
||||||
page: Number(page) || 1,
|
this.list.update({
|
||||||
sortKey,
|
data: items,
|
||||||
sortOrder,
|
total: items.length || 0,
|
||||||
filters,
|
limit: Number(limit) || 10,
|
||||||
isLoading: false,
|
page: Number(page) || 1,
|
||||||
...(this.list.silent ? {} : { selectedRowKeys: [] }),
|
sortKey,
|
||||||
});
|
sortOrder,
|
||||||
|
filters,
|
||||||
|
isLoading: false,
|
||||||
|
...(this.list.silent ? {} : { selectedRowKeys: [] }),
|
||||||
|
});
|
||||||
|
|
||||||
return items;
|
return items;
|
||||||
});
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
@ -233,8 +239,8 @@ export class GroupStore extends Base {
|
|||||||
const { userId } = filters;
|
const { userId } = filters;
|
||||||
const params = {};
|
const params = {};
|
||||||
const [roleAssignmentsReault, result] = await Promise.all([
|
const [roleAssignmentsReault, result] = await Promise.all([
|
||||||
request.get(`${this.apiVersion}/role_assignments`),
|
this.roleAssignmentClient.list(),
|
||||||
request.get(`${this.apiVersion}/users/${userId}/groups`, params),
|
this.userClient.groups.list(userId, params),
|
||||||
]);
|
]);
|
||||||
const projectGroupIds = [];
|
const projectGroupIds = [];
|
||||||
roleAssignmentsReault.role_assignments.forEach((roleAssignment) => {
|
roleAssignmentsReault.role_assignments.forEach((roleAssignment) => {
|
||||||
@ -269,9 +275,7 @@ export class GroupStore extends Base {
|
|||||||
|
|
||||||
@action
|
@action
|
||||||
async fetchGroupUsers({ id }) {
|
async fetchGroupUsers({ id }) {
|
||||||
const usersResult = await request.get(
|
const usersResult = await this.client.users.list(id);
|
||||||
`${this.apiVersion}/groups/${id}/users`
|
|
||||||
);
|
|
||||||
const { users: result } = usersResult;
|
const { users: result } = usersResult;
|
||||||
this.groupUsers = result;
|
this.groupUsers = result;
|
||||||
return result;
|
return result;
|
||||||
@ -279,18 +283,12 @@ export class GroupStore extends Base {
|
|||||||
|
|
||||||
@action
|
@action
|
||||||
async deleteGroupUsers({ id, user_id }) {
|
async deleteGroupUsers({ id, user_id }) {
|
||||||
const result = request.delete(
|
return this.client.users.delete(id, user_id);
|
||||||
`${this.apiVersion}/groups/${id}/users/${user_id}`
|
|
||||||
);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
async addGroupUsers({ id, user_id }) {
|
async addGroupUsers({ id, user_id }) {
|
||||||
const result = request.put(
|
return this.client.users.update(id, user_id);
|
||||||
`${this.apiVersion}/groups/${id}/users/${user_id}`
|
|
||||||
);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mapperProject = (roleAssignmentsReault, item) => {
|
mapperProject = (roleAssignmentsReault, item) => {
|
||||||
@ -320,17 +318,12 @@ export class GroupStore extends Base {
|
|||||||
// todo: no page, no limit, fetch all
|
// todo: no page, no limit, fetch all
|
||||||
const params = { ...filters };
|
const params = { ...filters };
|
||||||
|
|
||||||
const result = await request.get(
|
const result = await this.client.list(params);
|
||||||
this.getListDetailUrl() || this.getListUrl(),
|
const roleAssignmentsReault = await this.roleAssignmentClient.list();
|
||||||
params
|
|
||||||
);
|
|
||||||
const roleAssignmentsReault = await request.get(
|
|
||||||
`${this.apiVersion}/role_assignments/`
|
|
||||||
);
|
|
||||||
const data = get(result, this.listResponseKey, []);
|
const data = get(result, this.listResponseKey, []);
|
||||||
Promise.all(
|
Promise.all(
|
||||||
data.map(
|
data.map(
|
||||||
(it) => request.get(`${this.apiVersion}/groups/${it.id}/users`)
|
(it) => this.client.users.list(it.id)
|
||||||
// const { users } = userResult;
|
// const { users } = userResult;
|
||||||
// return { ...it, users };
|
// return { ...it, users };
|
||||||
)
|
)
|
||||||
@ -338,8 +331,13 @@ export class GroupStore extends Base {
|
|||||||
const addUserItem = data.map((it, index) => {
|
const addUserItem = data.map((it, index) => {
|
||||||
const { users } = rest[index];
|
const { users } = rest[index];
|
||||||
const userIds = users.map((user) => user.id);
|
const userIds = users.map((user) => user.id);
|
||||||
|
const userInfo = users.map((user) => ({
|
||||||
|
id: user.id,
|
||||||
|
name: user.name,
|
||||||
|
}));
|
||||||
it.users = userIds;
|
it.users = userIds;
|
||||||
it.user_num = users.length;
|
it.user_num = users.length;
|
||||||
|
it.user_info = userInfo;
|
||||||
return it;
|
return it;
|
||||||
});
|
});
|
||||||
const items = addUserItem.map((item) =>
|
const items = addUserItem.map((item) =>
|
||||||
@ -369,15 +367,19 @@ export class GroupStore extends Base {
|
|||||||
}
|
}
|
||||||
const [roleAssignmentsReault, groupResult, usersInGroup] =
|
const [roleAssignmentsReault, groupResult, usersInGroup] =
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
request.get(`${this.apiVersion}/role_assignments`),
|
this.roleAssignmentClient.list(),
|
||||||
request.get(`${this.apiVersion}/groups/${id}`),
|
this.client.show(id),
|
||||||
request.get(`${this.apiVersion}/groups/${id}/users`),
|
this.client.users.list(id),
|
||||||
]);
|
]);
|
||||||
const originData = get(groupResult, this.responseKey) || groupResult;
|
const originData = get(groupResult, this.responseKey) || groupResult;
|
||||||
const { users } = usersInGroup;
|
const { users } = usersInGroup;
|
||||||
const userIds = users.map((user) => user.id);
|
const userIds = users.map((user) => user.id);
|
||||||
originData.users = userIds;
|
originData.users = userIds;
|
||||||
originData.user_num = users.length;
|
originData.user_num = users.length;
|
||||||
|
originData.user_info = users.map((user) => ({
|
||||||
|
id: user.id,
|
||||||
|
name: user.name,
|
||||||
|
}));
|
||||||
const group = this.mapperProject(roleAssignmentsReault, originData);
|
const group = this.mapperProject(roleAssignmentsReault, originData);
|
||||||
this.detail = group;
|
this.detail = group;
|
||||||
this.isLoading = false;
|
this.isLoading = false;
|
||||||
@ -386,7 +388,7 @@ export class GroupStore extends Base {
|
|||||||
|
|
||||||
@action
|
@action
|
||||||
async fetchGroupData() {
|
async fetchGroupData() {
|
||||||
const result = await request.get(this.getListUrl());
|
const result = await this.client.list();
|
||||||
const { groups } = result;
|
const { groups } = result;
|
||||||
return groups;
|
return groups;
|
||||||
}
|
}
|
||||||
@ -404,9 +406,9 @@ export class GroupStore extends Base {
|
|||||||
const { roleId } = filters;
|
const { roleId } = filters;
|
||||||
const params = {};
|
const params = {};
|
||||||
const [roleAssignmentsReault, projectResult, result] = await Promise.all([
|
const [roleAssignmentsReault, projectResult, result] = await Promise.all([
|
||||||
request.get(`${this.apiVersion}/role_assignments`),
|
this.roleAssignmentClient.list(),
|
||||||
request.get(`${this.apiVersion}/projects`),
|
this.projectClient.list(),
|
||||||
request.get(this.getListUrl(), params),
|
this.client.list(params),
|
||||||
]);
|
]);
|
||||||
const projectRoleUsers = {};
|
const projectRoleUsers = {};
|
||||||
const systemRoleUsers = {};
|
const systemRoleUsers = {};
|
||||||
@ -442,30 +444,35 @@ export class GroupStore extends Base {
|
|||||||
|
|
||||||
// const items = data.map(this.mapper);
|
// const items = data.map(this.mapper);
|
||||||
// const newData = await this.listDidFetch(items);
|
// const newData = await this.listDidFetch(items);
|
||||||
Promise.all(
|
Promise.all(data.map((it) => this.client.users.list(it.id))).then(
|
||||||
data.map((it) => request.get(`${this.apiVersion}/groups/${it.id}/users`))
|
(rest) => {
|
||||||
).then((rest) => {
|
items.map((it, index) => {
|
||||||
items.map((it, index) => {
|
const { users } = rest[index];
|
||||||
const { users } = rest[index];
|
const userIds = users.map((user) => user.id);
|
||||||
const userIds = users.map((user) => user.id);
|
const userInfo = users.map((user) => ({
|
||||||
it.users = userIds;
|
id: user.id,
|
||||||
it.user_num = users.length;
|
name: user.name,
|
||||||
return it;
|
}));
|
||||||
});
|
it.users = userIds;
|
||||||
this.list.update({
|
it.user_num = users.length;
|
||||||
data: items,
|
it.user_info = userInfo;
|
||||||
total: items.length || 0,
|
return it;
|
||||||
limit: Number(limit) || 10,
|
});
|
||||||
page: Number(page) || 1,
|
this.list.update({
|
||||||
sortKey,
|
data: items,
|
||||||
sortOrder,
|
total: items.length || 0,
|
||||||
filters,
|
limit: Number(limit) || 10,
|
||||||
isLoading: false,
|
page: Number(page) || 1,
|
||||||
...(this.list.silent ? {} : { selectedRowKeys: [] }),
|
sortKey,
|
||||||
});
|
sortOrder,
|
||||||
|
filters,
|
||||||
|
isLoading: false,
|
||||||
|
...(this.list.silent ? {} : { selectedRowKeys: [] }),
|
||||||
|
});
|
||||||
|
|
||||||
return items;
|
return items;
|
||||||
});
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,12 +13,13 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { action, observable } from 'mobx';
|
import { action, observable } from 'mobx';
|
||||||
import request from 'utils/request';
|
|
||||||
import { keystoneBase } from 'utils/constants';
|
|
||||||
import { get } from 'lodash';
|
import { get } from 'lodash';
|
||||||
import Base from '../base';
|
import List from 'stores/base-list';
|
||||||
|
import client from 'client';
|
||||||
|
import globalRootStore from 'stores/root';
|
||||||
import globalProjectStore from './project';
|
import globalProjectStore from './project';
|
||||||
import globalGroupStore from './user-group';
|
import globalGroupStore from './user-group';
|
||||||
|
import Base from '../base';
|
||||||
|
|
||||||
export class UserStore extends Base {
|
export class UserStore extends Base {
|
||||||
@observable
|
@observable
|
||||||
@ -27,6 +28,12 @@ export class UserStore extends Base {
|
|||||||
@observable
|
@observable
|
||||||
roleAssignments = [];
|
roleAssignments = [];
|
||||||
|
|
||||||
|
@observable
|
||||||
|
userProjects = new List();
|
||||||
|
|
||||||
|
@observable
|
||||||
|
userGroups = new List();
|
||||||
|
|
||||||
@observable
|
@observable
|
||||||
projects = [];
|
projects = [];
|
||||||
|
|
||||||
@ -36,16 +43,36 @@ export class UserStore extends Base {
|
|||||||
@observable
|
@observable
|
||||||
domainRoles = [];
|
domainRoles = [];
|
||||||
|
|
||||||
get module() {
|
get client() {
|
||||||
return 'users';
|
return client.keystone.users;
|
||||||
}
|
}
|
||||||
|
|
||||||
get apiVersion() {
|
get domainClient() {
|
||||||
return keystoneBase();
|
return client.keystone.domains;
|
||||||
}
|
}
|
||||||
|
|
||||||
get responseKey() {
|
get systemGroupClient() {
|
||||||
return 'user';
|
return client.keystone.systemGroups;
|
||||||
|
}
|
||||||
|
|
||||||
|
get roleClient() {
|
||||||
|
return client.keystone.roles;
|
||||||
|
}
|
||||||
|
|
||||||
|
get roleAssignmentClient() {
|
||||||
|
return client.keystone.roleAssignments;
|
||||||
|
}
|
||||||
|
|
||||||
|
get projectClient() {
|
||||||
|
return client.keystone.projects;
|
||||||
|
}
|
||||||
|
|
||||||
|
get systemUserClient() {
|
||||||
|
return client.keystone.systemUsers;
|
||||||
|
}
|
||||||
|
|
||||||
|
get groupClient() {
|
||||||
|
return client.keystone.groups;
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
@ -61,14 +88,10 @@ export class UserStore extends Base {
|
|||||||
const data = other;
|
const data = other;
|
||||||
body[this.responseKey] = data;
|
body[this.responseKey] = data;
|
||||||
this.isSubmitting = true;
|
this.isSubmitting = true;
|
||||||
const result = await request.post(this.getListUrl(), body);
|
const result = await this.client.create(body);
|
||||||
const {
|
const {
|
||||||
user: { id: user_id },
|
user: { id: user_id },
|
||||||
} = result;
|
} = result;
|
||||||
// if (default_project_id) {
|
|
||||||
// const url = `${this.apiVersion}/projects/${default_project_id}/users/${user_id}/roles/${adminId}`;
|
|
||||||
// await request.put(url);
|
|
||||||
// }
|
|
||||||
const promiseList = [];
|
const promiseList = [];
|
||||||
if (select_user_group[0] || select_project[0]) {
|
if (select_user_group[0] || select_project[0]) {
|
||||||
const newProjects = Object.keys(newProjectRoles);
|
const newProjects = Object.keys(newProjectRoles);
|
||||||
@ -99,7 +122,7 @@ export class UserStore extends Base {
|
|||||||
|
|
||||||
@action
|
@action
|
||||||
async fetchDomain() {
|
async fetchDomain() {
|
||||||
const doaminsResult = await request.get(`${this.apiVersion}/domains`);
|
const doaminsResult = await this.domainClient.list();
|
||||||
this.domains = doaminsResult.domains;
|
this.domains = doaminsResult.domains;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,6 +136,40 @@ export class UserStore extends Base {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
async getUserProjects() {
|
||||||
|
this.userProjects.update({
|
||||||
|
isLoading: true,
|
||||||
|
});
|
||||||
|
const {
|
||||||
|
user: {
|
||||||
|
user: { id },
|
||||||
|
},
|
||||||
|
} = globalRootStore;
|
||||||
|
const { projects } = await this.client.projects.list(id);
|
||||||
|
this.userProjects.update({
|
||||||
|
data: projects,
|
||||||
|
isLoading: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
async getUserGroups() {
|
||||||
|
this.userGroups.update({
|
||||||
|
isLoading: true,
|
||||||
|
});
|
||||||
|
const {
|
||||||
|
user: {
|
||||||
|
user: { id },
|
||||||
|
},
|
||||||
|
} = globalRootStore;
|
||||||
|
const { groups } = await this.client.groups.list(id);
|
||||||
|
this.userGroups.update({
|
||||||
|
data: groups,
|
||||||
|
isLoading: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
getUserProjectRole = (user, roleAssignment, projectMapRole) => {
|
getUserProjectRole = (user, roleAssignment, projectMapRole) => {
|
||||||
if (roleAssignment.user) {
|
if (roleAssignment.user) {
|
||||||
@ -131,6 +188,17 @@ export class UserStore extends Base {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
getUserProjectWithRole = (projectMapRole, roles, projects) => {
|
||||||
|
return Object.keys(projectMapRole).map((key) => {
|
||||||
|
const item = projects.find((it) => it.id === key);
|
||||||
|
const roleItems = projectMapRole[key].map((roleId) =>
|
||||||
|
roles.find((it) => it.id === roleId)
|
||||||
|
);
|
||||||
|
item.roles = roleItems;
|
||||||
|
return item;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
@action
|
@action
|
||||||
async fetchList({
|
async fetchList({
|
||||||
limit,
|
limit,
|
||||||
@ -143,11 +211,13 @@ export class UserStore extends Base {
|
|||||||
} = {}) {
|
} = {}) {
|
||||||
this.list.isLoading = true;
|
this.list.isLoading = true;
|
||||||
// todo: no page, no limit, fetch all
|
// todo: no page, no limit, fetch all
|
||||||
const [roleAssignmentsReault, usersResult, roleResult] = await Promise.all([
|
const [roleAssignmentsReault, usersResult, roleResult, projectResult] =
|
||||||
request.get(`${this.apiVersion}/role_assignments`),
|
await Promise.all([
|
||||||
request.get(`${this.apiVersion}/users`),
|
this.roleAssignmentClient.list(),
|
||||||
request.get(`${this.apiVersion}/roles`),
|
this.client.list(),
|
||||||
]);
|
this.roleClient.list(),
|
||||||
|
this.projectClient.list(),
|
||||||
|
]);
|
||||||
const { users } = usersResult;
|
const { users } = usersResult;
|
||||||
const { roles } = roleResult;
|
const { roles } = roleResult;
|
||||||
const systemRoles = roles.filter(
|
const systemRoles = roles.filter(
|
||||||
@ -167,6 +237,11 @@ export class UserStore extends Base {
|
|||||||
systemRoleId,
|
systemRoleId,
|
||||||
projectMapSystemRole
|
projectMapSystemRole
|
||||||
);
|
);
|
||||||
|
user.projectItems = this.getUserProjectWithRole(
|
||||||
|
projectMapRole,
|
||||||
|
roles,
|
||||||
|
projectResult.projects
|
||||||
|
);
|
||||||
user.projects = projectMapRole;
|
user.projects = projectMapRole;
|
||||||
user.projectMapSystemRole = projectMapSystemRole;
|
user.projectMapSystemRole = projectMapSystemRole;
|
||||||
user.project_num = Object.keys(projectMapRole).length;
|
user.project_num = Object.keys(projectMapRole).length;
|
||||||
@ -195,9 +270,9 @@ export class UserStore extends Base {
|
|||||||
this.isLoading = true;
|
this.isLoading = true;
|
||||||
}
|
}
|
||||||
const [roleAssignmentsReault, usersResult, roleResult] = await Promise.all([
|
const [roleAssignmentsReault, usersResult, roleResult] = await Promise.all([
|
||||||
request.get(`${this.apiVersion}/role_assignments`),
|
this.roleAssignmentClient.list(),
|
||||||
request.get(`${this.apiVersion}/users/${id}`),
|
this.client.show(id),
|
||||||
request.get(`${this.apiVersion}/roles`),
|
this.roleClient.list(),
|
||||||
]);
|
]);
|
||||||
const { roles } = roleResult;
|
const { roles } = roleResult;
|
||||||
const systemRoles = roles.filter(
|
const systemRoles = roles.filter(
|
||||||
@ -241,43 +316,39 @@ export class UserStore extends Base {
|
|||||||
|
|
||||||
@action
|
@action
|
||||||
async enable({ id }) {
|
async enable({ id }) {
|
||||||
const url = `${this.apiVersion}/users/${id}`;
|
|
||||||
const reqBody = {
|
const reqBody = {
|
||||||
user: { enabled: true },
|
user: { enabled: true },
|
||||||
};
|
};
|
||||||
return this.submitting(request.patch(url, reqBody));
|
return this.submitting(this.client.patch(id, reqBody));
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
async forbidden({ id }) {
|
async forbidden({ id }) {
|
||||||
const url = `${this.apiVersion}/users/${id}`;
|
|
||||||
const reqBody = {
|
const reqBody = {
|
||||||
user: { enabled: false },
|
user: { enabled: false },
|
||||||
};
|
};
|
||||||
return this.submitting(request.patch(url, reqBody));
|
return this.submitting(this.client.patch(id, reqBody));
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
async changePassword({ id, password }) {
|
async changePassword({ id, password }) {
|
||||||
const url = `${this.apiVersion}/users/${id}`;
|
|
||||||
const reqBody = {
|
const reqBody = {
|
||||||
user: { password },
|
user: { password },
|
||||||
};
|
};
|
||||||
return this.submitting(request.patch(url, reqBody));
|
return this.submitting(this.client.patch(id, reqBody));
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
async changePasswordUser({ id, password, original_password }) {
|
async changePasswordUser({ id, password, original_password }) {
|
||||||
const url = `${this.apiVersion}/users/${id}/password`;
|
|
||||||
const reqBody = {
|
const reqBody = {
|
||||||
user: { password, original_password },
|
user: { password, original_password },
|
||||||
};
|
};
|
||||||
return this.submitting(request.post(url, reqBody));
|
return this.submitting(this.client.updatePassword(id, reqBody));
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
async fetchProject() {
|
async fetchProject() {
|
||||||
const projectsResult = await request.get(`${this.apiVersion}/projects`);
|
const projectsResult = await this.projectClient.list();
|
||||||
this.projects = projectsResult.projects;
|
this.projects = projectsResult.projects;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -285,9 +356,9 @@ export class UserStore extends Base {
|
|||||||
async fetchSystemRole({ id, projects }) {
|
async fetchSystemRole({ id, projects }) {
|
||||||
this.systemRoles = [];
|
this.systemRoles = [];
|
||||||
const project_id = projects[0].id;
|
const project_id = projects[0].id;
|
||||||
// const rolesResult = await request.get(`${this.apiVersion}/system/users/${id}/roles`);
|
const projectResult = await this.projectClient.users.roles.list(
|
||||||
const projectResult = await request.get(
|
project_id,
|
||||||
`${this.apiVersion}/projects/${project_id}/users/${id}/roles/`
|
id
|
||||||
);
|
);
|
||||||
const systemRole = projectResult.roles.filter(
|
const systemRole = projectResult.roles.filter(
|
||||||
(it) => it.name.includes('system_') && !it.name.includes('_system_')
|
(it) => it.name.includes('system_') && !it.name.includes('_system_')
|
||||||
@ -297,48 +368,33 @@ export class UserStore extends Base {
|
|||||||
|
|
||||||
@action
|
@action
|
||||||
async assignSystemRole({ id, role_id }) {
|
async assignSystemRole({ id, role_id }) {
|
||||||
const result = request.put(
|
return this.systemUserClient.roles.update(id, role_id);
|
||||||
`${this.apiVersion}/system/users/${id}/roles/${role_id}`
|
|
||||||
);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
async deleteSystemRole({ id, role_id }) {
|
async deleteSystemRole({ id, role_id }) {
|
||||||
const result = request.delete(
|
return this.systemUserClient.delete(id, role_id);
|
||||||
`${this.apiVersion}/system/users/${id}/roles/${role_id}`
|
|
||||||
);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
async fetchDomainRole({ id, domain_id }) {
|
async fetchDomainRole({ id, domain_id }) {
|
||||||
this.domainRoles = [];
|
this.domainRoles = [];
|
||||||
const rolesResult = await request.get(
|
const rolesResult = await this.domainClient.users.roles.list(id, domain_id);
|
||||||
`${this.apiVersion}/domains/${domain_id}/users/${id}/roles`
|
|
||||||
);
|
|
||||||
this.domainRoles = rolesResult.roles;
|
this.domainRoles = rolesResult.roles;
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
async assignDomainRole({ id, role_id, domain_id }) {
|
async assignDomainRole({ id, role_id, domain_id }) {
|
||||||
const result = request.put(
|
return this.domainClient.users.roles.update(domain_id, id, role_id);
|
||||||
`${this.apiVersion}/domains/${domain_id}/users/${id}/roles/${role_id}`
|
|
||||||
);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
async deleteDomainRole({ id, role_id, domain_id }) {
|
async deleteDomainRole({ id, role_id, domain_id }) {
|
||||||
const result = request.delete(
|
return this.domainClient.users.roles.delete(domain_id, id, role_id);
|
||||||
`${this.apiVersion}/domains/${domain_id}/users/${id}/roles/${role_id}`
|
|
||||||
);
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
async edit(id, { email, phone, real_name, description, name }) {
|
async edit(id, { email, phone, real_name, description, name }) {
|
||||||
const url = `${this.apiVersion}/users/${id}`;
|
|
||||||
const reqBody = {
|
const reqBody = {
|
||||||
user: {
|
user: {
|
||||||
email,
|
email,
|
||||||
@ -348,7 +404,7 @@ export class UserStore extends Base {
|
|||||||
name,
|
name,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
return this.submitting(request.patch(url, reqBody));
|
return this.submitting(this.client.patch(id, reqBody));
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
@ -363,36 +419,34 @@ export class UserStore extends Base {
|
|||||||
this.list.isLoading = true;
|
this.list.isLoading = true;
|
||||||
const { domainId } = filters;
|
const { domainId } = filters;
|
||||||
const params = {};
|
const params = {};
|
||||||
const result = await request.get(this.getListUrl(), params);
|
const result = await this.client.list(params);
|
||||||
let data = get(result, this.listResponseKey, []);
|
let data = get(result, this.listResponseKey, []);
|
||||||
data = data.filter((it) => it.domain_id === domainId);
|
data = data.filter((it) => it.domain_id === domainId);
|
||||||
const items = data.map(this.mapper);
|
const items = data.map(this.mapper);
|
||||||
const newData = await this.listDidFetch(items);
|
const newData = await this.listDidFetch(items);
|
||||||
Promise.all(
|
Promise.all(newData.map((it) => this.client.projects.list(it.id))).then(
|
||||||
newData.map((it) =>
|
(projectResult) => {
|
||||||
request.get(`${this.apiVersion}/users/${it.id}/projects`)
|
newData.map((it, index) => {
|
||||||
)
|
const { projects } = projectResult[index];
|
||||||
).then((projectResult) => {
|
it.projects = projects;
|
||||||
newData.map((it, index) => {
|
it.project_num = projects.length;
|
||||||
const { projects } = projectResult[index];
|
return it;
|
||||||
it.projects = projects;
|
});
|
||||||
it.project_num = projects.length;
|
this.list.update({
|
||||||
return it;
|
data: newData,
|
||||||
});
|
total: items.length || 0,
|
||||||
this.list.update({
|
limit: Number(limit) || 10,
|
||||||
data: newData,
|
page: Number(page) || 1,
|
||||||
total: items.length || 0,
|
sortKey,
|
||||||
limit: Number(limit) || 10,
|
sortOrder,
|
||||||
page: Number(page) || 1,
|
filters,
|
||||||
sortKey,
|
isLoading: false,
|
||||||
sortOrder,
|
...(this.list.silent ? {} : { selectedRowKeys: [] }),
|
||||||
filters,
|
});
|
||||||
isLoading: false,
|
|
||||||
...(this.list.silent ? {} : { selectedRowKeys: [] }),
|
|
||||||
});
|
|
||||||
|
|
||||||
return items;
|
return items;
|
||||||
});
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
@ -408,9 +462,9 @@ export class UserStore extends Base {
|
|||||||
const { projectId } = filters;
|
const { projectId } = filters;
|
||||||
const params = {};
|
const params = {};
|
||||||
const [roleAssignmentsReault, roleResult, result] = await Promise.all([
|
const [roleAssignmentsReault, roleResult, result] = await Promise.all([
|
||||||
request.get(`${this.apiVersion}/role_assignments`),
|
this.roleAssignmentClient.list(),
|
||||||
request.get(`${this.apiVersion}/roles`),
|
this.roleClient.list(),
|
||||||
request.get(this.getListUrl(), params),
|
this.client.list(params),
|
||||||
]);
|
]);
|
||||||
const projectUserIds = [];
|
const projectUserIds = [];
|
||||||
const userMapRole = {};
|
const userMapRole = {};
|
||||||
@ -435,34 +489,32 @@ export class UserStore extends Base {
|
|||||||
data = data.filter((it) => projectUserIds.includes(it.id));
|
data = data.filter((it) => projectUserIds.includes(it.id));
|
||||||
const items = data.map(this.mapper);
|
const items = data.map(this.mapper);
|
||||||
const newData = await this.listDidFetch(items);
|
const newData = await this.listDidFetch(items);
|
||||||
Promise.all(
|
Promise.all(newData.map((it) => this.client.projects.list(it.id))).then(
|
||||||
newData.map((it) =>
|
(projectResult) => {
|
||||||
request.get(`${this.apiVersion}/users/${it.id}/projects`)
|
newData.map((it, index) => {
|
||||||
)
|
const { projects } = projectResult[index];
|
||||||
).then((projectResult) => {
|
it.projects = projects;
|
||||||
newData.map((it, index) => {
|
it.project_num = projects.length;
|
||||||
const { projects } = projectResult[index];
|
it.project_roles = userMapRole[it.id].map(
|
||||||
it.projects = projects;
|
(r) => roleResult.roles.filter((role) => role.id === r)[0].name
|
||||||
it.project_num = projects.length;
|
);
|
||||||
it.project_roles = userMapRole[it.id].map(
|
return it;
|
||||||
(r) => roleResult.roles.filter((role) => role.id === r)[0].name
|
});
|
||||||
);
|
this.list.update({
|
||||||
return it;
|
data: newData,
|
||||||
});
|
total: items.length || 0,
|
||||||
this.list.update({
|
limit: Number(limit) || 10,
|
||||||
data: newData,
|
page: Number(page) || 1,
|
||||||
total: items.length || 0,
|
sortKey,
|
||||||
limit: Number(limit) || 10,
|
sortOrder,
|
||||||
page: Number(page) || 1,
|
filters,
|
||||||
sortKey,
|
isLoading: false,
|
||||||
sortOrder,
|
...(this.list.silent ? {} : { selectedRowKeys: [] }),
|
||||||
filters,
|
});
|
||||||
isLoading: false,
|
|
||||||
...(this.list.silent ? {} : { selectedRowKeys: [] }),
|
|
||||||
});
|
|
||||||
|
|
||||||
return items;
|
return items;
|
||||||
});
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
@ -477,38 +529,33 @@ export class UserStore extends Base {
|
|||||||
this.list.isLoading = true;
|
this.list.isLoading = true;
|
||||||
const { groupId } = filters;
|
const { groupId } = filters;
|
||||||
const params = {};
|
const params = {};
|
||||||
const result = await request.get(
|
const result = await this.groupClient.users.list(groupId, params);
|
||||||
`${this.apiVersion}/groups/${groupId}/users`,
|
|
||||||
params
|
|
||||||
);
|
|
||||||
const data = get(result, this.listResponseKey, []);
|
const data = get(result, this.listResponseKey, []);
|
||||||
const items = data.map(this.mapper);
|
const items = data.map(this.mapper);
|
||||||
const newData = await this.listDidFetch(items);
|
const newData = await this.listDidFetch(items);
|
||||||
Promise.all(
|
Promise.all(newData.map((it) => this.client.projects.list(it.id))).then(
|
||||||
newData.map((it) =>
|
(projectResult) => {
|
||||||
request.get(`${this.apiVersion}/users/${it.id}/projects`)
|
newData.map((it, index) => {
|
||||||
)
|
const { projects } = projectResult[index];
|
||||||
).then((projectResult) => {
|
it.projects = projects;
|
||||||
newData.map((it, index) => {
|
it.project_num = projects.length;
|
||||||
const { projects } = projectResult[index];
|
return it;
|
||||||
it.projects = projects;
|
});
|
||||||
it.project_num = projects.length;
|
this.list.update({
|
||||||
return it;
|
data: newData,
|
||||||
});
|
total: items.length || 0,
|
||||||
this.list.update({
|
limit: Number(limit) || 10,
|
||||||
data: newData,
|
page: Number(page) || 1,
|
||||||
total: items.length || 0,
|
sortKey,
|
||||||
limit: Number(limit) || 10,
|
sortOrder,
|
||||||
page: Number(page) || 1,
|
filters,
|
||||||
sortKey,
|
isLoading: false,
|
||||||
sortOrder,
|
...(this.list.silent ? {} : { selectedRowKeys: [] }),
|
||||||
filters,
|
});
|
||||||
isLoading: false,
|
|
||||||
...(this.list.silent ? {} : { selectedRowKeys: [] }),
|
|
||||||
});
|
|
||||||
|
|
||||||
return items;
|
return items;
|
||||||
});
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@action
|
@action
|
||||||
@ -524,9 +571,9 @@ export class UserStore extends Base {
|
|||||||
const { roleId } = filters;
|
const { roleId } = filters;
|
||||||
const params = {};
|
const params = {};
|
||||||
const [roleAssignmentsReault, projectResult, result] = await Promise.all([
|
const [roleAssignmentsReault, projectResult, result] = await Promise.all([
|
||||||
request.get(`${this.apiVersion}/role_assignments`),
|
this.roleAssignmentClient.list(),
|
||||||
request.get(`${this.apiVersion}/projects`),
|
this.projectClient.list(),
|
||||||
request.get(this.getListUrl(), params),
|
this.client.list(params),
|
||||||
]);
|
]);
|
||||||
const projectRoleUsers = {};
|
const projectRoleUsers = {};
|
||||||
const systemRoleUsers = {};
|
const systemRoleUsers = {};
|
||||||
@ -542,9 +589,9 @@ export class UserStore extends Base {
|
|||||||
(it) => it.id === project.id
|
(it) => it.id === project.id
|
||||||
);
|
);
|
||||||
if (projectRoleUsers[user_id]) {
|
if (projectRoleUsers[user_id]) {
|
||||||
projectRoleUsers[user_id].push(projectData.name);
|
projectRoleUsers[user_id].push(projectData);
|
||||||
} else {
|
} else {
|
||||||
projectRoleUsers[user_id] = [projectData.name];
|
projectRoleUsers[user_id] = [projectData];
|
||||||
}
|
}
|
||||||
} else if (role_id === roleId && system) {
|
} else if (role_id === roleId && system) {
|
||||||
systemRoleUsers[user_id] = system.all;
|
systemRoleUsers[user_id] = system.all;
|
||||||
@ -555,7 +602,7 @@ export class UserStore extends Base {
|
|||||||
const items = data
|
const items = data
|
||||||
.filter((it) => projectRoleUsers[it.id] || systemRoleUsers[it.id])
|
.filter((it) => projectRoleUsers[it.id] || systemRoleUsers[it.id])
|
||||||
.map((it) => ({
|
.map((it) => ({
|
||||||
projectScope: projectRoleUsers[it.id] || [],
|
projects: projectRoleUsers[it.id] || [],
|
||||||
systemScope: systemRoleUsers[it.id] || [],
|
systemScope: systemRoleUsers[it.id] || [],
|
||||||
...it,
|
...it,
|
||||||
}));
|
}));
|
||||||
|
@ -13,30 +13,34 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { action } from 'mobx';
|
import { action } from 'mobx';
|
||||||
import { neutronBase } from 'utils/constants';
|
import client from 'client';
|
||||||
|
import { isArray } from 'lodash';
|
||||||
import Base from '../base';
|
import Base from '../base';
|
||||||
|
|
||||||
export class NeutronAgentNetworkStore extends Base {
|
export class NeutronAgentNetworkStore extends Base {
|
||||||
get module() {
|
get client() {
|
||||||
return 'networks';
|
return client.neutron.agents.dhcpNetworks;
|
||||||
}
|
}
|
||||||
|
|
||||||
get apiVersion() {
|
get isSubResource() {
|
||||||
return neutronBase();
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
get responseKey() {
|
getFatherResourceId = (params) => params.agentId;
|
||||||
return 'network';
|
|
||||||
}
|
|
||||||
|
|
||||||
get listFilterByProject() {
|
get listFilterByProject() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
getListUrl = ({ agentId }) =>
|
get mapper() {
|
||||||
`${this.apiVersion}/agents/${agentId}/dhcp-networks`;
|
return (data) => {
|
||||||
|
const { created_at } = data;
|
||||||
getDetailUrl = ({ agentId, id }) => `${this.getListUrl({ agentId })}/${id}`;
|
return {
|
||||||
|
...data,
|
||||||
|
standard_attr_id: created_at,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
async listDidFetch(items, allProjects, filters) {
|
async listDidFetch(items, allProjects, filters) {
|
||||||
const { agentId } = filters;
|
const { agentId } = filters;
|
||||||
@ -48,11 +52,16 @@ export class NeutronAgentNetworkStore extends Base {
|
|||||||
|
|
||||||
@action
|
@action
|
||||||
remove = ({ agentId, id }) =>
|
remove = ({ agentId, id }) =>
|
||||||
this.submitting(request.delete(this.getDetailUrl({ agentId, id })));
|
this.submitting(this.client.delete(agentId, id));
|
||||||
|
|
||||||
@action
|
@action
|
||||||
add = ({ agentId }, body) =>
|
add = ({ agentId }, body) => {
|
||||||
this.submitting(request.post(this.getListUrl({ agentId }), body));
|
if (!isArray(body)) {
|
||||||
|
return this.submitting(this.client.create(agentId, body));
|
||||||
|
}
|
||||||
|
const reqs = body.map((it) => this.client.create(agentId, it));
|
||||||
|
return this.submitting(Promise.allSettled(reqs));
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const globalNeutronAgentNetworkStore = new NeutronAgentNetworkStore();
|
const globalNeutronAgentNetworkStore = new NeutronAgentNetworkStore();
|
||||||
|
@ -13,34 +13,28 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { action } from 'mobx';
|
import { action } from 'mobx';
|
||||||
import { neutronBase } from 'utils/constants';
|
import client from 'client';
|
||||||
|
import { isArray } from 'lodash';
|
||||||
import Base from '../base';
|
import Base from '../base';
|
||||||
|
|
||||||
export class NeutronAgentRouterStore extends Base {
|
export class NeutronAgentRouterStore extends Base {
|
||||||
get module() {
|
get client() {
|
||||||
return 'routers';
|
return client.neutron.agents.l3Routers;
|
||||||
}
|
|
||||||
|
|
||||||
get apiVersion() {
|
|
||||||
return neutronBase();
|
|
||||||
}
|
|
||||||
|
|
||||||
get responseKey() {
|
|
||||||
return 'router';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get listFilterByProject() {
|
get listFilterByProject() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
getListUrl = ({ agentId }) =>
|
get isSubResource() {
|
||||||
`${this.apiVersion}/agents/${agentId}/l3-routers`;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
getDetailUrl = ({ agentId, id }) => `${this.getListUrl({ agentId })}/${id}`;
|
getFatherResourceId = (params) => params.agentId;
|
||||||
|
|
||||||
get mapper() {
|
get mapper() {
|
||||||
return (data) => {
|
return (data) => {
|
||||||
const externalGateway = data.external_gateway_info;
|
const { external_gateway_info: externalGateway, created_at } = data || {};
|
||||||
return {
|
return {
|
||||||
...data,
|
...data,
|
||||||
hasExternalGateway: !!externalGateway,
|
hasExternalGateway: !!externalGateway,
|
||||||
@ -50,6 +44,7 @@ export class NeutronAgentRouterStore extends Base {
|
|||||||
(externalGateway && externalGateway.network_name) || '',
|
(externalGateway && externalGateway.network_name) || '',
|
||||||
externalFixedIps:
|
externalFixedIps:
|
||||||
(externalGateway && externalGateway.external_fixed_ips) || [],
|
(externalGateway && externalGateway.external_fixed_ips) || [],
|
||||||
|
standard_attr_id: created_at,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -64,11 +59,16 @@ export class NeutronAgentRouterStore extends Base {
|
|||||||
|
|
||||||
@action
|
@action
|
||||||
remove = ({ agentId, id }) =>
|
remove = ({ agentId, id }) =>
|
||||||
this.submitting(request.delete(this.getDetailUrl({ agentId, id })));
|
this.submitting(this.client.delete(agentId, id));
|
||||||
|
|
||||||
@action
|
@action
|
||||||
add = ({ agentId }, body) =>
|
add = ({ agentId }, body) => {
|
||||||
this.submitting(request.post(this.getListUrl({ agentId }), body));
|
if (!isArray(body)) {
|
||||||
|
return this.submitting(this.client.create(agentId, body));
|
||||||
|
}
|
||||||
|
const reqs = body.map((it) => this.client.create(agentId, it));
|
||||||
|
return this.submitting(Promise.allSettled(reqs));
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const globalNeutronAgentRouterStore = new NeutronAgentRouterStore();
|
const globalNeutronAgentRouterStore = new NeutronAgentRouterStore();
|
||||||
|
@ -12,20 +12,12 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { neutronBase } from 'utils/constants';
|
import client from 'client';
|
||||||
import Base from '../base';
|
import Base from '../base';
|
||||||
|
|
||||||
export class NeutronAgentStore extends Base {
|
export class NeutronAgentStore extends Base {
|
||||||
get module() {
|
get client() {
|
||||||
return 'agents';
|
return client.neutron.agents;
|
||||||
}
|
|
||||||
|
|
||||||
get apiVersion() {
|
|
||||||
return neutronBase();
|
|
||||||
}
|
|
||||||
|
|
||||||
get responseKey() {
|
|
||||||
return 'agent';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get listFilterByProject() {
|
get listFilterByProject() {
|
||||||
|
@ -12,26 +12,25 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { neutronBase } from 'utils/constants';
|
|
||||||
import globalNetworkStore from 'stores/neutron/network';
|
import globalNetworkStore from 'stores/neutron/network';
|
||||||
import globalFloatingIpsStore from 'stores/neutron/floatingIp';
|
import globalFloatingIpsStore from 'stores/neutron/floatingIp';
|
||||||
|
import client from 'client';
|
||||||
import Base from '../base';
|
import Base from '../base';
|
||||||
|
|
||||||
export class FixedIpStore extends Base {
|
export class FixedIpStore extends Base {
|
||||||
get module() {
|
get client() {
|
||||||
return 'ports';
|
return client.neutron.ports;
|
||||||
}
|
}
|
||||||
|
|
||||||
get apiVersion() {
|
get paramsFunc() {
|
||||||
return neutronBase();
|
return ({ all_projects, ...rest }) => rest;
|
||||||
}
|
}
|
||||||
|
|
||||||
get listResponseKey() {
|
async getItemFloatingIPs(fixed_ip, portId) {
|
||||||
return 'ports';
|
return globalFloatingIpsStore.pureFetchList({
|
||||||
}
|
fixed_ip_address: fixed_ip,
|
||||||
|
port_id: portId,
|
||||||
async getItemFloatingIPs(fixed_ip) {
|
});
|
||||||
return globalFloatingIpsStore.pureFetchList({ fixed_ip_address: fixed_ip });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async listDidFetch(items) {
|
async listDidFetch(items) {
|
||||||
@ -39,7 +38,7 @@ export class FixedIpStore extends Base {
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
const port = items[0];
|
const port = items[0];
|
||||||
const { fixed_ips: fixedIPs = [] } = port;
|
const { fixed_ips: fixedIPs = [], id } = port;
|
||||||
const subnets = Array.from(new Set(fixedIPs.map((it) => it.subnet_id)));
|
const subnets = Array.from(new Set(fixedIPs.map((it) => it.subnet_id)));
|
||||||
const subnetResults = await Promise.all(
|
const subnetResults = await Promise.all(
|
||||||
subnets.map((item) => globalNetworkStore.fetchSubnetDetail({ id: item }))
|
subnets.map((item) => globalNetworkStore.fetchSubnetDetail({ id: item }))
|
||||||
@ -49,7 +48,7 @@ export class FixedIpStore extends Base {
|
|||||||
subnetMap[result.id] = result;
|
subnetMap[result.id] = result;
|
||||||
});
|
});
|
||||||
const fipResults = await Promise.all(
|
const fipResults = await Promise.all(
|
||||||
fixedIPs.map((item) => this.getItemFloatingIPs(item.ip_address))
|
fixedIPs.map((item) => this.getItemFloatingIPs(item.ip_address, id))
|
||||||
);
|
);
|
||||||
return fixedIPs.map((it, index) => ({
|
return fixedIPs.map((it, index) => ({
|
||||||
...it,
|
...it,
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user