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'),
|
||||
styles: root('src/styles'),
|
||||
resources: root('src/resources'),
|
||||
client: root('src/client'),
|
||||
},
|
||||
},
|
||||
plugins: [
|
||||
|
@ -81,7 +81,8 @@
|
||||
"react-highcharts": "^16.0.2",
|
||||
"react-router": "^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": {
|
||||
"@babel/core": "^7.14.3",
|
||||
|
@ -16,7 +16,7 @@
|
||||
* @param {String} key api url
|
||||
* @returns {String}
|
||||
*/
|
||||
import { cinderBase } from 'utils/constants';
|
||||
import { cinderBase } from 'client/client/constants';
|
||||
|
||||
const getCinderBaseUrl = (key) => `${cinderBase()}/${key}`;
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
* @param {String} key api url
|
||||
* @returns {String}
|
||||
*/
|
||||
import { glanceBase } from 'utils/constants';
|
||||
import { glanceBase } from 'client/client/constants';
|
||||
|
||||
const getGlanceBaseUrl = (key) => `${glanceBase()}/${key}`;
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
* @param {String} key api url
|
||||
* @returns {String}
|
||||
*/
|
||||
import { gocronBase } from 'utils/constants';
|
||||
import { gocronBase } from 'client/client/constants';
|
||||
|
||||
const getGocronBaseUrl = (key) => `${gocronBase()}/${key}`;
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
* @param {String} key api url
|
||||
* @returns {String}
|
||||
*/
|
||||
import { heatBase } from 'utils/constants';
|
||||
import { heatBase } from 'client/client/constants';
|
||||
|
||||
const getHeatBaseUrl = (key) => `${heatBase()}/${key}`;
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
* @param {String} key api url
|
||||
* @returns {String}
|
||||
*/
|
||||
import { ironicInspectorBase } from 'utils/constants';
|
||||
import { ironicInspectorBase } from 'client/client/constants';
|
||||
|
||||
const getIronicInspectorBaseUrl = (key) => `${ironicInspectorBase()}/${key}`;
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
* @param {String} key api url
|
||||
* @returns {String}
|
||||
*/
|
||||
import { ironicBase } from 'utils/constants';
|
||||
import { ironicBase } from 'client/client/constants';
|
||||
|
||||
const getIronicBaseUrl = (key) => `${ironicBase()}/${key}`;
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
* @param {String} key api url
|
||||
* @returns {String}
|
||||
*/
|
||||
import { keystoneBase } from 'utils/constants';
|
||||
import { keystoneBase } from 'client/client/constants';
|
||||
|
||||
const getKeystoneBaseUrl = (key) => `${keystoneBase()}/${key}`;
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
* @param {String} key api url
|
||||
* @returns {String}
|
||||
*/
|
||||
import { neutronBase } from 'utils/constants';
|
||||
import { neutronBase } from 'client/client/constants';
|
||||
|
||||
const getNeutronBaseUrl = (key) => `${neutronBase()}/${key}`;
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
* @param {String} key api url
|
||||
* @returns {String}
|
||||
*/
|
||||
import { novaBase } from 'utils/constants';
|
||||
import { novaBase } from 'client/client/constants';
|
||||
|
||||
const getNovaBaseUrl = (key) => `${novaBase()}/${key}`;
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
* @param {String} key api url
|
||||
* @returns {String}
|
||||
*/
|
||||
import { octaviaBase } from 'utils/constants';
|
||||
import { octaviaBase } from 'client/client/constants';
|
||||
|
||||
const getOctaviaBaseUrl = (key) => `${octaviaBase()}/${key}`;
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
* @param {String} key api url
|
||||
* @returns {String}
|
||||
*/
|
||||
import { pankoBase } from 'utils/constants';
|
||||
import { pankoBase } from 'client/client/constants';
|
||||
|
||||
const getPankoBaseUrl = (key) => `${pankoBase()}/${key}`;
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
* @param {String} key api url
|
||||
* @returns {String}
|
||||
*/
|
||||
import { placementBase } from 'utils/constants';
|
||||
import { placementBase } from 'client/client/constants';
|
||||
|
||||
const getPlacementBaseUrl = (key) => `${placementBase()}/${key}`;
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
* @param {String} key api url
|
||||
* @returns {String}
|
||||
*/
|
||||
import { skylineBase } from 'utils/constants';
|
||||
import { skylineBase } from 'client/client/constants';
|
||||
|
||||
const getSkylineBaseUrl = (key) => `${skylineBase()}/${key}`;
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
* @param {String} key api url
|
||||
* @returns {String}
|
||||
*/
|
||||
import { swiftBase } from 'utils/constants';
|
||||
import { swiftBase } from 'client/client/constants';
|
||||
|
||||
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 '';
|
||||
}
|
||||
|
||||
get currentUser() {
|
||||
const { user } = this.props.rootStore || {};
|
||||
return user || {};
|
||||
}
|
||||
|
||||
get isAdminPage() {
|
||||
const { pathname = '' } = this.props.location || {};
|
||||
return isAdminPage(pathname);
|
||||
@ -114,11 +119,11 @@ export default class BaseForm extends React.Component {
|
||||
}
|
||||
|
||||
get currentProjectId() {
|
||||
return globals.user.project.id;
|
||||
return this.props.rootStore.projectId;
|
||||
}
|
||||
|
||||
get currentProjectName() {
|
||||
return globals.user.project.name;
|
||||
return this.props.rootStore.projectName;
|
||||
}
|
||||
|
||||
getUrl(path, adminStr) {
|
||||
@ -258,7 +263,7 @@ export default class BaseForm extends React.Component {
|
||||
this.responseError = err;
|
||||
this.showNotice && Notify.errorWithDetail(err, this.errorText);
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(err);
|
||||
console.log('err', err);
|
||||
if (callback && isFunction(callback)) {
|
||||
callback(false, true);
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ export default class NetworkSelectTable extends Component {
|
||||
}
|
||||
|
||||
get currentProjectId() {
|
||||
return globals.user.project.id;
|
||||
return this.props.rootStore.projectId;
|
||||
}
|
||||
|
||||
get hasAdminRole() {
|
||||
|
@ -34,7 +34,7 @@ export default class VolumeSelectTable extends Component {
|
||||
}
|
||||
|
||||
get currentProjectId() {
|
||||
return globals.user.project.id;
|
||||
return this.props.rootStore.projectId;
|
||||
}
|
||||
|
||||
get hasAdminRole() {
|
||||
|
@ -126,7 +126,7 @@ class AvatarDropdown extends React.Component {
|
||||
<ItemActionButtons
|
||||
actions={{ moreActions: [{ action: Password }] }}
|
||||
onFinishAction={this.afterChangePassword}
|
||||
item={globals.user.user}
|
||||
item={this.user && this.user.user}
|
||||
isWide
|
||||
/>
|
||||
</Menu.Item>
|
||||
|
@ -28,7 +28,7 @@ const gotoConsole = (type, props) => {
|
||||
};
|
||||
|
||||
const GlobalHeaderRight = (props) => {
|
||||
const { isAdminPage = false, rootStore: { hasAdminRole = false } = {} } =
|
||||
const { isAdminPage = false, rootStore: { hasAdminPageRole = false } = {} } =
|
||||
props;
|
||||
let linkRender = null;
|
||||
if (isAdminPage) {
|
||||
@ -41,7 +41,7 @@ const GlobalHeaderRight = (props) => {
|
||||
{t('Console')}
|
||||
</Button>
|
||||
);
|
||||
} else if (hasAdminRole) {
|
||||
} else if (hasAdminPageRole) {
|
||||
linkRender = (
|
||||
<Button
|
||||
type="link"
|
||||
|
@ -107,6 +107,15 @@ export default class BaseStepForm extends React.Component {
|
||||
return this.checkEndpoint && !this.endpoint;
|
||||
}
|
||||
|
||||
get currentUser() {
|
||||
const { user } = this.props.rootStore || {};
|
||||
return user || {};
|
||||
}
|
||||
|
||||
get currentProjectId() {
|
||||
return this.props.rootStore.projectId;
|
||||
}
|
||||
|
||||
get labelCol() {
|
||||
return {
|
||||
xs: { span: 4 },
|
||||
@ -218,9 +227,10 @@ export default class BaseStepForm extends React.Component {
|
||||
Notify.success(this.successText);
|
||||
},
|
||||
(err) => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('reject', err);
|
||||
Notify.errorWithDetail(err, this.errorText);
|
||||
this.responseError = err;
|
||||
const { response: { data: responseData } = {} } = err;
|
||||
console.log('err', err, responseData);
|
||||
Notify.errorWithDetail(responseData, this.errorText);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
@ -243,7 +243,8 @@ class ActionButton extends Component {
|
||||
const message = submitErrorMsgBatch
|
||||
? submitErrorMsgBatch(data)
|
||||
: 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);
|
||||
};
|
||||
|
||||
@ -260,10 +261,12 @@ class ActionButton extends Component {
|
||||
return;
|
||||
}
|
||||
const { submitErrorMsg } = this.props.action;
|
||||
const { data: responseData } = error.response || error || {};
|
||||
const realError = responseData || error;
|
||||
const message = submitErrorMsg
|
||||
? submitErrorMsg(data, error)
|
||||
? submitErrorMsg(data, realError)
|
||||
: getDefaultMsg(this.props.action, data).submitErrorMsg;
|
||||
Notify.errorWithDetail(error, message);
|
||||
Notify.errorWithDetail(realError, message);
|
||||
this.onCallback(false, true);
|
||||
};
|
||||
|
||||
|
@ -59,9 +59,16 @@ function DropdownActionButton({
|
||||
const menuItems = actions.map((it) => {
|
||||
const key = `table-batch-more-${generateId()}`;
|
||||
const newConf = updateConf(it, selectedItems);
|
||||
const { buttonType } = newConf;
|
||||
const { buttonType, name } = newConf;
|
||||
newConf.onFinishAction = onFinishAction;
|
||||
newConf.danger = buttonType === 'danger';
|
||||
if (!selectedItems.length) {
|
||||
return (
|
||||
<Menu.Item key={key} disabled style={{ textAlign: 'center' }}>
|
||||
{name}
|
||||
</Menu.Item>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Menu.Item key={key}>
|
||||
<ActionButton
|
||||
|
@ -55,8 +55,8 @@ export default class TablePrimaryButtons extends Component {
|
||||
this.getActionsAllowed();
|
||||
}
|
||||
|
||||
componentDidUpdate(nextProps) {
|
||||
if (!isEqual(nextProps, this.props)) {
|
||||
componentDidUpdate(prevProps) {
|
||||
if (!isEqual(prevProps, this.props)) {
|
||||
this.getActionsAllowed();
|
||||
}
|
||||
}
|
||||
|
@ -223,8 +223,12 @@ export default class SimpleTable extends React.Component {
|
||||
}
|
||||
return {
|
||||
onClick: () => {
|
||||
const { selectedRowKeys, onChange, type, getCheckboxProps } =
|
||||
rowSelection;
|
||||
const {
|
||||
selectedRowKeys = [],
|
||||
onChange,
|
||||
type,
|
||||
getCheckboxProps,
|
||||
} = rowSelection || {};
|
||||
if (getCheckboxProps) {
|
||||
const { disabled } = getCheckboxProps(record);
|
||||
if (disabled) {
|
||||
|
@ -35,8 +35,13 @@ export default class BaseDetail extends React.Component {
|
||||
return id;
|
||||
}
|
||||
|
||||
get currentProject() {
|
||||
return globals.user.project.id;
|
||||
get currentUser() {
|
||||
const { user } = this.props.rootStore || {};
|
||||
return user || {};
|
||||
}
|
||||
|
||||
get currentProjectId() {
|
||||
return this.props.rootStore.projectId;
|
||||
}
|
||||
|
||||
get projectId() {
|
||||
@ -45,7 +50,7 @@ export default class BaseDetail extends React.Component {
|
||||
}
|
||||
|
||||
get isMyResource() {
|
||||
return this.projectId === this.currentProject;
|
||||
return this.projectId === this.currentProjectId;
|
||||
}
|
||||
|
||||
get detailData() {
|
||||
|
@ -271,8 +271,13 @@ export default class BaseList extends React.Component {
|
||||
return true;
|
||||
}
|
||||
|
||||
get currentUser() {
|
||||
const { user } = this.props.rootStore || {};
|
||||
return user || {};
|
||||
}
|
||||
|
||||
get currentProjectId() {
|
||||
return globals.user.project.id;
|
||||
return this.props.rootStore.projectId;
|
||||
}
|
||||
|
||||
get fetchDataByCurrentProject() {
|
||||
@ -480,7 +485,7 @@ export default class BaseList extends React.Component {
|
||||
}
|
||||
|
||||
getDataWithPolicy(params) {
|
||||
if (!globals.user) {
|
||||
if (!this.currentUser || isEmpty(this.currentUser)) {
|
||||
return;
|
||||
}
|
||||
if (this.endpointError) {
|
||||
@ -510,7 +515,7 @@ export default class BaseList extends React.Component {
|
||||
} catch (e) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('fetch list error', e);
|
||||
const { message = '', data, status } = e || {};
|
||||
const { message = '', data, status } = e.response || e || {};
|
||||
if (status === 500) {
|
||||
const sysErr = t('System is error, please try again later.');
|
||||
const title = `${t('Get {name} error.', {
|
||||
@ -520,7 +525,7 @@ export default class BaseList extends React.Component {
|
||||
} else {
|
||||
const error = {
|
||||
message: data || message || e || '',
|
||||
status: e.status,
|
||||
status,
|
||||
};
|
||||
Notify.errorWithDetail(
|
||||
error,
|
||||
|
@ -245,12 +245,8 @@ export default class DetailBase extends React.Component {
|
||||
catch = (e) => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(e);
|
||||
if (
|
||||
e.code === 404 ||
|
||||
e.status === 404 ||
|
||||
e.reason === 'NotFound' ||
|
||||
e.reason === 'Not Found'
|
||||
) {
|
||||
const { data, status } = e.response || e || {};
|
||||
if (status === 404) {
|
||||
this.setState({ notFound: true });
|
||||
Notify.warn(
|
||||
t('{name} {id} could not be found.', {
|
||||
@ -260,8 +256,8 @@ export default class DetailBase extends React.Component {
|
||||
);
|
||||
} else {
|
||||
const error = {
|
||||
message: e,
|
||||
status: e.code || e.status,
|
||||
message: data,
|
||||
status,
|
||||
};
|
||||
Notify.errorWithDetail(
|
||||
error,
|
||||
|
@ -21,34 +21,13 @@ import { ConfigProvider } from 'antd';
|
||||
import zhCN from 'antd/es/locale/zh_CN';
|
||||
import enUS from 'antd/es/locale/en_US';
|
||||
import globalRootStore from 'stores/root';
|
||||
import request from 'utils/request';
|
||||
import PageLoading from 'components/PageLoading';
|
||||
import i18n from './i18n';
|
||||
import App from './App';
|
||||
|
||||
window.t = i18n.t;
|
||||
window.request = request;
|
||||
window.globals = {
|
||||
user: null,
|
||||
};
|
||||
|
||||
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 history = syncHistoryWithStore(browserHistory, store.routing);
|
||||
const lang = i18n.getLocale();
|
||||
|
@ -61,6 +61,10 @@ class BaseLayout extends Component {
|
||||
return this.user && this.rootStore.hasAdminRole;
|
||||
}
|
||||
|
||||
get hasAdminPageRole() {
|
||||
return this.user && this.rootStore.hasAdminPageRole;
|
||||
}
|
||||
|
||||
get originMenu() {
|
||||
if (this.isAdminPage) {
|
||||
return renderAdminMenu(i18n.t);
|
||||
|
@ -71,7 +71,7 @@ const renderMenu = (t) => {
|
||||
level: 2,
|
||||
},
|
||||
{
|
||||
path: /^\/compute\/flavor-admin\/detail\/.[^/]+$/,
|
||||
path: /^\/compute\/flavor-admin\/detail\/[^/]+$/,
|
||||
name: t('Flavor Detail'),
|
||||
key: 'flavor-detail',
|
||||
level: 2,
|
||||
|
@ -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 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.": "Please set CPU && Ram first.",
|
||||
"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 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.": "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 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 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).": "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 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 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.",
|
||||
|
@ -236,7 +236,6 @@
|
||||
"Clear Gateway": "",
|
||||
"Click here for filters.": "筛选",
|
||||
"Click to Upload": "点击上传文件",
|
||||
"Click to see": "点击查看",
|
||||
"Click to show detail": "点击查看详情",
|
||||
"Clone Volume": "克隆云硬盘",
|
||||
"Clone volume": "克隆云硬盘",
|
||||
@ -1159,7 +1158,6 @@
|
||||
"Please select!": "请选择!",
|
||||
"Please set CPU && Ram first.": "请先设置CPU、内存。",
|
||||
"Please set MUNA": "请设置NUMA节点",
|
||||
"Please set expiration time": "请设置到期时间",
|
||||
"Pleasse input a valid ip!": "请输入正确的IP地址",
|
||||
"Pleasse select a network!": "请选择网络!",
|
||||
"Pleasse select a subnet!": "请选择子网!",
|
||||
@ -1509,7 +1507,6 @@
|
||||
"The current operation requires the instance to be shut down:": "当前操作需要云主机在关机状态下进行:",
|
||||
"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 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 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: ": "云主机架构图主要展示云主机的总体架构组成。如果需要查看云主机的网络拓扑,请转到:",
|
||||
@ -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 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 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 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\",才可支持共享盘属性。",
|
||||
|
@ -20,6 +20,7 @@ import { InfoCircleFilled } from '@ant-design/icons';
|
||||
import SimpleForm from 'components/SimpleForm';
|
||||
import globalSkylineStore from 'stores/skyline/skyline';
|
||||
import i18n from 'core/i18n';
|
||||
import { isEmpty } from 'lodash';
|
||||
import styles from './index.less';
|
||||
|
||||
@inject('rootStore')
|
||||
@ -189,13 +190,15 @@ export default class Login extends Component {
|
||||
this.setState({
|
||||
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({
|
||||
loading: false,
|
||||
error: false,
|
||||
});
|
||||
if (globals.user) {
|
||||
if (this.rootStore.user && !isEmpty(this.rootStore.user)) {
|
||||
this.rootStore.routing.push(this.nextPage);
|
||||
}
|
||||
},
|
||||
@ -205,7 +208,7 @@ export default class Login extends Component {
|
||||
});
|
||||
const {
|
||||
data: { detail },
|
||||
} = error;
|
||||
} = error.response;
|
||||
if (
|
||||
detail.indexOf(
|
||||
'The password is expired and needs to be changed for user'
|
||||
@ -240,13 +243,16 @@ export default class Login extends Component {
|
||||
|
||||
getErrorMessage() {
|
||||
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(
|
||||
'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 (
|
||||
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(
|
||||
'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
|
||||
class ResourceStatistic extends Component {
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,7 @@ import { observer, inject } from 'mobx-react';
|
||||
import Base from 'containers/List';
|
||||
import globalIronicStore from 'stores/ironic/ironic';
|
||||
import { powerState, provisioningState } from 'resources/ironic';
|
||||
import { ironicOriginEndpoint } from 'utils/constants';
|
||||
import { ironicOriginEndpoint } from 'client/client/constants';
|
||||
import actionConfigs from './actions';
|
||||
|
||||
@inject('rootStore')
|
||||
|
@ -16,8 +16,6 @@ import { inject, observer } from 'mobx-react';
|
||||
import { HypervisorStore } from 'stores/nova/hypervisor';
|
||||
import Base from 'containers/TabDetail';
|
||||
import Members from 'pages/compute/containers/Instance';
|
||||
import Link from 'react-router-dom/Link';
|
||||
import React from 'react';
|
||||
|
||||
@inject('rootStore')
|
||||
@observer
|
||||
@ -55,15 +53,6 @@ export default class HypervisorDetail extends Base {
|
||||
render: (value, record) =>
|
||||
`${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';
|
||||
}
|
||||
|
||||
get hasAdminRole() {
|
||||
return globals.user.hasAdminRole;
|
||||
}
|
||||
|
||||
get keypairs() {
|
||||
return (this.keyPairStore.list.data || []).map((it) => ({
|
||||
...it,
|
||||
|
@ -22,7 +22,7 @@ import globalProjectStore from 'stores/keystone/project';
|
||||
import classnames from 'classnames';
|
||||
import { isEmpty, isFinite } from 'lodash';
|
||||
import { getUserData, canCreateIronicByLicense } from 'resources/instance';
|
||||
import { ironicOriginEndpoint } from 'utils/constants';
|
||||
import { ironicOriginEndpoint } from 'client/client/constants';
|
||||
import styles from './index.less';
|
||||
import ConfirmStep from './ConfirmStep';
|
||||
import SystemStep from './SystemStep';
|
||||
@ -68,9 +68,8 @@ export default class CreateIronic extends StepAction {
|
||||
}
|
||||
|
||||
async getQuota() {
|
||||
const { project: { id: project_id } = {} } = globals.user || {};
|
||||
await this.projectStore.fetchProjectQuota({
|
||||
project_id,
|
||||
project_id: this.currentProjectId,
|
||||
});
|
||||
this.onCountChange(1);
|
||||
}
|
||||
|
@ -44,10 +44,6 @@ export default class SystemStep extends Base {
|
||||
return 'SystemStep';
|
||||
}
|
||||
|
||||
get hasAdminRole() {
|
||||
return globals.user.hasAdminRole;
|
||||
}
|
||||
|
||||
get keypairs() {
|
||||
return (this.keyPairStore.list.data || []).map((it) => ({
|
||||
...it,
|
||||
|
@ -63,9 +63,8 @@ class StepCreate extends StepAction {
|
||||
}
|
||||
|
||||
async getQuota() {
|
||||
const { project: { id: project_id } = {} } = globals.user || {};
|
||||
await this.projectStore.fetchProjectQuota({
|
||||
project_id,
|
||||
project_id: this.currentProjectId,
|
||||
});
|
||||
this.onCountChange(1);
|
||||
}
|
||||
|
@ -36,26 +36,15 @@ export default class PortForwarding extends Base {
|
||||
return true;
|
||||
}
|
||||
|
||||
updateFetchParamsByPage = (params) => {
|
||||
const { id, ...rest } = params;
|
||||
updateFetchParams = (params) => {
|
||||
const { id, all_projects, ...rest } = params;
|
||||
return {
|
||||
fipID: id,
|
||||
fipInfo: this.props.detail,
|
||||
...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() {
|
||||
return this.isAdminPage
|
||||
? actionConfigs.actionConfigsAdmin
|
||||
|
@ -147,7 +147,11 @@ export default class FloatingIps extends Base {
|
||||
title: t('Associated Resource'),
|
||||
dataIndex: 'resource_name',
|
||||
render: (resource_name, record) => {
|
||||
if (!resource_name && record.port_forwardings.length !== 0) {
|
||||
if (
|
||||
!resource_name &&
|
||||
record.port_forwardings &&
|
||||
record.port_forwardings.length !== 0
|
||||
) {
|
||||
return (
|
||||
<>
|
||||
{t('{number} port forwarding rules', {
|
||||
|
@ -15,7 +15,7 @@
|
||||
import { inject, observer } from 'mobx-react';
|
||||
import Base from 'containers/List';
|
||||
import { LbaasStore } from 'stores/octavia/loadbalancer';
|
||||
import { lbEndpoint } from 'utils/constants';
|
||||
import { lbEndpoint } from 'client/client/constants';
|
||||
import { actionConfigs, adminActions } from './actions';
|
||||
|
||||
@inject('rootStore')
|
||||
|
@ -30,10 +30,6 @@ export default class QoSPolicy extends Base {
|
||||
return 'get_policy';
|
||||
}
|
||||
|
||||
get module() {
|
||||
return 'qos_policies';
|
||||
}
|
||||
|
||||
get name() {
|
||||
return t('QoS policies');
|
||||
}
|
||||
|
@ -35,10 +35,6 @@ export default class QoSPolicy extends Base {
|
||||
return 'get_policy';
|
||||
}
|
||||
|
||||
get module() {
|
||||
return 'qos_policies';
|
||||
}
|
||||
|
||||
get name() {
|
||||
return t('QoS policies');
|
||||
}
|
||||
|
@ -35,10 +35,6 @@ export default class QoSPolicy extends Base {
|
||||
return 'get_policy';
|
||||
}
|
||||
|
||||
get module() {
|
||||
return 'qos_policies';
|
||||
}
|
||||
|
||||
get name() {
|
||||
return t('QoS policies');
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ export default class AssociateFip extends ModalAction {
|
||||
} = this.item;
|
||||
this.floatingIpStore.fetchList({
|
||||
floating_network_id: network_id,
|
||||
project_id: globals.user.project.id,
|
||||
project_id: this.currentProjectId,
|
||||
status: 'DOWN',
|
||||
});
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
|
||||
import { observer, inject } from 'mobx-react';
|
||||
import Base from 'containers/TabList';
|
||||
import { vpnEndpoint } from 'utils/constants';
|
||||
import { vpnEndpoint } from 'client/client/constants';
|
||||
import VPNGateway from './VPNGateway';
|
||||
import EndPointGroup from './EndpointGroup';
|
||||
import IKEPolicy from './IKEPolicy';
|
||||
|
@ -15,6 +15,7 @@
|
||||
import React from 'react';
|
||||
import ImageType from 'components/ImageType';
|
||||
import { get } from 'lodash';
|
||||
import globalRootStore from 'stores/root';
|
||||
|
||||
export const imageStatus = {
|
||||
active: t('Active'),
|
||||
@ -99,21 +100,14 @@ export const imageProperties = {
|
||||
export const transitionStatusList = ['saving', 'queued', 'pending_delete'];
|
||||
|
||||
export const isOwnerOrAdmin = (item) => {
|
||||
const {
|
||||
project: { id },
|
||||
hasAdminRole,
|
||||
} = globals.user;
|
||||
if (id === item.owner) {
|
||||
if (globalRootStore.projectId === item.owner) {
|
||||
return true;
|
||||
}
|
||||
return hasAdminRole;
|
||||
return globalRootStore.hasAdminRole;
|
||||
};
|
||||
|
||||
export const isOwner = (item) => {
|
||||
const {
|
||||
project: { id },
|
||||
} = globals.user;
|
||||
if (id === item.owner) {
|
||||
if (globalRootStore.projectId === item.owner) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -13,10 +13,8 @@
|
||||
// limitations under the License.
|
||||
|
||||
import React from 'react';
|
||||
import moment from 'moment';
|
||||
import ImageType from 'components/ImageType';
|
||||
import globalRootStore from 'stores/root';
|
||||
import { getLocalTimeStr, timeFormatStr } from 'utils/time';
|
||||
|
||||
import lockSvg from 'src/asset/image/lock.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);
|
||||
};
|
||||
|
||||
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) => {
|
||||
if (!subnet) {
|
||||
return null;
|
||||
|
@ -95,3 +95,5 @@ export const getAnchorData = (num, y) => {
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
export const isExternalNetwork = (network) => !!network['router:external'];
|
||||
|
@ -13,12 +13,13 @@
|
||||
// limitations under the License.
|
||||
|
||||
import { isArray, isObject, isFunction, isString, has } from 'lodash';
|
||||
import globalRootStore from 'stores/root';
|
||||
|
||||
export const checkPolicyRule = (rule, actionName) => {
|
||||
if (!rule) {
|
||||
return true;
|
||||
}
|
||||
const item = globals.policies.find((it) => it.rule === rule);
|
||||
const item = globalRootStore.policies.find((it) => it.rule === rule);
|
||||
if (!item) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('policy rule not exit', rule, actionName);
|
||||
@ -37,7 +38,7 @@ const checkPolicyRules = (rules, every, actionName) => {
|
||||
};
|
||||
|
||||
export const systemRoleIsReader = () => {
|
||||
const { user: { roles = [] } = {} } = globals || {};
|
||||
const { roles = [] } = globalRootStore.user || {};
|
||||
const readerRole = 'system_reader';
|
||||
const adminRoles = ['system_admin', 'admin'];
|
||||
const hasReaderRole = roles.some((it) => it.name === readerRole);
|
||||
@ -55,9 +56,11 @@ const checkItemPolicy = ({
|
||||
isAdminPage,
|
||||
enableSystemReader,
|
||||
}) => {
|
||||
if (globals.policies.length === 0) {
|
||||
// TODO: change to false
|
||||
return true;
|
||||
if (globalRootStore.policies.length === 0) {
|
||||
return false;
|
||||
}
|
||||
if (isAdminPage && !enableSystemReader && systemRoleIsReader()) {
|
||||
return false;
|
||||
}
|
||||
if (isAdminPage && !enableSystemReader && systemRoleIsReader()) {
|
||||
return false;
|
||||
|
@ -12,11 +12,12 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { get, isArray } from 'lodash';
|
||||
import { get } from 'lodash';
|
||||
import { action, observable } from 'mobx';
|
||||
import { keystoneBase } from 'utils/constants';
|
||||
import client from 'client';
|
||||
import List from './base-list';
|
||||
import globalProjectMapStore from './project';
|
||||
import globalRootStore from './root';
|
||||
|
||||
export default class BaseStore {
|
||||
list = new List();
|
||||
@ -30,16 +31,16 @@ export default class BaseStore {
|
||||
@observable
|
||||
isSubmitting = false;
|
||||
|
||||
get module() {
|
||||
return '';
|
||||
get client() {
|
||||
return {};
|
||||
}
|
||||
|
||||
get apiVersion() {
|
||||
return '';
|
||||
get skylineClient() {
|
||||
return client.skyline;
|
||||
}
|
||||
|
||||
get responseKey() {
|
||||
return '';
|
||||
return this.client.responseKey;
|
||||
}
|
||||
|
||||
get listResponseKey() {
|
||||
@ -50,6 +51,22 @@ export default class BaseStore {
|
||||
return true;
|
||||
}
|
||||
|
||||
get currentUser() {
|
||||
return globalRootStore.user || {};
|
||||
}
|
||||
|
||||
get currentProjectId() {
|
||||
return globalRootStore.projectId;
|
||||
}
|
||||
|
||||
get hasAdminRole() {
|
||||
return globalRootStore.hasAdminRole;
|
||||
}
|
||||
|
||||
get enableBilling() {
|
||||
return globalRootStore.enableBilling;
|
||||
}
|
||||
|
||||
get mapper() {
|
||||
// update response items;
|
||||
return (data) => data;
|
||||
@ -112,7 +129,7 @@ export default class BaseStore {
|
||||
|
||||
get paramsFuncPage() {
|
||||
return (params) => {
|
||||
const { current, ...rest } = params;
|
||||
const { current, withPrice, ...rest } = params;
|
||||
return rest;
|
||||
};
|
||||
}
|
||||
@ -126,14 +143,39 @@ export default class BaseStore {
|
||||
return false;
|
||||
}
|
||||
|
||||
get currentProject() {
|
||||
return globals.user.project.id;
|
||||
}
|
||||
|
||||
get markerKey() {
|
||||
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) {
|
||||
return (
|
||||
item.project_id ||
|
||||
@ -153,21 +195,13 @@ export default class BaseStore {
|
||||
const itemProject = globalProjectMapStore.getItemProjectId(item);
|
||||
const { shared, visibility, is_public } = item;
|
||||
return (
|
||||
itemProject === this.currentProject ||
|
||||
itemProject === this.currentProjectId ||
|
||||
is_public ||
|
||||
shared ||
|
||||
visibility === 'public'
|
||||
);
|
||||
};
|
||||
|
||||
getListUrl = () => `${this.apiVersion}/${this.module}`;
|
||||
|
||||
getListDetailUrl = () => '';
|
||||
|
||||
getListPageUrl = () => '';
|
||||
|
||||
getDetailUrl = ({ id }) => `${this.getListUrl()}/${id}`;
|
||||
|
||||
@action
|
||||
setModule(module) {
|
||||
this.module = module;
|
||||
@ -188,12 +222,6 @@ export default class BaseStore {
|
||||
return promise;
|
||||
};
|
||||
|
||||
async fetchProjectDetail({ id }) {
|
||||
return request.get(`${keystoneBase()}/projects/${id}`, {}, null, () =>
|
||||
Promise.resolve('error')
|
||||
);
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
async listDidFetch(items, allProjects, filters) {
|
||||
return items;
|
||||
@ -208,7 +236,7 @@ export default class BaseStore {
|
||||
if (!this.needGetProject) {
|
||||
return items;
|
||||
}
|
||||
if (!all_projects || !globals.user.hasAdminRole) {
|
||||
if (!all_projects || !this.hasAdminRole) {
|
||||
return items;
|
||||
}
|
||||
const projectIds = [];
|
||||
@ -240,28 +268,33 @@ export default class BaseStore {
|
||||
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 = {
|
||||
...params,
|
||||
limit,
|
||||
...markerParams,
|
||||
};
|
||||
if (marker) {
|
||||
newParams.marker = marker;
|
||||
}
|
||||
return request.get(url, newParams);
|
||||
return this.listFetchByClient(newParams);
|
||||
}
|
||||
|
||||
async requestListAllByLimit(url, params, limit) {
|
||||
async requestListAllByLimit(params, limit) {
|
||||
let marker = '';
|
||||
let hasNext = true;
|
||||
let datas = [];
|
||||
while (hasNext) {
|
||||
// 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);
|
||||
datas = [...datas, ...data];
|
||||
if (data.length >= limit) {
|
||||
marker = this.parseMarker(data);
|
||||
marker = this.parseMarker(data, result, datas);
|
||||
if (!marker) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('parse marker error!');
|
||||
@ -274,21 +307,21 @@ export default class BaseStore {
|
||||
return datas;
|
||||
}
|
||||
|
||||
async requestListAll(url, params) {
|
||||
const result = await request.get(url, params);
|
||||
async requestListAll(params, originParams) {
|
||||
const result = await this.listFetchByClient(params, originParams);
|
||||
return this.getListDataFromResult(result);
|
||||
}
|
||||
|
||||
async requestList(url, params) {
|
||||
async requestList(params, originParams) {
|
||||
const datas = !this.fetchListByLimit
|
||||
? await this.requestListAll(url, params)
|
||||
: await this.requestListAllByLimit(url, params, 100);
|
||||
? await this.requestListAll(params, originParams)
|
||||
: await this.requestListAllByLimit(params, 100);
|
||||
return datas;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
async requestListByPage(url, params, page, filters) {
|
||||
const datas = await request.get(url, params);
|
||||
async requestListByPage(params, page, originParams) {
|
||||
const datas = await this.listFetchByClient(params, originParams);
|
||||
return datas;
|
||||
}
|
||||
|
||||
@ -319,19 +352,7 @@ export default class BaseStore {
|
||||
params.all_projects = true;
|
||||
}
|
||||
}
|
||||
let url = `${this.getListDetailUrl() || this.getListUrl()}?`;
|
||||
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);
|
||||
const allData = await this.requestList(params, {});
|
||||
return allData;
|
||||
}
|
||||
|
||||
@ -355,9 +376,7 @@ export default class BaseStore {
|
||||
}
|
||||
}
|
||||
const newParams = this.paramsFunc(params);
|
||||
const url = this.getListDetailUrl(filters) || this.getListUrl(filters);
|
||||
const newUrl = this.updateUrl(url, params);
|
||||
const allData = await this.requestList(newUrl, newParams, filters);
|
||||
const allData = await this.requestList(newParams, filters);
|
||||
const allDataNew = allData.map((it) =>
|
||||
this.mapperBeforeFetchProject(it, filters)
|
||||
);
|
||||
@ -393,15 +412,15 @@ export default class BaseStore {
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
parseMarker(datas, result) {
|
||||
parseMarker(datas, result, allDatas) {
|
||||
return datas.length === 0
|
||||
? ''
|
||||
: get(datas[datas.length - 1], this.markerKey);
|
||||
}
|
||||
|
||||
@action
|
||||
updateMarker(datas, page, result) {
|
||||
const marker = this.parseMarker(datas, result);
|
||||
updateMarker(datas, page, result, allDatas) {
|
||||
const marker = this.parseMarker(datas, result, allDatas);
|
||||
if (page === 1) {
|
||||
this.list.markers = [marker];
|
||||
} else {
|
||||
@ -423,6 +442,9 @@ export default class BaseStore {
|
||||
return {};
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
getOtherInfo = (result) => {};
|
||||
|
||||
@action
|
||||
async fetchListByPage({
|
||||
limit = 10,
|
||||
@ -448,20 +470,10 @@ export default class BaseStore {
|
||||
if (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 result = await this.requestListByPage(
|
||||
newUrl,
|
||||
newParams,
|
||||
page,
|
||||
filters
|
||||
);
|
||||
const result = await this.requestListByPage(newParams, page, filters);
|
||||
const allData = this.getListDataFromResult(result);
|
||||
this.updateMarker(allData, page, result);
|
||||
this.updateMarker(allData, page, result, allData);
|
||||
const allDataNew = allData.map(this.mapperBeforeFetchProject);
|
||||
let newData = await this.listDidFetchProject(allDataNew, all_projects);
|
||||
newData = await this.listDidFetch(newData, all_projects, filters);
|
||||
@ -482,6 +494,7 @@ export default class BaseStore {
|
||||
count = retCount;
|
||||
total = retTotal;
|
||||
}
|
||||
const others = this.getOtherInfo(result);
|
||||
this.list.update({
|
||||
data: newData,
|
||||
limit: Number(limit) || 10,
|
||||
@ -493,54 +506,7 @@ export default class BaseStore {
|
||||
isLoading: false,
|
||||
total: count || total,
|
||||
...(this.list.silent ? {} : { selectedRowKeys: [] }),
|
||||
});
|
||||
|
||||
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: [] }),
|
||||
...others,
|
||||
});
|
||||
|
||||
return newData;
|
||||
@ -551,8 +517,8 @@ export default class BaseStore {
|
||||
if (!silent) {
|
||||
this.isLoading = true;
|
||||
}
|
||||
const result = await request.get(
|
||||
this.getDetailUrl(rest),
|
||||
const result = await this.detailFetchByClient(
|
||||
rest,
|
||||
this.getDetailParams({ all_projects })
|
||||
);
|
||||
const originData = get(result, this.responseKey) || result;
|
||||
@ -579,37 +545,30 @@ export default class BaseStore {
|
||||
create(data) {
|
||||
const body = {};
|
||||
body[this.responseKey] = data;
|
||||
return this.submitting(request.post(this.getListUrl(), body));
|
||||
}
|
||||
|
||||
@action
|
||||
update({ id }, newObject, sleepTime) {
|
||||
return this.submitting(
|
||||
request.post(
|
||||
`${this.getDetailUrl({ id })}/action`,
|
||||
newObject,
|
||||
null,
|
||||
null,
|
||||
sleepTime
|
||||
)
|
||||
);
|
||||
return this.submitting(this.client.create(body));
|
||||
}
|
||||
|
||||
@action
|
||||
edit({ id }, newObject) {
|
||||
const body = {};
|
||||
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
|
||||
patch({ id }, newObject) {
|
||||
return this.submitting(request.patch(this.getDetailUrl({ id }), newObject));
|
||||
return this.submitting(this.client.patch(id, newObject));
|
||||
}
|
||||
|
||||
@action
|
||||
delete = ({ id }) =>
|
||||
this.submitting(request.delete(this.getDetailUrl({ id })));
|
||||
delete = ({ id }) => this.submitting(this.client.delete(id));
|
||||
|
||||
@action
|
||||
batchDelete(rowKeys) {
|
||||
@ -617,17 +576,13 @@ export default class BaseStore {
|
||||
Promise.all(
|
||||
rowKeys.map((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
|
||||
clearData() {
|
||||
this.list.reset();
|
||||
|
@ -13,28 +13,19 @@
|
||||
// limitations under the License.
|
||||
|
||||
import { action } from 'mobx';
|
||||
import { cinderBase } from 'utils/constants';
|
||||
import client from 'client';
|
||||
import Base from '../base';
|
||||
import { VolumeStore } from './volume';
|
||||
|
||||
export class BackupStore extends Base {
|
||||
get module() {
|
||||
if (!globals.user) {
|
||||
return null;
|
||||
}
|
||||
return `${globals.user.project.id}/backups`;
|
||||
get client() {
|
||||
return client.cinder.backups;
|
||||
}
|
||||
|
||||
get apiVersion() {
|
||||
return cinderBase();
|
||||
get listWithDetail() {
|
||||
return true;
|
||||
}
|
||||
|
||||
get responseKey() {
|
||||
return 'backup';
|
||||
}
|
||||
|
||||
getListDetailUrl = () => `${this.apiVersion}/${this.module}/detail`;
|
||||
|
||||
updateParamsSortPage = (params, sortKey, sortOrder) => {
|
||||
if (sortKey && sortOrder) {
|
||||
params.sort = `${sortKey}:${sortOrder === 'descend' ? 'desc' : 'asc'}`;
|
||||
@ -65,9 +56,7 @@ export class BackupStore extends Base {
|
||||
@action
|
||||
restore(id, data) {
|
||||
const body = { restore: data || {} };
|
||||
return this.submitting(
|
||||
request.post(`${this.getDetailUrl({ id })}/restore`, body)
|
||||
);
|
||||
return this.submitting(this.client.restore(id, body));
|
||||
}
|
||||
}
|
||||
const globalBackupStore = new BackupStore();
|
||||
|
@ -13,43 +13,21 @@
|
||||
// limitations under the License.
|
||||
|
||||
import { action } from 'mobx';
|
||||
import { cinderBase } from 'utils/constants';
|
||||
import client from 'client';
|
||||
import Base from '../base';
|
||||
|
||||
export class ExtraSpecStore extends Base {
|
||||
get module() {
|
||||
if (!globals.user) {
|
||||
return null;
|
||||
}
|
||||
return `${globals.user.project.id}/types`;
|
||||
get client() {
|
||||
return client.cinder.types.extraSpecs;
|
||||
}
|
||||
|
||||
get apiVersion() {
|
||||
return cinderBase();
|
||||
get isSubResource() {
|
||||
return true;
|
||||
}
|
||||
|
||||
get responseKey() {
|
||||
return 'extra_spec';
|
||||
}
|
||||
getFatherResourceId = (params) => params.id;
|
||||
|
||||
getExtraSpecsUrl = ({ id }) =>
|
||||
`${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);
|
||||
getListDataFromResult = (result) => {
|
||||
const { extra_specs } = result;
|
||||
const data = [];
|
||||
Object.keys(extra_specs).forEach((key) => {
|
||||
@ -60,36 +38,20 @@ export class ExtraSpecStore extends Base {
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
@action
|
||||
createOrUpdate(id, data) {
|
||||
const body = {
|
||||
extra_specs: data,
|
||||
};
|
||||
return this.submitting(request.post(this.getExtraSpecsUrl({ id }), body));
|
||||
return this.submitting(this.client.create(id, body));
|
||||
}
|
||||
|
||||
@action
|
||||
delete = ({ id, keyname }) => {
|
||||
return this.submitting(
|
||||
request.delete(`${this.getExtraSpecsUrl({ id })}/${keyname}`)
|
||||
);
|
||||
return this.submitting(this.client.delete(id, keyname));
|
||||
};
|
||||
}
|
||||
const globalExtraSpecStore = new ExtraSpecStore();
|
||||
|
@ -12,27 +12,26 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { cinderBase } from 'utils/constants';
|
||||
import { isNumber } from 'lodash';
|
||||
import client from 'client';
|
||||
import Base from '../base';
|
||||
|
||||
export class PoolStore extends Base {
|
||||
get module() {
|
||||
return 'scheduler-stats/get_pools';
|
||||
}
|
||||
|
||||
get apiVersion() {
|
||||
return cinderBase();
|
||||
}
|
||||
|
||||
get responseKey() {
|
||||
return 'pool';
|
||||
get client() {
|
||||
return client.cinder.pools;
|
||||
}
|
||||
|
||||
get listFilterByProject() {
|
||||
return false;
|
||||
}
|
||||
|
||||
get paramsFunc() {
|
||||
return (params) => ({
|
||||
...params,
|
||||
detail: true,
|
||||
});
|
||||
}
|
||||
|
||||
get mapper() {
|
||||
return (data) => {
|
||||
const { name, capabilities = {} } = data;
|
||||
@ -46,9 +45,6 @@ export class PoolStore extends Base {
|
||||
return newItem;
|
||||
};
|
||||
}
|
||||
|
||||
getListUrl = () =>
|
||||
`${this.apiVersion}/${globals.user.project.id}/${this.module}?detail=true`;
|
||||
}
|
||||
|
||||
const globalPoolStore = new PoolStore();
|
||||
|
@ -13,42 +13,20 @@
|
||||
// limitations under the License.
|
||||
|
||||
import { action } from 'mobx';
|
||||
import { cinderBase } from 'utils/constants';
|
||||
import client from 'client';
|
||||
import Base from '../base';
|
||||
|
||||
export class QosSpecKeyStore extends Base {
|
||||
get module() {
|
||||
if (!globals.user) {
|
||||
return null;
|
||||
}
|
||||
return `${globals.user.project.id}/qos-specs`;
|
||||
get client() {
|
||||
return client.cinder.qosSpecs;
|
||||
}
|
||||
|
||||
get apiVersion() {
|
||||
return cinderBase();
|
||||
listFetchByClient(params) {
|
||||
const { id } = params;
|
||||
return this.client.show(id);
|
||||
}
|
||||
|
||||
get responseKey() {
|
||||
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);
|
||||
getListDataFromResult = (result) => {
|
||||
const { specs = {} } = result.qos_specs || {};
|
||||
const data = [];
|
||||
Object.keys(specs).forEach((key) => {
|
||||
@ -59,35 +37,21 @@ export class QosSpecKeyStore extends Base {
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
@action
|
||||
createOrUpdate(id, data) {
|
||||
const body = {};
|
||||
body[this.responseKey] = data;
|
||||
return this.submitting(request.put(this.getListUrl({ id }), body));
|
||||
body.qos_specs = data;
|
||||
return this.submitting(this.client.update(id, body));
|
||||
}
|
||||
|
||||
// TODO
|
||||
@action
|
||||
delete = ({ id, keyname }) =>
|
||||
this.submitting(
|
||||
request.put(`${this.getListUrl({ id })}/delete_keys`, {
|
||||
this.client.deleteKeys(id, {
|
||||
keys: [keyname],
|
||||
})
|
||||
);
|
||||
|
@ -13,25 +13,12 @@
|
||||
// limitations under the License.
|
||||
|
||||
import { action } from 'mobx';
|
||||
import { cinderBase } from 'utils/constants';
|
||||
import client from 'client';
|
||||
import Base from '../base';
|
||||
|
||||
const qs = require('qs');
|
||||
|
||||
export class QosSpecStore extends Base {
|
||||
get module() {
|
||||
if (!globals.user) {
|
||||
return null;
|
||||
}
|
||||
return `${globals.user.project.id}/qos-specs`;
|
||||
}
|
||||
|
||||
get apiVersion() {
|
||||
return cinderBase();
|
||||
}
|
||||
|
||||
get responseKey() {
|
||||
return 'qos_spec';
|
||||
get client() {
|
||||
return client.cinder.qosSpecs;
|
||||
}
|
||||
|
||||
@action
|
||||
@ -39,13 +26,13 @@ export class QosSpecStore extends Base {
|
||||
const body = {};
|
||||
const { values } = data;
|
||||
body[`${this.responseKey}s`] = values;
|
||||
return this.submitting(request.post(this.getListUrl(), body));
|
||||
return this.submitting(this.client.create(body));
|
||||
}
|
||||
|
||||
@action
|
||||
editConsumer({ id, consumer }) {
|
||||
return this.submitting(
|
||||
request.put(this.getDetailUrl({ id }), {
|
||||
this.client.update(id, {
|
||||
qos_specs: {
|
||||
consumer,
|
||||
},
|
||||
@ -66,18 +53,12 @@ export class QosSpecStore extends Base {
|
||||
|
||||
@action
|
||||
associate(id, data) {
|
||||
const query = qs.stringify(data);
|
||||
return this.submitting(
|
||||
request.get(`${this.getDetailUrl({ id })}/associate?${query}`)
|
||||
);
|
||||
return this.submitting(this.client.associate(id, data));
|
||||
}
|
||||
|
||||
@action
|
||||
disassociate(id, data) {
|
||||
const query = qs.stringify(data);
|
||||
return this.submitting(
|
||||
request.get(`${this.getDetailUrl({ id })}/disassociate?${query}`)
|
||||
);
|
||||
return this.submitting(this.client.disassociate(id, data));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,40 +12,23 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { cinderBase } from 'utils/constants';
|
||||
import { action } from 'mobx';
|
||||
import client from 'client';
|
||||
import Base from '../base';
|
||||
|
||||
export class ServiceStore extends Base {
|
||||
get module() {
|
||||
return 'os-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));
|
||||
get client() {
|
||||
return client.cinder.services;
|
||||
}
|
||||
|
||||
@action
|
||||
enable(body) {
|
||||
return this.operate('enable', body);
|
||||
return this.submitting(this.client.enable(body));
|
||||
}
|
||||
|
||||
@action
|
||||
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
|
||||
// limitations under the License.
|
||||
|
||||
import { action, observable } from 'mobx';
|
||||
import { cinderBase, skylineBase } from 'utils/constants';
|
||||
import { action } from 'mobx';
|
||||
import client from 'client';
|
||||
import Base from '../base';
|
||||
|
||||
export class SnapshotStore extends Base {
|
||||
@observable
|
||||
allSnapshotList = [];
|
||||
|
||||
get module() {
|
||||
if (!globals.user) {
|
||||
return null;
|
||||
}
|
||||
return `${globals.user.project.id}/snapshots`;
|
||||
}
|
||||
|
||||
get apiVersion() {
|
||||
return cinderBase();
|
||||
}
|
||||
|
||||
get responseKey() {
|
||||
return 'snapshot';
|
||||
get client() {
|
||||
return client.cinder.snapshots;
|
||||
}
|
||||
|
||||
get listResponseKey() {
|
||||
return 'volume_snapshots';
|
||||
}
|
||||
|
||||
listFetchByClient(params) {
|
||||
return this.skylineClient.extension.volumeSnapshots(params);
|
||||
}
|
||||
|
||||
get paramsFunc() {
|
||||
return (params) => {
|
||||
const { id, ...rest } = params;
|
||||
const { id, withPrice, ...rest } = params;
|
||||
return rest;
|
||||
};
|
||||
}
|
||||
|
||||
getListPageUrl = () => `${skylineBase()}/extension/volume_snapshots`;
|
||||
|
||||
getListDetailUrl = () => `${skylineBase()}/extension/volume_snapshots`;
|
||||
|
||||
async listDidFetch(items, allProjects, filters) {
|
||||
if (items.length === 0) {
|
||||
return items;
|
||||
@ -61,10 +47,7 @@ export class SnapshotStore extends Base {
|
||||
|
||||
async detailDidFetch(item) {
|
||||
const { volume_id } = item;
|
||||
const volumeUrl = `${cinderBase()}/${
|
||||
globals.user.project.id
|
||||
}/volumes/${volume_id}`;
|
||||
const { volume } = await request.get(volumeUrl);
|
||||
const { volume } = await client.cinder.volumes.show(volume_id);
|
||||
item.volume = volume;
|
||||
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
|
||||
update(id, 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();
|
||||
|
@ -13,26 +13,19 @@
|
||||
// limitations under the License.
|
||||
|
||||
import { action, observable } from 'mobx';
|
||||
import { cinderBase } from 'utils/constants';
|
||||
import client from 'client';
|
||||
import { uniq } from 'lodash';
|
||||
import Base from '../base';
|
||||
|
||||
export class VolumeTypeStore extends Base {
|
||||
@observable
|
||||
access = [];
|
||||
|
||||
get module() {
|
||||
if (!globals.user) {
|
||||
return null;
|
||||
}
|
||||
return `${globals.user.project.id}/types`;
|
||||
}
|
||||
@observable
|
||||
projectVolumeTypes = [];
|
||||
|
||||
get apiVersion() {
|
||||
return cinderBase();
|
||||
}
|
||||
|
||||
get responseKey() {
|
||||
return 'volume_type';
|
||||
get client() {
|
||||
return client.cinder.types;
|
||||
}
|
||||
|
||||
get listFilterByProject() {
|
||||
@ -41,32 +34,58 @@ export class VolumeTypeStore extends Base {
|
||||
|
||||
get paramsFuncPage() {
|
||||
return (params) => {
|
||||
const { current, showEncryption, ...rest } = params;
|
||||
const {
|
||||
current,
|
||||
showEncryption,
|
||||
showQoS,
|
||||
withPrice,
|
||||
resourceType,
|
||||
...rest
|
||||
} = params;
|
||||
return rest;
|
||||
};
|
||||
}
|
||||
|
||||
get paramsFunc() {
|
||||
return this.paramsFuncPage;
|
||||
}
|
||||
|
||||
get mapper() {
|
||||
return (data) => {
|
||||
const { extra_specs: { multiattach = 'False' } = {} } = data;
|
||||
return {
|
||||
...data,
|
||||
multiattach: multiattach === '<is> True',
|
||||
enableBilling: this.enableBilling,
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
async listDidFetch(items, allProjects, filters) {
|
||||
const { showEncryption } = filters;
|
||||
const { showEncryption, showQoS } = filters;
|
||||
if (items.length === 0) {
|
||||
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) {
|
||||
return items;
|
||||
}
|
||||
const promiseList = items.map((i) =>
|
||||
request.get(`${this.getDetailUrl({ id: i.id })}/encryption`)
|
||||
);
|
||||
const promiseList = items.map((i) => this.client.encryption.list(i.id));
|
||||
const encryptionList = await Promise.all(promiseList);
|
||||
const result = items.map((i) => {
|
||||
const { id } = i;
|
||||
@ -81,7 +100,7 @@ export class VolumeTypeStore extends Base {
|
||||
|
||||
async detailDidFetch(item) {
|
||||
const { id } = item || {};
|
||||
const result = await request.get(`${this.getDetailUrl({ id })}/encryption`);
|
||||
const result = await this.client.encryption.list(id);
|
||||
item.encryption = result;
|
||||
return item;
|
||||
}
|
||||
@ -90,7 +109,7 @@ export class VolumeTypeStore extends Base {
|
||||
update(id, data) {
|
||||
const body = {};
|
||||
body[this.responseKey] = data;
|
||||
return this.submitting(request.put(this.getDetailUrl({ id }), body));
|
||||
return this.submitting(this.client.update(id, body));
|
||||
}
|
||||
|
||||
@action
|
||||
@ -98,16 +117,12 @@ export class VolumeTypeStore extends Base {
|
||||
const body = {
|
||||
encryption: data,
|
||||
};
|
||||
return this.submitting(
|
||||
request.post(`${this.getDetailUrl({ id })}/encryption`, body)
|
||||
);
|
||||
return this.submitting(this.client.encryption.create(id, body));
|
||||
}
|
||||
|
||||
@action
|
||||
deleteEncryption(id, encryption_id) {
|
||||
return this.submitting(
|
||||
request.delete(`${this.getDetailUrl({ id })}/encryption/${encryption_id}`)
|
||||
);
|
||||
return this.submitting(this.client.encryption.delete(id, encryption_id));
|
||||
}
|
||||
|
||||
@action
|
||||
@ -115,17 +130,16 @@ export class VolumeTypeStore extends Base {
|
||||
const body = {};
|
||||
body[this.responseKey] = data;
|
||||
if (projectIds.length === 0) {
|
||||
return this.submitting(request.post(this.getListUrl(), body));
|
||||
return this.submitting(this.client.create(body));
|
||||
}
|
||||
this.isSubmitting = true;
|
||||
const result = await request.post(this.getListUrl(), body);
|
||||
const result = await this.client.create(body);
|
||||
const { id } = result[this.responseKey];
|
||||
return this.addProjectAccess(id, projectIds);
|
||||
}
|
||||
|
||||
@action
|
||||
addProjectAccess(id, projectIds = []) {
|
||||
const actionUrl = `${this.getDetailUrl({ id })}/action`;
|
||||
return this.submitting(
|
||||
Promise.all(
|
||||
projectIds.map((it) => {
|
||||
@ -134,7 +148,7 @@ export class VolumeTypeStore extends Base {
|
||||
project: it,
|
||||
},
|
||||
};
|
||||
return request.post(actionUrl, actionBody);
|
||||
return this.client.action(id, actionBody);
|
||||
})
|
||||
)
|
||||
);
|
||||
@ -142,7 +156,6 @@ export class VolumeTypeStore extends Base {
|
||||
|
||||
@action
|
||||
removeProjectAccess(id, projectIds = []) {
|
||||
const actionUrl = `${this.getDetailUrl({ id })}/action`;
|
||||
return this.submitting(
|
||||
Promise.all(
|
||||
projectIds.map((it) => {
|
||||
@ -151,7 +164,7 @@ export class VolumeTypeStore extends Base {
|
||||
project: it,
|
||||
},
|
||||
};
|
||||
return request.post(actionUrl, actionBody);
|
||||
return this.client.action(id, actionBody);
|
||||
})
|
||||
)
|
||||
);
|
||||
@ -159,8 +172,7 @@ export class VolumeTypeStore extends Base {
|
||||
|
||||
@action
|
||||
async fetchProjectAccess(id) {
|
||||
const url = `${this.getDetailUrl({ id })}/os-volume-type-access`;
|
||||
const result = await request.get(url);
|
||||
const result = await this.client.getAccess(id);
|
||||
this.access = result.volume_type_access;
|
||||
}
|
||||
|
||||
@ -176,6 +188,30 @@ export class VolumeTypeStore extends Base {
|
||||
await this.removeProjectAccess(id, dels);
|
||||
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();
|
||||
export default globalVolumeTypeStore;
|
||||
|
@ -13,8 +13,9 @@
|
||||
// limitations under the License.
|
||||
|
||||
import { action, observable } from 'mobx';
|
||||
import { cinderBase, skylineBase } from 'utils/constants';
|
||||
import { isOsDisk } from 'resources/volume';
|
||||
import { renderFilterMap } from 'utils/index';
|
||||
import client from 'client';
|
||||
import Base from '../base';
|
||||
import globalVolumeTypeStore from './volume-type';
|
||||
|
||||
@ -31,32 +32,32 @@ export class VolumeStore extends Base {
|
||||
@observable
|
||||
quotaSet = {};
|
||||
|
||||
get module() {
|
||||
if (!globals.user) {
|
||||
return null;
|
||||
get client() {
|
||||
return client.cinder.volumes;
|
||||
}
|
||||
|
||||
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() {
|
||||
return (volume) => ({
|
||||
...volume,
|
||||
disk_tag: isOsDisk(volume) ? 'os_disk' : 'data_disk',
|
||||
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) => {
|
||||
const { recycle } = params;
|
||||
if (sortKey && sortOrder) {
|
||||
params.sort_keys = sortKey;
|
||||
params.sort_dirs = sortOrder === 'descend' ? 'desc' : 'asc';
|
||||
const 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) {
|
||||
const { withPrice } = filters;
|
||||
if (items.length === 0) {
|
||||
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;
|
||||
return !serverId
|
||||
? items
|
||||
@ -88,54 +105,41 @@ export class VolumeStore extends Base {
|
||||
);
|
||||
}
|
||||
|
||||
async detailDidFetch(item, all_projects) {
|
||||
async detailDidFetch(item, all_projects, { withPrice }) {
|
||||
const { id } = item;
|
||||
try {
|
||||
const result = await this.fetchList({ uuid: id, all_projects });
|
||||
item.itemInList = result[0];
|
||||
item.attachmentsContrib = result[0].attachments;
|
||||
} 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;
|
||||
}
|
||||
|
||||
@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
|
||||
async fetchQuota() {
|
||||
const url = `${this.apiVersion}/${this.currentProject}/os-quota-sets/${this.currentProject}?usage=True`;
|
||||
const result = await request.get(url);
|
||||
const result = await client.cinder.quotaSets.show(this.currentProjectId, {
|
||||
usage: 'True',
|
||||
});
|
||||
this.quotaSet = result.quota_set;
|
||||
}
|
||||
|
||||
@action
|
||||
async fetchAvailabilityZoneList() {
|
||||
const url = `${this.apiVersion}/${globals.user.project.id}/os-availability-zone`;
|
||||
const result = await request.get(url);
|
||||
const result = await client.cinder.azones.list();
|
||||
this.availabilityZones = result.availabilityZoneInfo;
|
||||
}
|
||||
|
||||
@action
|
||||
async operation(id, data, key) {
|
||||
const body = { [key]: data };
|
||||
return this.submitting(
|
||||
request.post(`${this.getDetailUrl({ id })}/action`, body)
|
||||
);
|
||||
return this.submitting(this.client.action(id, body));
|
||||
}
|
||||
|
||||
@action
|
||||
@ -150,7 +154,7 @@ export class VolumeStore extends Base {
|
||||
|
||||
@action
|
||||
revert(id, data) {
|
||||
return this.operation(id, data, 'revert');
|
||||
return this.operation(id, data, 'revert_any');
|
||||
}
|
||||
|
||||
@action
|
||||
@ -171,45 +175,36 @@ export class VolumeStore extends Base {
|
||||
@action
|
||||
update(id, 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
|
||||
createTransfer(data) {
|
||||
const body = { transfer: data };
|
||||
return this.submitting(
|
||||
request.post(
|
||||
`${this.apiVersion}/${globals.user.project.id}/volume-transfers`,
|
||||
body
|
||||
)
|
||||
);
|
||||
return this.submitting(this.transferClient.create(body));
|
||||
}
|
||||
|
||||
@action
|
||||
cancelTransfer({ id }) {
|
||||
return this.submitting(
|
||||
request.get(
|
||||
`${this.apiVersion}/${globals.user.project.id}/volume-transfers`
|
||||
)
|
||||
).then((resData) => {
|
||||
return this.submitting(this.transferClient.list()).then((resData) => {
|
||||
const findObj = (resData.transfers || []).find((s) => s.volume_id === id);
|
||||
return this.submitting(
|
||||
request.delete(
|
||||
`${this.apiVersion}/${globals.user.project.id}/volume-transfers/${findObj.id}`
|
||||
)
|
||||
);
|
||||
return this.submitting(this.transferClient.delete(findObj.id));
|
||||
});
|
||||
}
|
||||
|
||||
@action
|
||||
acceptVolumeTransfer(transfer_id, data) {
|
||||
const body = { accept: data };
|
||||
return this.submitting(
|
||||
request.post(
|
||||
`${this.apiVersion}/${globals.user.project.id}/volume-transfers/${transfer_id}/accept`,
|
||||
body
|
||||
)
|
||||
);
|
||||
return this.submitting(this.transferClient.accept(transfer_id, body));
|
||||
}
|
||||
|
||||
@action
|
||||
@ -225,3 +220,5 @@ export class VolumeStore extends Base {
|
||||
|
||||
const globalVolumeStore = new VolumeStore();
|
||||
export default globalVolumeStore;
|
||||
|
||||
export const globalRecycleVolumeStore = new VolumeStore();
|
||||
|
@ -12,32 +12,18 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { glanceBase } from 'utils/constants';
|
||||
import { action, observable } from 'mobx';
|
||||
import client from 'client';
|
||||
import Base from '../base';
|
||||
// import { getArrayBuffer } from 'utils/file';
|
||||
|
||||
export class ImageStore extends Base {
|
||||
@observable
|
||||
members = [];
|
||||
|
||||
get module() {
|
||||
return 'images';
|
||||
get client() {
|
||||
return client.glance.images;
|
||||
}
|
||||
|
||||
get apiVersion() {
|
||||
return glanceBase();
|
||||
}
|
||||
|
||||
get responseKey() {
|
||||
return 'image';
|
||||
}
|
||||
|
||||
// get listFilterByProject() {
|
||||
// // use it for nuetron apois
|
||||
// return true;
|
||||
// }
|
||||
|
||||
get fetchListByLimit() {
|
||||
return true;
|
||||
}
|
||||
@ -46,9 +32,16 @@ export class ImageStore extends Base {
|
||||
return this.paramsFuncPage;
|
||||
}
|
||||
|
||||
updateParamsSortPage = (params, sortKey, sortOrder) => {
|
||||
if (sortKey && sortOrder) {
|
||||
params.sort_key = sortKey;
|
||||
params.sort_dir = sortOrder === 'descend' ? 'desc' : 'asc';
|
||||
}
|
||||
};
|
||||
|
||||
get paramsFuncPage() {
|
||||
return (params) => {
|
||||
const { current, all_projects, ...rest } = params;
|
||||
const { current, all_projects, withPrice, ...rest } = params;
|
||||
return {
|
||||
...rest,
|
||||
// image_type: 'image',
|
||||
@ -73,50 +66,32 @@ export class ImageStore extends Base {
|
||||
}
|
||||
|
||||
@action
|
||||
async uploadImage(imageId, file) {
|
||||
const url = `${this.getListUrl()}/${imageId}/file`;
|
||||
// const body = await getArrayBuffer(file);
|
||||
const body = file;
|
||||
const headers = {
|
||||
'content-type': 'application/octet-stream',
|
||||
};
|
||||
|
||||
const options = {
|
||||
headers,
|
||||
};
|
||||
return request.put(url, body, options);
|
||||
async uploadImage(imageId, file, conf) {
|
||||
return this.client.uploadFile(imageId, file, conf);
|
||||
}
|
||||
|
||||
@action
|
||||
async create(data, file, members) {
|
||||
async create(data, file, members, conf) {
|
||||
this.isSubmitting = true;
|
||||
const image = await request.post(this.getListUrl(), data);
|
||||
const image = await this.client.create(data);
|
||||
const { id } = image;
|
||||
// return this.submitting(this.uploadImage(id, file));
|
||||
if (members.length > 0) {
|
||||
await Promise.all(members.map((it) => this.createMember(id, it)));
|
||||
}
|
||||
await this.uploadImage(id, file);
|
||||
await this.uploadImage(id, file, conf);
|
||||
this.isSubmitting = false;
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
@action
|
||||
async update({ id }, newbody) {
|
||||
const url = this.getDetailUrl({ id });
|
||||
const headers = {
|
||||
'content-type': 'application/openstack-images-v2.1-json-patch',
|
||||
};
|
||||
const options = {
|
||||
headers,
|
||||
};
|
||||
return request.patch(url, newbody, options);
|
||||
return this.client.patch(id, newbody);
|
||||
}
|
||||
|
||||
@action
|
||||
async getMembers(id) {
|
||||
const url = `${this.getDetailUrl({ id })}/members`;
|
||||
const result = await request.get(url);
|
||||
const result = await this.client.members.list(id);
|
||||
const { members = [] } = result || {};
|
||||
this.members = members;
|
||||
return members;
|
||||
@ -124,27 +99,24 @@ export class ImageStore extends Base {
|
||||
|
||||
@action
|
||||
async createMember(id, member) {
|
||||
const url = `${this.getDetailUrl({ id })}/members`;
|
||||
const body = {
|
||||
member,
|
||||
};
|
||||
await request.post(url, body);
|
||||
await this.client.members.create(id, body);
|
||||
return this.updateMemberStatus(id, member, 'accepted');
|
||||
}
|
||||
|
||||
@action
|
||||
async updateMemberStatus(id, member, status) {
|
||||
const url = `${this.getDetailUrl({ id })}/members/${member}`;
|
||||
const body = {
|
||||
status,
|
||||
};
|
||||
return request.put(url, body);
|
||||
return this.client.members.update(id, member, body);
|
||||
}
|
||||
|
||||
@action
|
||||
async deleteMember(id, member) {
|
||||
const url = `${this.getDetailUrl({ id })}/members/${member}`;
|
||||
return request.delete(url);
|
||||
return this.client.members.delete(id, member);
|
||||
}
|
||||
|
||||
@action
|
||||
|
@ -12,20 +12,12 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { glanceBase, cinderBase, novaBase } from 'utils/constants';
|
||||
import client from 'client';
|
||||
import Base from '../base';
|
||||
|
||||
export class InstanceSnapshotStore extends Base {
|
||||
get module() {
|
||||
return 'images';
|
||||
}
|
||||
|
||||
get apiVersion() {
|
||||
return glanceBase();
|
||||
}
|
||||
|
||||
get responseKey() {
|
||||
return 'image';
|
||||
get client() {
|
||||
return client.glance.images;
|
||||
}
|
||||
|
||||
get listFilterByProject() {
|
||||
@ -49,18 +41,26 @@ export class InstanceSnapshotStore extends Base {
|
||||
|
||||
get paramsFuncPage() {
|
||||
return (params, all_projects) => {
|
||||
const { id, current, ...rest } = params;
|
||||
const { id, current, owner, ...rest } = params;
|
||||
const newParams = {
|
||||
...rest,
|
||||
// image_type: 'snapshot',
|
||||
image_type: 'snapshot',
|
||||
};
|
||||
if (!all_projects) {
|
||||
newParams.owner = this.currentProject;
|
||||
if (owner) {
|
||||
newParams.owner = owner;
|
||||
} else if (!all_projects) {
|
||||
newParams.owner = this.currentProjectId;
|
||||
}
|
||||
return newParams;
|
||||
};
|
||||
}
|
||||
|
||||
async getCountForPage(params) {
|
||||
const { limit, marker, ...rest } = params;
|
||||
const result = await this.client.count(rest);
|
||||
return result;
|
||||
}
|
||||
|
||||
get mapperBeforeFetchProject() {
|
||||
return (data) => ({
|
||||
...data,
|
||||
@ -76,13 +76,11 @@ export class InstanceSnapshotStore extends Base {
|
||||
if (!id) {
|
||||
return items;
|
||||
}
|
||||
const snapshotsUrl = `${cinderBase()}/${globals.user.project.id}/snapshots`;
|
||||
const volumesUrl = `${novaBase()}/servers/${id}/os-volume_attachments`;
|
||||
const volumeParams = {};
|
||||
const snapshotParams = { all_tenants: allProjects };
|
||||
const results = await Promise.all([
|
||||
request.get(snapshotsUrl, snapshotParams),
|
||||
request.get(volumesUrl, volumeParams),
|
||||
client.cinder.snapshots.list(snapshotParams),
|
||||
client.nova.servers.volumeAttachments.list(id, volumeParams),
|
||||
]);
|
||||
const snapshotsAll = results[0].snapshots;
|
||||
const volumesAll = results[1].volumeAttachments;
|
||||
@ -121,16 +119,11 @@ export class InstanceSnapshotStore extends Base {
|
||||
if (snapshot) {
|
||||
const { snapshot_id: snapshotId } = snapshot;
|
||||
item.snapshotId = snapshotId;
|
||||
const currentProject = globals.user.project.id;
|
||||
const snapshotsUrl = `${cinderBase()}/${currentProject}/snapshots/${snapshotId}`;
|
||||
const snapshotResult = await request.get(snapshotsUrl);
|
||||
const snapshotResult = await client.cinder.snapshots.show(snapshotId);
|
||||
const snapshotDetail = snapshotResult.snapshot;
|
||||
item.snapshotDetail = snapshotDetail;
|
||||
const { volume_id: volumeId } = snapshotDetail;
|
||||
const volumeUrl = `${cinderBase()}/${
|
||||
globals.user.project.id
|
||||
}/volumes/${volumeId}`;
|
||||
const volumeResult = await await request.get(volumeUrl);
|
||||
const volumeResult = await client.cinder.volumes.show(volumeId);
|
||||
const volumeDetail = volumeResult.volume;
|
||||
item.volumeDetail = volumeDetail;
|
||||
instanceId =
|
||||
@ -142,10 +135,10 @@ export class InstanceSnapshotStore extends Base {
|
||||
const { instance_uuid } = item;
|
||||
instanceId = instance_uuid;
|
||||
}
|
||||
let instanceResult = {};
|
||||
try {
|
||||
if (instanceId) {
|
||||
const instanceUrl = `${novaBase()}/servers/${instanceId}`;
|
||||
const instanceResult = await request.get(instanceUrl);
|
||||
instanceResult = await client.nova.servers.show(instanceId);
|
||||
const { server: { name } = {} } = instanceResult;
|
||||
instanceName = name;
|
||||
}
|
||||
@ -154,6 +147,7 @@ export class InstanceSnapshotStore extends Base {
|
||||
server_id: instanceId,
|
||||
server_name: instanceName,
|
||||
};
|
||||
item.instanceDetail = instanceResult.server || {};
|
||||
return item;
|
||||
}
|
||||
}
|
||||
|
@ -12,24 +12,23 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { glanceBase } from 'utils/constants';
|
||||
import { action, observable } from 'mobx';
|
||||
import client from 'client';
|
||||
import Base from '../base';
|
||||
|
||||
export class MetadataStore extends Base {
|
||||
@observable
|
||||
resourceTypes = [];
|
||||
|
||||
get module() {
|
||||
return 'metadefs/namespaces';
|
||||
@observable
|
||||
resourceTypeLoading = false;
|
||||
|
||||
get client() {
|
||||
return client.glance.namespaces;
|
||||
}
|
||||
|
||||
get apiVersion() {
|
||||
return glanceBase();
|
||||
}
|
||||
|
||||
get responseKey() {
|
||||
return 'namespace';
|
||||
get resourceTypeClient() {
|
||||
return client.glance.resourceTypes;
|
||||
}
|
||||
|
||||
get needGetProject() {
|
||||
@ -44,9 +43,7 @@ export class MetadataStore extends Base {
|
||||
const results = await Promise.all(
|
||||
items.map((it) => {
|
||||
const { namespace } = it;
|
||||
return request.get(this.getDetailUrl({ id: namespace }), {
|
||||
resource_type: resource_types,
|
||||
});
|
||||
return this.client.show(namespace, { resource_type: resource_types });
|
||||
})
|
||||
);
|
||||
items.forEach((it, index) => {
|
||||
@ -95,7 +92,7 @@ export class MetadataStore extends Base {
|
||||
@action
|
||||
async fetchDetail({ id }) {
|
||||
this.isLoading = true;
|
||||
const result = await request.get(this.getDetailUrl({ id }));
|
||||
const result = await this.client.show(id);
|
||||
this.detail = result;
|
||||
this.isLoading = false;
|
||||
return result;
|
||||
@ -103,20 +100,18 @@ export class MetadataStore extends Base {
|
||||
|
||||
@action
|
||||
edit({ id }, newObject) {
|
||||
return this.submitting(
|
||||
request.put(`${this.getDetailUrl({ id })}`, newObject)
|
||||
);
|
||||
return this.submitting(this.client.update(id, newObject));
|
||||
}
|
||||
|
||||
@action
|
||||
create(newObject) {
|
||||
return this.submitting(request.post(`${this.getListUrl()}`, newObject));
|
||||
return this.submitting(this.client.create(newObject));
|
||||
}
|
||||
|
||||
@action
|
||||
async fetchResourceTypes(item) {
|
||||
const url = `${this.apiVersion}/metadefs/resource_types`;
|
||||
const result = await request.get(url);
|
||||
this.resourceTypeLoading = true;
|
||||
const result = await this.resourceTypeClient.list();
|
||||
const { resource_type_associations: associations = [] } = item || {};
|
||||
const { resource_types: resourceTypes = [] } = result;
|
||||
const mapper = {};
|
||||
@ -130,6 +125,7 @@ export class MetadataStore extends Base {
|
||||
}
|
||||
});
|
||||
this.resourceTypes = resourceTypes;
|
||||
this.resourceTypeLoading = false;
|
||||
}
|
||||
|
||||
@action
|
||||
@ -137,11 +133,9 @@ export class MetadataStore extends Base {
|
||||
this.isSubmitting = true;
|
||||
await Promise.all(
|
||||
dels.map((it) => {
|
||||
const delUrl = `${this.apiVersion}/${this.module}/${namespace}/resource_types/${it.name}`;
|
||||
return request.delete(delUrl);
|
||||
return this.client.resourceTypes.delete(namespace, it.name);
|
||||
})
|
||||
);
|
||||
const addUrl = `${this.apiVersion}/${this.module}/${namespace}/resource_types`;
|
||||
return this.submitting(
|
||||
Promise.all(
|
||||
adds.map((it) => {
|
||||
@ -149,7 +143,7 @@ export class MetadataStore extends Base {
|
||||
name: it.name,
|
||||
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
|
||||
// limitations under the License.
|
||||
|
||||
import { heatBase } from 'utils/constants';
|
||||
import client from 'client';
|
||||
import Base from '../base';
|
||||
|
||||
export class StackEventStore extends Base {
|
||||
get module() {
|
||||
if (!globals.user) {
|
||||
return null;
|
||||
}
|
||||
return `${globals.user.project.id}/stacks`;
|
||||
}
|
||||
|
||||
get apiVersion() {
|
||||
return heatBase();
|
||||
get client() {
|
||||
return client.heat.stacks;
|
||||
}
|
||||
|
||||
get responseKey() {
|
||||
return 'event';
|
||||
}
|
||||
|
||||
getListUrl = ({ id, name }) =>
|
||||
`${this.apiVersion}/${this.module}/${name}/${id}/events`;
|
||||
listFetchByClient(params, originParams) {
|
||||
const { id, name } = originParams;
|
||||
return this.client.events({ id, name }, params);
|
||||
}
|
||||
|
||||
get paramsFunc() {
|
||||
return () => {};
|
||||
|
@ -12,27 +12,22 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { heatBase } from 'utils/constants';
|
||||
import client from 'client';
|
||||
import Base from '../base';
|
||||
|
||||
export class StackResourceStore extends Base {
|
||||
get module() {
|
||||
if (!globals.user) {
|
||||
return null;
|
||||
}
|
||||
return `${globals.user.project.id}/stacks`;
|
||||
}
|
||||
|
||||
get apiVersion() {
|
||||
return heatBase();
|
||||
get client() {
|
||||
return client.heat.stacks;
|
||||
}
|
||||
|
||||
get responseKey() {
|
||||
return 'resource';
|
||||
}
|
||||
|
||||
getListUrl = ({ id, name }) =>
|
||||
`${this.apiVersion}/${this.module}/${name}/${id}/resources`;
|
||||
listFetchByClient(params, originParams) {
|
||||
const { id, name } = originParams;
|
||||
return this.client.resources({ id, name }, params);
|
||||
}
|
||||
|
||||
get paramsFunc() {
|
||||
return () => {};
|
||||
|
@ -12,24 +12,13 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { heatBase } from 'utils/constants';
|
||||
import client from 'client';
|
||||
import Base from '../base';
|
||||
|
||||
export class HeatServiceStore extends Base {
|
||||
get module() {
|
||||
return 'services';
|
||||
get client() {
|
||||
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();
|
||||
|
@ -13,26 +13,20 @@
|
||||
// limitations under the License.
|
||||
|
||||
import { action, observable } from 'mobx';
|
||||
import { heatBase } from 'utils/constants';
|
||||
import client from 'client';
|
||||
import Base from '../base';
|
||||
|
||||
export class StackStore extends Base {
|
||||
@observable
|
||||
template = {};
|
||||
template = null;
|
||||
|
||||
get module() {
|
||||
if (!globals.user) {
|
||||
return null;
|
||||
}
|
||||
return `${globals.user.project.id}/stacks`;
|
||||
get client() {
|
||||
return client.heat.stacks;
|
||||
}
|
||||
|
||||
get apiVersion() {
|
||||
return heatBase();
|
||||
}
|
||||
|
||||
get responseKey() {
|
||||
return 'stack';
|
||||
detailFetchByClient(resourceParams) {
|
||||
const { id, name } = resourceParams;
|
||||
return this.client.show({ id, name });
|
||||
}
|
||||
|
||||
updateParamsSortPage = (params, sortKey, sortOrder) => {
|
||||
@ -42,8 +36,6 @@ export class StackStore extends Base {
|
||||
}
|
||||
};
|
||||
|
||||
getDetailUrl = ({ id, name }) => `${this.getListUrl()}/${name}/${id}`;
|
||||
|
||||
get paramsFuncPage() {
|
||||
return (params) => {
|
||||
const { current, all_projects, ...rest } = params;
|
||||
@ -54,7 +46,7 @@ export class StackStore extends Base {
|
||||
if (all_projects) {
|
||||
newParams.global_tenant = true;
|
||||
} else {
|
||||
newParams.tenant = globals.user.project.id;
|
||||
newParams.tenant = this.currentProjectId;
|
||||
}
|
||||
return newParams;
|
||||
};
|
||||
@ -76,28 +68,25 @@ export class StackStore extends Base {
|
||||
|
||||
@action
|
||||
create(body) {
|
||||
return this.submitting(request.post(this.getListUrl(), body));
|
||||
return this.submitting(this.client.create(body));
|
||||
}
|
||||
|
||||
@action
|
||||
edit({ id, name }, body) {
|
||||
return this.submitting(request.put(this.getDetailUrl({ id, name }), body));
|
||||
return this.submitting(this.client.update({ id, name }, body));
|
||||
}
|
||||
|
||||
@action
|
||||
delete = ({ id, name }) =>
|
||||
this.submitting(request.delete(this.getDetailUrl({ id, name })));
|
||||
delete = ({ id, name }) => this.submitting(this.client.delete({ id, name }));
|
||||
|
||||
@action
|
||||
abandon = ({ id, name }) => {
|
||||
const url = `${this.getDetailUrl({ id, name })}/abandon`;
|
||||
return this.submitting(request.delete(url));
|
||||
return this.submitting(this.client.abandon({ id, name }));
|
||||
};
|
||||
|
||||
@action
|
||||
getTemplate = async ({ id, name }) => {
|
||||
const url = `${this.getDetailUrl({ id, name })}/template`;
|
||||
const result = await request.get(url);
|
||||
const result = await this.client.template({ id, name });
|
||||
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.
|
||||
|
||||
import { action, observable } from 'mobx';
|
||||
import { ironicBase, placementBase } from 'utils/constants';
|
||||
import client from 'client';
|
||||
import Base from '../base';
|
||||
|
||||
export class IronicStore extends Base {
|
||||
@ -26,20 +26,18 @@ export class IronicStore extends Base {
|
||||
@observable
|
||||
traits = [];
|
||||
|
||||
get module() {
|
||||
return 'nodes';
|
||||
get client() {
|
||||
return client.ironic.nodes;
|
||||
}
|
||||
|
||||
get apiVersion() {
|
||||
return ironicBase();
|
||||
get portClient() {
|
||||
return client.ironic.ports;
|
||||
}
|
||||
|
||||
get responseKey() {
|
||||
return 'node';
|
||||
get listWithDetail() {
|
||||
return true;
|
||||
}
|
||||
|
||||
getListDetailUrl = () => `${this.getListUrl()}/detail`;
|
||||
|
||||
async detailDidFetch(item, all_projects, params) {
|
||||
if (params.onlyDetail) {
|
||||
return item;
|
||||
@ -48,9 +46,9 @@ export class IronicStore extends Base {
|
||||
const newItem = { ...item };
|
||||
const [bootDevice, states, validate, ports] = await Promise.all([
|
||||
this.getBootDevice(id),
|
||||
request.get(`${this.getDetailUrl({ id })}/states`),
|
||||
request.get(`${this.getDetailUrl({ id })}/validate`),
|
||||
request.get(`${this.getDetailUrl({ id })}/ports`),
|
||||
this.client.states.list(id),
|
||||
this.client.validate.list(id),
|
||||
this.client.ports.list(id),
|
||||
]);
|
||||
newItem.bootDevice = bootDevice;
|
||||
newItem.states = states;
|
||||
@ -63,8 +61,7 @@ export class IronicStore extends Base {
|
||||
if (items.length === 0) {
|
||||
return items;
|
||||
}
|
||||
const url = `${this.apiVersion}/ports/detail`;
|
||||
const result = await request.get(url);
|
||||
const result = await this.portClient.listDetail();
|
||||
const { ports } = result;
|
||||
items.forEach((it) => {
|
||||
const nodePorts = ports.filter((port) => port.node_uuid === it.uuid);
|
||||
@ -75,33 +72,30 @@ export class IronicStore extends Base {
|
||||
|
||||
@action
|
||||
changeProvision(id, body) {
|
||||
const url = `${this.getDetailUrl({ id })}/states/provision`;
|
||||
return this.submitting(request.put(url, body));
|
||||
return this.submitting(this.client.updateStatesProvision(id, body));
|
||||
}
|
||||
|
||||
@action
|
||||
changePower(id, body) {
|
||||
const url = `${this.getDetailUrl({ id })}/states/power`;
|
||||
return this.submitting(request.put(url, body));
|
||||
return this.submitting(this.client.UpdateStatesPower(id, body));
|
||||
}
|
||||
|
||||
@action
|
||||
setMaintenance(id, body) {
|
||||
const url = `${this.getDetailUrl({ id })}/maintenance`;
|
||||
return this.submitting(request.put(url, body));
|
||||
return this.submitting(this.client.updateMaintenance(id, body));
|
||||
}
|
||||
|
||||
@action
|
||||
clearMaintenance(id) {
|
||||
const url = `${this.getDetailUrl({ id })}/maintenance`;
|
||||
return this.submitting(request.delete(url));
|
||||
return this.submitting(this.client.deleteMaintenance(id));
|
||||
}
|
||||
|
||||
@action
|
||||
async getBootDevice(id) {
|
||||
const url = `${this.getDetailUrl({ id })}/management/boot_device`;
|
||||
try {
|
||||
const result = await this.submitting(request.get(url));
|
||||
const result = await this.submitting(
|
||||
this.client.getManagementBootDevice(id)
|
||||
);
|
||||
this.bootDevice = result;
|
||||
return result;
|
||||
} catch (e) {
|
||||
@ -113,39 +107,38 @@ export class IronicStore extends Base {
|
||||
|
||||
@action
|
||||
async getSupportedBootDevice(id) {
|
||||
const url = `${this.getDetailUrl({ id })}/management/boot_device/supported`;
|
||||
const result = await this.submitting(request.get(url));
|
||||
const result = await this.submitting(
|
||||
this.client.getManagementBootDeviceSupported(id)
|
||||
);
|
||||
this.supportedBootDevices = result.supported_boot_devices || [];
|
||||
return this.supportedBootDevices;
|
||||
}
|
||||
|
||||
@action
|
||||
setBootDevice(id, body) {
|
||||
const url = `${this.getDetailUrl({ id })}/management/boot_device`;
|
||||
return this.submitting(request.put(url, body));
|
||||
return this.submitting(this.client.upateManagementBootDevice(id, body));
|
||||
}
|
||||
|
||||
@action
|
||||
async create(body) {
|
||||
const { traits = [], ...rest } = body;
|
||||
if (traits.length === 0) {
|
||||
return this.submitting(request.post(this.getListUrl(), rest));
|
||||
return this.submitting(this.client.create(rest));
|
||||
}
|
||||
this.isLoading = true;
|
||||
const result = await request.post(this.getListUrl(), rest);
|
||||
const result = await this.client.create(rest);
|
||||
const { uuid } = result;
|
||||
return this.updateTraits(uuid, traits);
|
||||
}
|
||||
|
||||
@action
|
||||
edit({ id }, body) {
|
||||
return this.submitting(request.patch(`${this.getDetailUrl({ id })}`, body));
|
||||
return this.submitting(this.client.patch(id, body));
|
||||
}
|
||||
|
||||
@action
|
||||
async getTraits() {
|
||||
const url = `${placementBase()}/traits`;
|
||||
const result = await request.get(url);
|
||||
const result = await client.placement.traits.list();
|
||||
const { traits = [] } = result;
|
||||
traits.sort();
|
||||
this.traits = traits;
|
||||
@ -153,11 +146,10 @@ export class IronicStore extends Base {
|
||||
|
||||
@action
|
||||
updateTraits(id, traits) {
|
||||
const url = `${this.getDetailUrl({ id })}/traits`;
|
||||
const body = {
|
||||
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
|
||||
// limitations under the License.
|
||||
|
||||
import { ironicBase } from 'utils/constants';
|
||||
import { action } from 'mobx';
|
||||
import client from 'client';
|
||||
import Base from '../base';
|
||||
|
||||
export class IronicPortGroupStore extends Base {
|
||||
get module() {
|
||||
return 'portgroups';
|
||||
get client() {
|
||||
return client.ironic.nodes.portgroups;
|
||||
}
|
||||
|
||||
get apiVersion() {
|
||||
return ironicBase();
|
||||
listFetchByClient(params, originParams) {
|
||||
const { id } = originParams;
|
||||
return this.client.listDetail(id, params);
|
||||
}
|
||||
|
||||
get responseKey() {
|
||||
return 'portgroup';
|
||||
}
|
||||
|
||||
getListDetailUrl = ({ id }) =>
|
||||
`${this.apiVersion}/nodes/${id}/${this.module}/detail`;
|
||||
|
||||
get paramsFunc() {
|
||||
return () => {};
|
||||
}
|
||||
|
||||
@action
|
||||
create(data) {
|
||||
return this.submitting(request.post(this.getListUrl(), data));
|
||||
return this.submitting(client.ironic.portgroups.create(data));
|
||||
}
|
||||
|
||||
@action
|
||||
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
|
||||
// limitations under the License.
|
||||
|
||||
import { ironicBase } from 'utils/constants';
|
||||
import { action } from 'mobx';
|
||||
import client from 'client';
|
||||
import Base from '../base';
|
||||
|
||||
export class IronicPortStore extends Base {
|
||||
get module() {
|
||||
return 'ports';
|
||||
get client() {
|
||||
return client.ironic.ports;
|
||||
}
|
||||
|
||||
get apiVersion() {
|
||||
return ironicBase();
|
||||
listFetchByClient(params, originParams) {
|
||||
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() {
|
||||
return () => {};
|
||||
}
|
||||
|
||||
@action
|
||||
create(data) {
|
||||
return this.submitting(request.post(this.getListUrl(), data));
|
||||
return this.submitting(this.client.create(data));
|
||||
}
|
||||
|
||||
@action
|
||||
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
|
||||
// limitations under the License.
|
||||
|
||||
import { keystoneBase } from 'utils/constants';
|
||||
import client from 'client';
|
||||
import Base from '../base';
|
||||
|
||||
export class AuthCatalogStore extends Base {
|
||||
get module() {
|
||||
return 'auth/catalog';
|
||||
}
|
||||
|
||||
get apiVersion() {
|
||||
return keystoneBase();
|
||||
get client() {
|
||||
return client.keystone.catalog;
|
||||
}
|
||||
|
||||
get listResponseKey() {
|
||||
return 'catalog';
|
||||
return this.responseKey;
|
||||
}
|
||||
|
||||
get mapper() {
|
||||
|
@ -13,9 +13,8 @@
|
||||
// limitations under the License.
|
||||
|
||||
import { action, observable } from 'mobx';
|
||||
import request from 'utils/request';
|
||||
import { keystoneBase } from 'utils/constants';
|
||||
import { get } from 'lodash';
|
||||
import client from 'client';
|
||||
import Base from '../base';
|
||||
|
||||
export class DomainStore extends Base {
|
||||
@ -28,20 +27,14 @@ export class DomainStore extends Base {
|
||||
@observable
|
||||
adminRoleId = '';
|
||||
|
||||
get module() {
|
||||
return 'domains';
|
||||
get client() {
|
||||
return client.keystone.domains;
|
||||
}
|
||||
|
||||
get apiVersion() {
|
||||
return keystoneBase();
|
||||
get userClient() {
|
||||
return client.keystone.users;
|
||||
}
|
||||
|
||||
get responseKey() {
|
||||
return 'domain';
|
||||
}
|
||||
|
||||
getResourceUrl = () => keystoneBase();
|
||||
|
||||
@action
|
||||
async fetchList({
|
||||
limit,
|
||||
@ -55,33 +48,32 @@ export class DomainStore extends Base {
|
||||
// todo: no page, no limit, fetch all
|
||||
// const params = { ...filters };
|
||||
|
||||
await Promise.all([
|
||||
request.get(`${this.apiVersion}/domains`),
|
||||
request.get(`${this.apiVersion}/users`),
|
||||
]).then(([domainsResult, usersResult]) => {
|
||||
const { domains } = domainsResult;
|
||||
// eslint-disable-next-line array-callback-return
|
||||
domains.map((domain) => {
|
||||
const domainUsers = usersResult.users.filter(
|
||||
(it) => it.domain_id === domain.id
|
||||
);
|
||||
domain.user_num = domainUsers.length;
|
||||
});
|
||||
await Promise.all([this.client.list(), this.userClient.list()]).then(
|
||||
([domainsResult, usersResult]) => {
|
||||
const { domains } = domainsResult;
|
||||
// eslint-disable-next-line array-callback-return
|
||||
domains.map((domain) => {
|
||||
const domainUsers = usersResult.users.filter(
|
||||
(it) => it.domain_id === domain.id
|
||||
);
|
||||
domain.user_num = domainUsers.length;
|
||||
});
|
||||
|
||||
// const { domains: items } = domainsResult;
|
||||
this.list.update({
|
||||
data: domains,
|
||||
total: domains.length || 0,
|
||||
limit: Number(limit) || 10,
|
||||
page: Number(page) || 1,
|
||||
sortKey,
|
||||
sortOrder,
|
||||
filters,
|
||||
isLoading: false,
|
||||
...(this.list.silent ? {} : { selectedRowKeys: [] }),
|
||||
});
|
||||
return domains;
|
||||
});
|
||||
// const { domains: items } = domainsResult;
|
||||
this.list.update({
|
||||
data: domains,
|
||||
total: domains.length || 0,
|
||||
limit: Number(limit) || 10,
|
||||
page: Number(page) || 1,
|
||||
sortKey,
|
||||
sortOrder,
|
||||
filters,
|
||||
isLoading: false,
|
||||
...(this.list.silent ? {} : { selectedRowKeys: [] }),
|
||||
});
|
||||
return domains;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@action
|
||||
@ -89,74 +81,67 @@ export class DomainStore extends Base {
|
||||
if (!silent) {
|
||||
this.isLoading = true;
|
||||
}
|
||||
await Promise.all([
|
||||
request.get(this.getDetailUrl({ id })),
|
||||
request.get(`${this.apiVersion}/users`),
|
||||
]).then(([result, usersResult]) => {
|
||||
const domain = this.mapper(get(result, this.responseKey) || result);
|
||||
domain.domain_administrator = [];
|
||||
const domainUsers = usersResult.users.filter(
|
||||
(it) => it.domain_id === domain.id
|
||||
);
|
||||
domain.user_num = domainUsers.length;
|
||||
this.domainUsers = domainUsers;
|
||||
this.detail = domain;
|
||||
this.isLoading = false;
|
||||
return domain;
|
||||
});
|
||||
await Promise.all([this.client.show(id), this.userClient.list()]).then(
|
||||
([result, usersResult]) => {
|
||||
const domain = this.mapper(get(result, this.responseKey) || result);
|
||||
domain.domain_administrator = [];
|
||||
const domainUsers = usersResult.users.filter(
|
||||
(it) => it.domain_id === domain.id
|
||||
);
|
||||
domain.user_num = domainUsers.length;
|
||||
this.domainUsers = domainUsers;
|
||||
this.detail = domain;
|
||||
this.isLoading = false;
|
||||
return domain;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@action
|
||||
async fetchDomain() {
|
||||
const doaminsResult = await request.get(`${this.getResourceUrl()}/domains`);
|
||||
const doaminsResult = await this.client.list();
|
||||
this.domains = doaminsResult.domains;
|
||||
}
|
||||
|
||||
@action
|
||||
async update({ id, body }) {
|
||||
const url = `${this.apiVersion}/${id}`;
|
||||
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;
|
||||
return resData;
|
||||
}
|
||||
|
||||
@action
|
||||
async edit({ id, description }) {
|
||||
const url = `${this.apiVersion}/domains/${id}`;
|
||||
const reqBody = {
|
||||
domain: { description },
|
||||
};
|
||||
return this.submitting(request.patch(url, reqBody));
|
||||
return this.submitting(this.client.patch(id, reqBody));
|
||||
}
|
||||
|
||||
async setDomainAdmin({ id, user_id, role_id }) {
|
||||
const url = `${this.apiVersion}/domains/${id}/users/${user_id}/roles/${role_id}`;
|
||||
return this.submitting(request.put(url));
|
||||
return this.submitting(this.client.users.roles.put(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 request.delete(url);
|
||||
const result = await this.client.users.roles.delete(id, user_id, role_id);
|
||||
return result;
|
||||
}
|
||||
|
||||
@action
|
||||
async forbidden({ id }) {
|
||||
const url = `${this.apiVersion}/domains/${id}`;
|
||||
const reqBody = {
|
||||
domain: { enabled: false },
|
||||
};
|
||||
return this.submitting(request.patch(url, reqBody));
|
||||
return this.submitting(this.client.patch(id, reqBody));
|
||||
}
|
||||
|
||||
@action
|
||||
async enable({ id }) {
|
||||
const url = `${this.apiVersion}/domains/${id}`;
|
||||
const reqBody = {
|
||||
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 { getGBValue } from 'utils/index';
|
||||
import request from 'utils/request';
|
||||
import {
|
||||
keystoneBase,
|
||||
novaBase,
|
||||
cinderBase,
|
||||
neutronBase,
|
||||
} from 'utils/constants';
|
||||
import { get } from 'lodash';
|
||||
import { get, isNil, isEmpty } from 'lodash';
|
||||
import client from 'client';
|
||||
import Base from '../base';
|
||||
|
||||
export class ProjectStore extends Base {
|
||||
@ -40,18 +34,20 @@ export class ProjectStore extends Base {
|
||||
@observable
|
||||
projectsOnly = [];
|
||||
|
||||
getResourceUrl = () => keystoneBase();
|
||||
|
||||
get module() {
|
||||
return 'projects';
|
||||
get client() {
|
||||
return client.keystone.projects;
|
||||
}
|
||||
|
||||
get apiVersion() {
|
||||
return keystoneBase();
|
||||
get roleAssignmentClient() {
|
||||
return client.keystone.roleAssignments;
|
||||
}
|
||||
|
||||
get responseKey() {
|
||||
return 'project';
|
||||
get roleClient() {
|
||||
return client.keystone.roles;
|
||||
}
|
||||
|
||||
get userClient() {
|
||||
return client.keystone.users;
|
||||
}
|
||||
|
||||
@action
|
||||
@ -66,16 +62,23 @@ export class ProjectStore extends Base {
|
||||
this.list.isLoading = true;
|
||||
// todo: no page, no limit, fetch all
|
||||
// const params = { ...filters };
|
||||
const { tags } = filters;
|
||||
|
||||
const [roleAssignmentsReault, projectsResult, roleResult] =
|
||||
await Promise.all([
|
||||
request.get(`${this.apiVersion}/role_assignments`),
|
||||
request.get(`${this.apiVersion}/projects`),
|
||||
request.get(`${this.apiVersion}/roles`),
|
||||
this.roleAssignmentClient.list(),
|
||||
this.client.list(tags ? { tags } : {}),
|
||||
this.roleClient.list(),
|
||||
]);
|
||||
const { projects } = projectsResult;
|
||||
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) => {
|
||||
const userMapRole = {}; // all user include system role and project role: { user_id: [roles_id] }
|
||||
const projectGroups = {};
|
||||
@ -169,25 +172,23 @@ export class ProjectStore extends Base {
|
||||
|
||||
@action
|
||||
async enable({ id }) {
|
||||
const url = `${this.apiVersion}/projects/${id}`;
|
||||
const reqBody = {
|
||||
project: { enabled: true },
|
||||
};
|
||||
return this.submitting(request.patch(url, reqBody));
|
||||
return this.submitting(this.client.patch(id, reqBody));
|
||||
}
|
||||
|
||||
@action
|
||||
async forbidden({ id }) {
|
||||
const url = `${this.apiVersion}/projects/${id}`;
|
||||
const reqBody = {
|
||||
project: { enabled: false },
|
||||
};
|
||||
return this.submitting(request.patch(url, reqBody));
|
||||
return this.submitting(this.client.patch(id, reqBody));
|
||||
}
|
||||
|
||||
@action
|
||||
async fetchDomain() {
|
||||
const doaminsResult = await request.get(`${this.getResourceUrl()}/domains`);
|
||||
const doaminsResult = await this.skylineClient.domains();
|
||||
this.domains = doaminsResult.domains;
|
||||
}
|
||||
|
||||
@ -196,9 +197,7 @@ export class ProjectStore extends Base {
|
||||
const reqBody = {
|
||||
project: data,
|
||||
};
|
||||
return this.submitting(
|
||||
request.post(`${this.getResourceUrl()}/projects`, reqBody)
|
||||
);
|
||||
return this.submitting(this.client.create(reqBody));
|
||||
}
|
||||
|
||||
@action
|
||||
@ -208,12 +207,18 @@ export class ProjectStore extends Base {
|
||||
}
|
||||
const [roleAssignmentsReault, projectResult, roleResult] =
|
||||
await Promise.all([
|
||||
request.get(`${this.apiVersion}/role_assignments`),
|
||||
request.get(`${this.apiVersion}/projects/${id}`),
|
||||
request.get(`${this.apiVersion}/roles`),
|
||||
this.roleAssignmentClient.list(),
|
||||
this.client.show(id),
|
||||
this.roleClient.list(),
|
||||
]);
|
||||
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 userMapRole = {};
|
||||
const projectGroups = {};
|
||||
@ -232,30 +237,26 @@ export class ProjectStore extends Base {
|
||||
project.groups = projectGroups;
|
||||
project.user_num = Object.keys(userMapRole).length;
|
||||
project.group_num = Object.keys(projectGroups).length;
|
||||
this.detail = project;
|
||||
const newItem = await this.detailDidFetch(project);
|
||||
this.detail = newItem;
|
||||
this.isLoading = false;
|
||||
return project;
|
||||
return newItem;
|
||||
}
|
||||
|
||||
@action
|
||||
async edit({ id, description, name }) {
|
||||
const url = `${this.apiVersion}/projects/${id}`;
|
||||
const reqBody = {
|
||||
project: { description, name },
|
||||
};
|
||||
return this.submitting(request.patch(url, reqBody));
|
||||
return this.submitting(this.client.patch(id, reqBody));
|
||||
}
|
||||
|
||||
@action
|
||||
async fetchProjectQuota({ project_id }) {
|
||||
const [novaResult, cinderResult, neutronResult] = await Promise.all([
|
||||
request.get(`${novaBase()}/os-quota-sets/${project_id}/detail`),
|
||||
request.get(
|
||||
`${cinderBase()}/${
|
||||
globals.user.project.id
|
||||
}/os-quota-sets/${project_id}?usage=True`
|
||||
),
|
||||
request.get(`${neutronBase()}/quotas/${project_id}/details`),
|
||||
client.nova.quotaSets.detail(project_id),
|
||||
client.cinder.quotaSets.show(project_id, { usage: 'True' }),
|
||||
client.neutron.quotas.details(project_id),
|
||||
]);
|
||||
this.isSubmitting = false;
|
||||
const { quota_set: novaQuota } = novaResult;
|
||||
@ -276,6 +277,15 @@ export class ProjectStore extends Base {
|
||||
this.quota = quota;
|
||||
}
|
||||
|
||||
omitNil = (obj) => {
|
||||
return Object.keys(obj).reduce((acc, v) => {
|
||||
if (!isNil(obj[v])) {
|
||||
acc[v] = obj[v];
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
};
|
||||
|
||||
@action
|
||||
async updateProjectQuota({ project_id, data }) {
|
||||
this.isSubmitting = true;
|
||||
@ -285,6 +295,7 @@ export class ProjectStore extends Base {
|
||||
ram,
|
||||
volumes,
|
||||
gigabytes,
|
||||
firewall_group,
|
||||
security_group_rule,
|
||||
server_groups,
|
||||
snapshots,
|
||||
@ -301,59 +312,61 @@ export class ProjectStore extends Base {
|
||||
...others
|
||||
} = data;
|
||||
let ramGb = ram;
|
||||
if (ram !== -1) {
|
||||
if (ram && ram !== -1) {
|
||||
ramGb = ram * 1024;
|
||||
}
|
||||
const novaReqBody = {
|
||||
quota_set: {
|
||||
quota_set: this.omitNil({
|
||||
instances,
|
||||
cores,
|
||||
ram: ramGb,
|
||||
server_groups,
|
||||
server_group_members,
|
||||
key_pairs,
|
||||
},
|
||||
}),
|
||||
};
|
||||
const cinderReqBody = {
|
||||
quota_set: {
|
||||
quota_set: this.omitNil({
|
||||
volumes,
|
||||
gigabytes,
|
||||
backup_gigabytes,
|
||||
snapshots,
|
||||
backups,
|
||||
...others,
|
||||
},
|
||||
}),
|
||||
};
|
||||
const firewallValue = firewall_group ? { firewall_group } : {};
|
||||
const neutronReqBody = {
|
||||
quota: {
|
||||
quota: this.omitNil({
|
||||
network,
|
||||
router,
|
||||
subnet,
|
||||
floatingip,
|
||||
security_group,
|
||||
security_group_rule,
|
||||
...firewallValue,
|
||||
port,
|
||||
},
|
||||
}),
|
||||
};
|
||||
const result = await Promise.all([
|
||||
request.put(`${novaBase()}/os-quota-sets/${project_id}`, novaReqBody),
|
||||
request.put(
|
||||
`${cinderBase()}/${
|
||||
globals.user.project.id
|
||||
}/os-quota-sets/${project_id}`,
|
||||
cinderReqBody
|
||||
),
|
||||
request.put(`${neutronBase()}/quotas/${project_id}`, neutronReqBody),
|
||||
]);
|
||||
const reqs = [];
|
||||
if (!isEmpty(novaReqBody.quota_set)) {
|
||||
reqs.push(client.nova.quotaSets.update(project_id, novaReqBody));
|
||||
}
|
||||
if (!isEmpty(cinderReqBody.quota_set)) {
|
||||
reqs.push(client.cinder.quotaSets.update(project_id, cinderReqBody));
|
||||
}
|
||||
if (!isEmpty(neutronReqBody.quota)) {
|
||||
reqs.push(client.neutron.quotas.update(project_id, neutronReqBody));
|
||||
}
|
||||
|
||||
const result = await Promise.all(reqs);
|
||||
this.isSubmitting = false;
|
||||
return result;
|
||||
}
|
||||
|
||||
@action
|
||||
async getUserRoleList({ id, user_id }) {
|
||||
const url = `${this.apiVersion}/projects/${id}/users/${user_id}/roles/`;
|
||||
this.isSubmitting = true;
|
||||
const result = await request.get(url);
|
||||
const result = await this.client.users.roles.list(id, user_id);
|
||||
this.userRoleList = result.roles;
|
||||
}
|
||||
|
||||
@ -362,43 +375,37 @@ export class ProjectStore extends Base {
|
||||
const body = {};
|
||||
body[this.responseKey] = data;
|
||||
this.isSubmitting = true;
|
||||
const result = await request.post(this.getListUrl(), body);
|
||||
const result = await this.client.create(body);
|
||||
this.isSubmitting = false;
|
||||
return result;
|
||||
}
|
||||
|
||||
@action
|
||||
async assignUserRole({ id, user_id, role_id }) {
|
||||
const url = `${this.apiVersion}/projects/${id}/users/${user_id}/roles/${role_id}`;
|
||||
const result = request.put(url);
|
||||
const result = await this.client.users.roles.update(id, user_id, role_id);
|
||||
return result;
|
||||
}
|
||||
|
||||
@action
|
||||
async removeUserRole({ id, user_id, role_id }) {
|
||||
const url = `${this.apiVersion}/projects/${id}/users/${user_id}/roles/${role_id}`;
|
||||
const result = request.delete(url);
|
||||
const result = await this.client.users.roles.delete(id, user_id, role_id);
|
||||
return result;
|
||||
}
|
||||
|
||||
@action
|
||||
async getGroupRoleList({ id, group_id }) {
|
||||
const url = `${this.apiVersion}/projects/${id}/groups/${group_id}/roles/`;
|
||||
this.isSubmitting = true;
|
||||
const result = await request.get(url);
|
||||
const result = await this.client.groups.roles.list(id, group_id);
|
||||
this.groupRoleList = result.roles;
|
||||
}
|
||||
|
||||
@action
|
||||
async assignGroupRole({ id, group_id, role_id }) {
|
||||
const url = `${this.apiVersion}/projects/${id}/groups/${group_id}/roles/${role_id}`;
|
||||
const result = request.put(url);
|
||||
const result = await this.client.groups.roles.update(id, group_id, role_id);
|
||||
return result;
|
||||
}
|
||||
|
||||
async removeGroupRole({ id, group_id, role_id }) {
|
||||
const url = `${this.apiVersion}/projects/${id}/groups/${group_id}/roles/${role_id}`;
|
||||
const result = request.delete(url);
|
||||
const result = await this.client.groups.roles.delete(id, group_id, role_id);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -415,10 +422,10 @@ export class ProjectStore extends Base {
|
||||
const { userId } = filters;
|
||||
const [roleAssignmentsReault, projectsResult, roleResult, groupResult] =
|
||||
await Promise.all([
|
||||
request.get(`${this.apiVersion}/role_assignments`),
|
||||
request.get(`${this.apiVersion}/users/${userId}/projects`),
|
||||
request.get(`${this.apiVersion}/roles`),
|
||||
request.get(`${this.apiVersion}/users/${userId}/groups`),
|
||||
this.roleAssignmentClient.list(),
|
||||
this.userClient.projects.list(userId),
|
||||
this.roleClient.list(),
|
||||
this.userClient.groups.list(userId),
|
||||
]);
|
||||
const projects = get(projectsResult, this.listResponseKey, []);
|
||||
projects.map((project) => {
|
||||
@ -485,9 +492,9 @@ export class ProjectStore extends Base {
|
||||
const { groupId } = filters;
|
||||
const [roleAssignmentsReault, projectsResult, roleResult] =
|
||||
await Promise.all([
|
||||
request.get(`${this.apiVersion}/role_assignments`),
|
||||
request.get(`${this.apiVersion}/projects`),
|
||||
request.get(`${this.apiVersion}/roles`),
|
||||
this.roleAssignmentClient.list(),
|
||||
this.client.list(),
|
||||
this.roleClient.list(),
|
||||
]);
|
||||
const projects = get(projectsResult, this.listResponseKey, []);
|
||||
projects.map((project) => {
|
||||
@ -534,8 +541,10 @@ export class ProjectStore extends Base {
|
||||
@action
|
||||
async fetchProjectListOnly() {
|
||||
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.list.isLoading = false;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,21 +12,13 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { keystoneBase } from 'utils/constants';
|
||||
import { action, observable } from 'mobx';
|
||||
import client from 'client';
|
||||
import Base from '../base';
|
||||
|
||||
export class RoleStore extends Base {
|
||||
get module() {
|
||||
return 'roles';
|
||||
}
|
||||
|
||||
get apiVersion() {
|
||||
return keystoneBase();
|
||||
}
|
||||
|
||||
get responseKey() {
|
||||
return 'role';
|
||||
get client() {
|
||||
return client.keystone.roles;
|
||||
}
|
||||
|
||||
@observable
|
||||
@ -34,9 +26,7 @@ export class RoleStore extends Base {
|
||||
|
||||
@action
|
||||
async fetchImpliedRoles({ id }) {
|
||||
const rolesResult = await request.get(
|
||||
`${this.getDetailUrl({ id })}/implies/`
|
||||
);
|
||||
const rolesResult = await this.client.implies.list(id);
|
||||
const {
|
||||
role_inference: { implies },
|
||||
} = rolesResult;
|
||||
|
@ -12,40 +12,28 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { keystoneBase } from 'utils/constants';
|
||||
import { action } from 'mobx';
|
||||
import client from 'client';
|
||||
import Base from '../base';
|
||||
|
||||
export class TagStore extends Base {
|
||||
get module() {
|
||||
return 'tags';
|
||||
get client() {
|
||||
return client.keystone.projects.tags;
|
||||
}
|
||||
|
||||
get apiVersion() {
|
||||
return keystoneBase();
|
||||
}
|
||||
|
||||
get responseKey() {
|
||||
return 'tag';
|
||||
listFetchByClient(params, originParams) {
|
||||
const { project_id } = originParams;
|
||||
return this.client.list(project_id, params);
|
||||
}
|
||||
|
||||
get paramsFunc() {
|
||||
return () => null;
|
||||
}
|
||||
|
||||
getListUrl = ({ project_id }) =>
|
||||
`${this.apiVersion}/projects/${project_id}/${this.module}`;
|
||||
|
||||
@action
|
||||
update({ project_id }, newObject, sleepTime) {
|
||||
update({ project_id }, newObject) {
|
||||
return this.submitting(
|
||||
request.put(
|
||||
`${this.getListUrl({ project_id })}`,
|
||||
newObject,
|
||||
null,
|
||||
null,
|
||||
sleepTime
|
||||
)
|
||||
client.keystone.projects.updateTags(project_id, newObject)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -13,9 +13,8 @@
|
||||
// limitations under the License.
|
||||
|
||||
import { action, observable } from 'mobx';
|
||||
import { keystoneBase } from 'utils/constants';
|
||||
import request from 'utils/request';
|
||||
import { get } from 'lodash';
|
||||
import client from 'client';
|
||||
import Base from '../base';
|
||||
import globalProjectStore from './project';
|
||||
|
||||
@ -32,16 +31,32 @@ export class GroupStore extends Base {
|
||||
@observable
|
||||
groupUsers = [];
|
||||
|
||||
get module() {
|
||||
return 'groups';
|
||||
get client() {
|
||||
return client.keystone.groups;
|
||||
}
|
||||
|
||||
get apiVersion() {
|
||||
return keystoneBase();
|
||||
get domainClient() {
|
||||
return client.keystone.domains;
|
||||
}
|
||||
|
||||
get responseKey() {
|
||||
return 'group';
|
||||
get systemGroupClient() {
|
||||
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
|
||||
@ -51,7 +66,7 @@ export class GroupStore extends Base {
|
||||
|
||||
body[this.responseKey] = other;
|
||||
this.isSubmitting = true;
|
||||
const result = await request.post(this.getListUrl(), body);
|
||||
const result = await this.client.create(body);
|
||||
const {
|
||||
group: { id: group_id },
|
||||
} = result;
|
||||
@ -83,7 +98,7 @@ export class GroupStore extends Base {
|
||||
|
||||
@action
|
||||
async fetchDomain() {
|
||||
const doaminsResult = await request.get(`${this.apiVersion}/domains`);
|
||||
const doaminsResult = await this.domainClient.list();
|
||||
this.domains = doaminsResult.domains;
|
||||
}
|
||||
|
||||
@ -99,12 +114,11 @@ export class GroupStore extends Base {
|
||||
|
||||
@action
|
||||
async edit({ id, description, name }) {
|
||||
const url = `${this.apiVersion}/groups/${id}`;
|
||||
this.isSubmitting = true;
|
||||
const reqBody = {
|
||||
group: { description, name },
|
||||
};
|
||||
const result = await request.patch(url, reqBody);
|
||||
const result = await this.client.patch(id, reqBody);
|
||||
this.isSubmitting = false;
|
||||
return result;
|
||||
}
|
||||
@ -112,51 +126,38 @@ export class GroupStore extends Base {
|
||||
@action
|
||||
async fetchSystemRole({ id }) {
|
||||
this.systemRoles = [];
|
||||
const rolesResult = await request.get(
|
||||
`${this.apiVersion}/system/groups/${id}/roles`
|
||||
);
|
||||
const rolesResult = await this.systemGroupClient.roles.list(id);
|
||||
this.systemRoles = rolesResult.roles;
|
||||
}
|
||||
|
||||
@action
|
||||
async assignSystemRole({ id, role_id }) {
|
||||
const result = request.put(
|
||||
`${this.apiVersion}/system/groups/${id}/roles/${role_id}`
|
||||
);
|
||||
return result;
|
||||
return this.systemGroupClient.roles.update(id, role_id);
|
||||
}
|
||||
|
||||
@action
|
||||
async deleteSystemRole({ id, role_id }) {
|
||||
const result = request.delete(
|
||||
`${this.apiVersion}/system/groups/${id}/roles/${role_id}`
|
||||
);
|
||||
return result;
|
||||
return this.systemGroupClient.roles.delete(id, role_id);
|
||||
}
|
||||
|
||||
@action
|
||||
async fetchDomainRole({ id, domain_id }) {
|
||||
this.domainRoles = [];
|
||||
const rolesResult = await request.get(
|
||||
`${this.apiVersion}/domains/${domain_id}/groups/${id}/roles`
|
||||
const rolesResult = await this.domainClient.groups.roles.list(
|
||||
domain_id,
|
||||
id
|
||||
);
|
||||
this.domainRoles = rolesResult.roles;
|
||||
}
|
||||
|
||||
@action
|
||||
async assignDomainRole({ id, role_id, domain_id }) {
|
||||
const result = request.put(
|
||||
`${this.apiVersion}/domains/${domain_id}/groups/${id}/roles/${role_id}`
|
||||
);
|
||||
return result;
|
||||
return this.domainClient.groups.roles.update(domain_id, id, role_id);
|
||||
}
|
||||
|
||||
@action
|
||||
async deleteDomainRole({ id, role_id, domain_id }) {
|
||||
const result = request.delete(
|
||||
`${this.apiVersion}/domains/${domain_id}/groups/${id}/roles/${role_id}`
|
||||
);
|
||||
return result;
|
||||
return this.domainClient.groups.roles.delete(domain_id, id, role_id);
|
||||
}
|
||||
|
||||
@action
|
||||
@ -172,8 +173,8 @@ export class GroupStore extends Base {
|
||||
const { projectId } = filters;
|
||||
const params = {};
|
||||
const [roleAssignmentsReault, result] = await Promise.all([
|
||||
request.get(`${this.apiVersion}/role_assignments`),
|
||||
request.get(this.getListUrl(), params),
|
||||
this.roleAssignmentClient.list(),
|
||||
this.client.list(params),
|
||||
]);
|
||||
const projectGroupIds = [];
|
||||
roleAssignmentsReault.role_assignments.forEach((roleAssignment) => {
|
||||
@ -191,33 +192,38 @@ export class GroupStore extends Base {
|
||||
data = data.filter((it) => projectGroupIds.indexOf(it.id) >= 0);
|
||||
// const items = data.map(this.mapper);
|
||||
// const newData = await this.listDidFetch(items);
|
||||
Promise.all(
|
||||
data.map((it) => request.get(`${this.apiVersion}/groups/${it.id}/users`))
|
||||
).then((rest) => {
|
||||
const addUserItem = data.map((it, index) => {
|
||||
const { users } = rest[index];
|
||||
const userIds = users.map((user) => user.id);
|
||||
it.users = userIds;
|
||||
it.user_num = users.length;
|
||||
return it;
|
||||
});
|
||||
const items = addUserItem.map((item) =>
|
||||
this.mapperProject(roleAssignmentsReault, item)
|
||||
);
|
||||
this.list.update({
|
||||
data: items,
|
||||
total: items.length || 0,
|
||||
limit: Number(limit) || 10,
|
||||
page: Number(page) || 1,
|
||||
sortKey,
|
||||
sortOrder,
|
||||
filters,
|
||||
isLoading: false,
|
||||
...(this.list.silent ? {} : { selectedRowKeys: [] }),
|
||||
});
|
||||
Promise.all(data.map((it) => this.client.users.list(it.id))).then(
|
||||
(rest) => {
|
||||
const addUserItem = data.map((it, index) => {
|
||||
const { users } = rest[index];
|
||||
const userIds = users.map((user) => user.id);
|
||||
const userInfo = users.map((user) => ({
|
||||
id: user.id,
|
||||
name: user.name,
|
||||
}));
|
||||
it.users = userIds;
|
||||
it.user_num = users.length;
|
||||
it.user_info = userInfo;
|
||||
return it;
|
||||
});
|
||||
const items = addUserItem.map((item) =>
|
||||
this.mapperProject(roleAssignmentsReault, item)
|
||||
);
|
||||
this.list.update({
|
||||
data: items,
|
||||
total: items.length || 0,
|
||||
limit: Number(limit) || 10,
|
||||
page: Number(page) || 1,
|
||||
sortKey,
|
||||
sortOrder,
|
||||
filters,
|
||||
isLoading: false,
|
||||
...(this.list.silent ? {} : { selectedRowKeys: [] }),
|
||||
});
|
||||
|
||||
return items;
|
||||
});
|
||||
return items;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@action
|
||||
@ -233,8 +239,8 @@ export class GroupStore extends Base {
|
||||
const { userId } = filters;
|
||||
const params = {};
|
||||
const [roleAssignmentsReault, result] = await Promise.all([
|
||||
request.get(`${this.apiVersion}/role_assignments`),
|
||||
request.get(`${this.apiVersion}/users/${userId}/groups`, params),
|
||||
this.roleAssignmentClient.list(),
|
||||
this.userClient.groups.list(userId, params),
|
||||
]);
|
||||
const projectGroupIds = [];
|
||||
roleAssignmentsReault.role_assignments.forEach((roleAssignment) => {
|
||||
@ -269,9 +275,7 @@ export class GroupStore extends Base {
|
||||
|
||||
@action
|
||||
async fetchGroupUsers({ id }) {
|
||||
const usersResult = await request.get(
|
||||
`${this.apiVersion}/groups/${id}/users`
|
||||
);
|
||||
const usersResult = await this.client.users.list(id);
|
||||
const { users: result } = usersResult;
|
||||
this.groupUsers = result;
|
||||
return result;
|
||||
@ -279,18 +283,12 @@ export class GroupStore extends Base {
|
||||
|
||||
@action
|
||||
async deleteGroupUsers({ id, user_id }) {
|
||||
const result = request.delete(
|
||||
`${this.apiVersion}/groups/${id}/users/${user_id}`
|
||||
);
|
||||
return result;
|
||||
return this.client.users.delete(id, user_id);
|
||||
}
|
||||
|
||||
@action
|
||||
async addGroupUsers({ id, user_id }) {
|
||||
const result = request.put(
|
||||
`${this.apiVersion}/groups/${id}/users/${user_id}`
|
||||
);
|
||||
return result;
|
||||
return this.client.users.update(id, user_id);
|
||||
}
|
||||
|
||||
mapperProject = (roleAssignmentsReault, item) => {
|
||||
@ -320,17 +318,12 @@ export class GroupStore extends Base {
|
||||
// todo: no page, no limit, fetch all
|
||||
const params = { ...filters };
|
||||
|
||||
const result = await request.get(
|
||||
this.getListDetailUrl() || this.getListUrl(),
|
||||
params
|
||||
);
|
||||
const roleAssignmentsReault = await request.get(
|
||||
`${this.apiVersion}/role_assignments/`
|
||||
);
|
||||
const result = await this.client.list(params);
|
||||
const roleAssignmentsReault = await this.roleAssignmentClient.list();
|
||||
const data = get(result, this.listResponseKey, []);
|
||||
Promise.all(
|
||||
data.map(
|
||||
(it) => request.get(`${this.apiVersion}/groups/${it.id}/users`)
|
||||
(it) => this.client.users.list(it.id)
|
||||
// const { users } = userResult;
|
||||
// return { ...it, users };
|
||||
)
|
||||
@ -338,8 +331,13 @@ export class GroupStore extends Base {
|
||||
const addUserItem = data.map((it, index) => {
|
||||
const { users } = rest[index];
|
||||
const userIds = users.map((user) => user.id);
|
||||
const userInfo = users.map((user) => ({
|
||||
id: user.id,
|
||||
name: user.name,
|
||||
}));
|
||||
it.users = userIds;
|
||||
it.user_num = users.length;
|
||||
it.user_info = userInfo;
|
||||
return it;
|
||||
});
|
||||
const items = addUserItem.map((item) =>
|
||||
@ -369,15 +367,19 @@ export class GroupStore extends Base {
|
||||
}
|
||||
const [roleAssignmentsReault, groupResult, usersInGroup] =
|
||||
await Promise.all([
|
||||
request.get(`${this.apiVersion}/role_assignments`),
|
||||
request.get(`${this.apiVersion}/groups/${id}`),
|
||||
request.get(`${this.apiVersion}/groups/${id}/users`),
|
||||
this.roleAssignmentClient.list(),
|
||||
this.client.show(id),
|
||||
this.client.users.list(id),
|
||||
]);
|
||||
const originData = get(groupResult, this.responseKey) || groupResult;
|
||||
const { users } = usersInGroup;
|
||||
const userIds = users.map((user) => user.id);
|
||||
originData.users = userIds;
|
||||
originData.user_num = users.length;
|
||||
originData.user_info = users.map((user) => ({
|
||||
id: user.id,
|
||||
name: user.name,
|
||||
}));
|
||||
const group = this.mapperProject(roleAssignmentsReault, originData);
|
||||
this.detail = group;
|
||||
this.isLoading = false;
|
||||
@ -386,7 +388,7 @@ export class GroupStore extends Base {
|
||||
|
||||
@action
|
||||
async fetchGroupData() {
|
||||
const result = await request.get(this.getListUrl());
|
||||
const result = await this.client.list();
|
||||
const { groups } = result;
|
||||
return groups;
|
||||
}
|
||||
@ -404,9 +406,9 @@ export class GroupStore extends Base {
|
||||
const { roleId } = filters;
|
||||
const params = {};
|
||||
const [roleAssignmentsReault, projectResult, result] = await Promise.all([
|
||||
request.get(`${this.apiVersion}/role_assignments`),
|
||||
request.get(`${this.apiVersion}/projects`),
|
||||
request.get(this.getListUrl(), params),
|
||||
this.roleAssignmentClient.list(),
|
||||
this.projectClient.list(),
|
||||
this.client.list(params),
|
||||
]);
|
||||
const projectRoleUsers = {};
|
||||
const systemRoleUsers = {};
|
||||
@ -442,30 +444,35 @@ export class GroupStore extends Base {
|
||||
|
||||
// const items = data.map(this.mapper);
|
||||
// const newData = await this.listDidFetch(items);
|
||||
Promise.all(
|
||||
data.map((it) => request.get(`${this.apiVersion}/groups/${it.id}/users`))
|
||||
).then((rest) => {
|
||||
items.map((it, index) => {
|
||||
const { users } = rest[index];
|
||||
const userIds = users.map((user) => user.id);
|
||||
it.users = userIds;
|
||||
it.user_num = users.length;
|
||||
return it;
|
||||
});
|
||||
this.list.update({
|
||||
data: items,
|
||||
total: items.length || 0,
|
||||
limit: Number(limit) || 10,
|
||||
page: Number(page) || 1,
|
||||
sortKey,
|
||||
sortOrder,
|
||||
filters,
|
||||
isLoading: false,
|
||||
...(this.list.silent ? {} : { selectedRowKeys: [] }),
|
||||
});
|
||||
Promise.all(data.map((it) => this.client.users.list(it.id))).then(
|
||||
(rest) => {
|
||||
items.map((it, index) => {
|
||||
const { users } = rest[index];
|
||||
const userIds = users.map((user) => user.id);
|
||||
const userInfo = users.map((user) => ({
|
||||
id: user.id,
|
||||
name: user.name,
|
||||
}));
|
||||
it.users = userIds;
|
||||
it.user_num = users.length;
|
||||
it.user_info = userInfo;
|
||||
return it;
|
||||
});
|
||||
this.list.update({
|
||||
data: items,
|
||||
total: items.length || 0,
|
||||
limit: Number(limit) || 10,
|
||||
page: Number(page) || 1,
|
||||
sortKey,
|
||||
sortOrder,
|
||||
filters,
|
||||
isLoading: false,
|
||||
...(this.list.silent ? {} : { selectedRowKeys: [] }),
|
||||
});
|
||||
|
||||
return items;
|
||||
});
|
||||
return items;
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,12 +13,13 @@
|
||||
// limitations under the License.
|
||||
|
||||
import { action, observable } from 'mobx';
|
||||
import request from 'utils/request';
|
||||
import { keystoneBase } from 'utils/constants';
|
||||
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 globalGroupStore from './user-group';
|
||||
import Base from '../base';
|
||||
|
||||
export class UserStore extends Base {
|
||||
@observable
|
||||
@ -27,6 +28,12 @@ export class UserStore extends Base {
|
||||
@observable
|
||||
roleAssignments = [];
|
||||
|
||||
@observable
|
||||
userProjects = new List();
|
||||
|
||||
@observable
|
||||
userGroups = new List();
|
||||
|
||||
@observable
|
||||
projects = [];
|
||||
|
||||
@ -36,16 +43,36 @@ export class UserStore extends Base {
|
||||
@observable
|
||||
domainRoles = [];
|
||||
|
||||
get module() {
|
||||
return 'users';
|
||||
get client() {
|
||||
return client.keystone.users;
|
||||
}
|
||||
|
||||
get apiVersion() {
|
||||
return keystoneBase();
|
||||
get domainClient() {
|
||||
return client.keystone.domains;
|
||||
}
|
||||
|
||||
get responseKey() {
|
||||
return 'user';
|
||||
get systemGroupClient() {
|
||||
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
|
||||
@ -61,14 +88,10 @@ export class UserStore extends Base {
|
||||
const data = other;
|
||||
body[this.responseKey] = data;
|
||||
this.isSubmitting = true;
|
||||
const result = await request.post(this.getListUrl(), body);
|
||||
const result = await this.client.create(body);
|
||||
const {
|
||||
user: { id: user_id },
|
||||
} = result;
|
||||
// if (default_project_id) {
|
||||
// const url = `${this.apiVersion}/projects/${default_project_id}/users/${user_id}/roles/${adminId}`;
|
||||
// await request.put(url);
|
||||
// }
|
||||
const promiseList = [];
|
||||
if (select_user_group[0] || select_project[0]) {
|
||||
const newProjects = Object.keys(newProjectRoles);
|
||||
@ -99,7 +122,7 @@ export class UserStore extends Base {
|
||||
|
||||
@action
|
||||
async fetchDomain() {
|
||||
const doaminsResult = await request.get(`${this.apiVersion}/domains`);
|
||||
const doaminsResult = await this.domainClient.list();
|
||||
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
|
||||
getUserProjectRole = (user, roleAssignment, projectMapRole) => {
|
||||
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
|
||||
async fetchList({
|
||||
limit,
|
||||
@ -143,11 +211,13 @@ export class UserStore extends Base {
|
||||
} = {}) {
|
||||
this.list.isLoading = true;
|
||||
// todo: no page, no limit, fetch all
|
||||
const [roleAssignmentsReault, usersResult, roleResult] = await Promise.all([
|
||||
request.get(`${this.apiVersion}/role_assignments`),
|
||||
request.get(`${this.apiVersion}/users`),
|
||||
request.get(`${this.apiVersion}/roles`),
|
||||
]);
|
||||
const [roleAssignmentsReault, usersResult, roleResult, projectResult] =
|
||||
await Promise.all([
|
||||
this.roleAssignmentClient.list(),
|
||||
this.client.list(),
|
||||
this.roleClient.list(),
|
||||
this.projectClient.list(),
|
||||
]);
|
||||
const { users } = usersResult;
|
||||
const { roles } = roleResult;
|
||||
const systemRoles = roles.filter(
|
||||
@ -167,6 +237,11 @@ export class UserStore extends Base {
|
||||
systemRoleId,
|
||||
projectMapSystemRole
|
||||
);
|
||||
user.projectItems = this.getUserProjectWithRole(
|
||||
projectMapRole,
|
||||
roles,
|
||||
projectResult.projects
|
||||
);
|
||||
user.projects = projectMapRole;
|
||||
user.projectMapSystemRole = projectMapSystemRole;
|
||||
user.project_num = Object.keys(projectMapRole).length;
|
||||
@ -195,9 +270,9 @@ export class UserStore extends Base {
|
||||
this.isLoading = true;
|
||||
}
|
||||
const [roleAssignmentsReault, usersResult, roleResult] = await Promise.all([
|
||||
request.get(`${this.apiVersion}/role_assignments`),
|
||||
request.get(`${this.apiVersion}/users/${id}`),
|
||||
request.get(`${this.apiVersion}/roles`),
|
||||
this.roleAssignmentClient.list(),
|
||||
this.client.show(id),
|
||||
this.roleClient.list(),
|
||||
]);
|
||||
const { roles } = roleResult;
|
||||
const systemRoles = roles.filter(
|
||||
@ -241,43 +316,39 @@ export class UserStore extends Base {
|
||||
|
||||
@action
|
||||
async enable({ id }) {
|
||||
const url = `${this.apiVersion}/users/${id}`;
|
||||
const reqBody = {
|
||||
user: { enabled: true },
|
||||
};
|
||||
return this.submitting(request.patch(url, reqBody));
|
||||
return this.submitting(this.client.patch(id, reqBody));
|
||||
}
|
||||
|
||||
@action
|
||||
async forbidden({ id }) {
|
||||
const url = `${this.apiVersion}/users/${id}`;
|
||||
const reqBody = {
|
||||
user: { enabled: false },
|
||||
};
|
||||
return this.submitting(request.patch(url, reqBody));
|
||||
return this.submitting(this.client.patch(id, reqBody));
|
||||
}
|
||||
|
||||
@action
|
||||
async changePassword({ id, password }) {
|
||||
const url = `${this.apiVersion}/users/${id}`;
|
||||
const reqBody = {
|
||||
user: { password },
|
||||
};
|
||||
return this.submitting(request.patch(url, reqBody));
|
||||
return this.submitting(this.client.patch(id, reqBody));
|
||||
}
|
||||
|
||||
@action
|
||||
async changePasswordUser({ id, password, original_password }) {
|
||||
const url = `${this.apiVersion}/users/${id}/password`;
|
||||
const reqBody = {
|
||||
user: { password, original_password },
|
||||
};
|
||||
return this.submitting(request.post(url, reqBody));
|
||||
return this.submitting(this.client.updatePassword(id, reqBody));
|
||||
}
|
||||
|
||||
@action
|
||||
async fetchProject() {
|
||||
const projectsResult = await request.get(`${this.apiVersion}/projects`);
|
||||
const projectsResult = await this.projectClient.list();
|
||||
this.projects = projectsResult.projects;
|
||||
}
|
||||
|
||||
@ -285,9 +356,9 @@ export class UserStore extends Base {
|
||||
async fetchSystemRole({ id, projects }) {
|
||||
this.systemRoles = [];
|
||||
const project_id = projects[0].id;
|
||||
// const rolesResult = await request.get(`${this.apiVersion}/system/users/${id}/roles`);
|
||||
const projectResult = await request.get(
|
||||
`${this.apiVersion}/projects/${project_id}/users/${id}/roles/`
|
||||
const projectResult = await this.projectClient.users.roles.list(
|
||||
project_id,
|
||||
id
|
||||
);
|
||||
const systemRole = projectResult.roles.filter(
|
||||
(it) => it.name.includes('system_') && !it.name.includes('_system_')
|
||||
@ -297,48 +368,33 @@ export class UserStore extends Base {
|
||||
|
||||
@action
|
||||
async assignSystemRole({ id, role_id }) {
|
||||
const result = request.put(
|
||||
`${this.apiVersion}/system/users/${id}/roles/${role_id}`
|
||||
);
|
||||
return result;
|
||||
return this.systemUserClient.roles.update(id, role_id);
|
||||
}
|
||||
|
||||
@action
|
||||
async deleteSystemRole({ id, role_id }) {
|
||||
const result = request.delete(
|
||||
`${this.apiVersion}/system/users/${id}/roles/${role_id}`
|
||||
);
|
||||
return result;
|
||||
return this.systemUserClient.delete(id, role_id);
|
||||
}
|
||||
|
||||
@action
|
||||
async fetchDomainRole({ id, domain_id }) {
|
||||
this.domainRoles = [];
|
||||
const rolesResult = await request.get(
|
||||
`${this.apiVersion}/domains/${domain_id}/users/${id}/roles`
|
||||
);
|
||||
const rolesResult = await this.domainClient.users.roles.list(id, domain_id);
|
||||
this.domainRoles = rolesResult.roles;
|
||||
}
|
||||
|
||||
@action
|
||||
async assignDomainRole({ id, role_id, domain_id }) {
|
||||
const result = request.put(
|
||||
`${this.apiVersion}/domains/${domain_id}/users/${id}/roles/${role_id}`
|
||||
);
|
||||
return result;
|
||||
return this.domainClient.users.roles.update(domain_id, id, role_id);
|
||||
}
|
||||
|
||||
@action
|
||||
async deleteDomainRole({ id, role_id, domain_id }) {
|
||||
const result = request.delete(
|
||||
`${this.apiVersion}/domains/${domain_id}/users/${id}/roles/${role_id}`
|
||||
);
|
||||
return result;
|
||||
return this.domainClient.users.roles.delete(domain_id, id, role_id);
|
||||
}
|
||||
|
||||
@action
|
||||
async edit(id, { email, phone, real_name, description, name }) {
|
||||
const url = `${this.apiVersion}/users/${id}`;
|
||||
const reqBody = {
|
||||
user: {
|
||||
email,
|
||||
@ -348,7 +404,7 @@ export class UserStore extends Base {
|
||||
name,
|
||||
},
|
||||
};
|
||||
return this.submitting(request.patch(url, reqBody));
|
||||
return this.submitting(this.client.patch(id, reqBody));
|
||||
}
|
||||
|
||||
@action
|
||||
@ -363,36 +419,34 @@ export class UserStore extends Base {
|
||||
this.list.isLoading = true;
|
||||
const { domainId } = filters;
|
||||
const params = {};
|
||||
const result = await request.get(this.getListUrl(), params);
|
||||
const result = await this.client.list(params);
|
||||
let data = get(result, this.listResponseKey, []);
|
||||
data = data.filter((it) => it.domain_id === domainId);
|
||||
const items = data.map(this.mapper);
|
||||
const newData = await this.listDidFetch(items);
|
||||
Promise.all(
|
||||
newData.map((it) =>
|
||||
request.get(`${this.apiVersion}/users/${it.id}/projects`)
|
||||
)
|
||||
).then((projectResult) => {
|
||||
newData.map((it, index) => {
|
||||
const { projects } = projectResult[index];
|
||||
it.projects = projects;
|
||||
it.project_num = projects.length;
|
||||
return it;
|
||||
});
|
||||
this.list.update({
|
||||
data: newData,
|
||||
total: items.length || 0,
|
||||
limit: Number(limit) || 10,
|
||||
page: Number(page) || 1,
|
||||
sortKey,
|
||||
sortOrder,
|
||||
filters,
|
||||
isLoading: false,
|
||||
...(this.list.silent ? {} : { selectedRowKeys: [] }),
|
||||
});
|
||||
Promise.all(newData.map((it) => this.client.projects.list(it.id))).then(
|
||||
(projectResult) => {
|
||||
newData.map((it, index) => {
|
||||
const { projects } = projectResult[index];
|
||||
it.projects = projects;
|
||||
it.project_num = projects.length;
|
||||
return it;
|
||||
});
|
||||
this.list.update({
|
||||
data: newData,
|
||||
total: items.length || 0,
|
||||
limit: Number(limit) || 10,
|
||||
page: Number(page) || 1,
|
||||
sortKey,
|
||||
sortOrder,
|
||||
filters,
|
||||
isLoading: false,
|
||||
...(this.list.silent ? {} : { selectedRowKeys: [] }),
|
||||
});
|
||||
|
||||
return items;
|
||||
});
|
||||
return items;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@action
|
||||
@ -408,9 +462,9 @@ export class UserStore extends Base {
|
||||
const { projectId } = filters;
|
||||
const params = {};
|
||||
const [roleAssignmentsReault, roleResult, result] = await Promise.all([
|
||||
request.get(`${this.apiVersion}/role_assignments`),
|
||||
request.get(`${this.apiVersion}/roles`),
|
||||
request.get(this.getListUrl(), params),
|
||||
this.roleAssignmentClient.list(),
|
||||
this.roleClient.list(),
|
||||
this.client.list(params),
|
||||
]);
|
||||
const projectUserIds = [];
|
||||
const userMapRole = {};
|
||||
@ -435,34 +489,32 @@ export class UserStore extends Base {
|
||||
data = data.filter((it) => projectUserIds.includes(it.id));
|
||||
const items = data.map(this.mapper);
|
||||
const newData = await this.listDidFetch(items);
|
||||
Promise.all(
|
||||
newData.map((it) =>
|
||||
request.get(`${this.apiVersion}/users/${it.id}/projects`)
|
||||
)
|
||||
).then((projectResult) => {
|
||||
newData.map((it, index) => {
|
||||
const { projects } = projectResult[index];
|
||||
it.projects = projects;
|
||||
it.project_num = projects.length;
|
||||
it.project_roles = userMapRole[it.id].map(
|
||||
(r) => roleResult.roles.filter((role) => role.id === r)[0].name
|
||||
);
|
||||
return it;
|
||||
});
|
||||
this.list.update({
|
||||
data: newData,
|
||||
total: items.length || 0,
|
||||
limit: Number(limit) || 10,
|
||||
page: Number(page) || 1,
|
||||
sortKey,
|
||||
sortOrder,
|
||||
filters,
|
||||
isLoading: false,
|
||||
...(this.list.silent ? {} : { selectedRowKeys: [] }),
|
||||
});
|
||||
Promise.all(newData.map((it) => this.client.projects.list(it.id))).then(
|
||||
(projectResult) => {
|
||||
newData.map((it, index) => {
|
||||
const { projects } = projectResult[index];
|
||||
it.projects = projects;
|
||||
it.project_num = projects.length;
|
||||
it.project_roles = userMapRole[it.id].map(
|
||||
(r) => roleResult.roles.filter((role) => role.id === r)[0].name
|
||||
);
|
||||
return it;
|
||||
});
|
||||
this.list.update({
|
||||
data: newData,
|
||||
total: items.length || 0,
|
||||
limit: Number(limit) || 10,
|
||||
page: Number(page) || 1,
|
||||
sortKey,
|
||||
sortOrder,
|
||||
filters,
|
||||
isLoading: false,
|
||||
...(this.list.silent ? {} : { selectedRowKeys: [] }),
|
||||
});
|
||||
|
||||
return items;
|
||||
});
|
||||
return items;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@action
|
||||
@ -477,38 +529,33 @@ export class UserStore extends Base {
|
||||
this.list.isLoading = true;
|
||||
const { groupId } = filters;
|
||||
const params = {};
|
||||
const result = await request.get(
|
||||
`${this.apiVersion}/groups/${groupId}/users`,
|
||||
params
|
||||
);
|
||||
const result = await this.groupClient.users.list(groupId, params);
|
||||
const data = get(result, this.listResponseKey, []);
|
||||
const items = data.map(this.mapper);
|
||||
const newData = await this.listDidFetch(items);
|
||||
Promise.all(
|
||||
newData.map((it) =>
|
||||
request.get(`${this.apiVersion}/users/${it.id}/projects`)
|
||||
)
|
||||
).then((projectResult) => {
|
||||
newData.map((it, index) => {
|
||||
const { projects } = projectResult[index];
|
||||
it.projects = projects;
|
||||
it.project_num = projects.length;
|
||||
return it;
|
||||
});
|
||||
this.list.update({
|
||||
data: newData,
|
||||
total: items.length || 0,
|
||||
limit: Number(limit) || 10,
|
||||
page: Number(page) || 1,
|
||||
sortKey,
|
||||
sortOrder,
|
||||
filters,
|
||||
isLoading: false,
|
||||
...(this.list.silent ? {} : { selectedRowKeys: [] }),
|
||||
});
|
||||
Promise.all(newData.map((it) => this.client.projects.list(it.id))).then(
|
||||
(projectResult) => {
|
||||
newData.map((it, index) => {
|
||||
const { projects } = projectResult[index];
|
||||
it.projects = projects;
|
||||
it.project_num = projects.length;
|
||||
return it;
|
||||
});
|
||||
this.list.update({
|
||||
data: newData,
|
||||
total: items.length || 0,
|
||||
limit: Number(limit) || 10,
|
||||
page: Number(page) || 1,
|
||||
sortKey,
|
||||
sortOrder,
|
||||
filters,
|
||||
isLoading: false,
|
||||
...(this.list.silent ? {} : { selectedRowKeys: [] }),
|
||||
});
|
||||
|
||||
return items;
|
||||
});
|
||||
return items;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@action
|
||||
@ -524,9 +571,9 @@ export class UserStore extends Base {
|
||||
const { roleId } = filters;
|
||||
const params = {};
|
||||
const [roleAssignmentsReault, projectResult, result] = await Promise.all([
|
||||
request.get(`${this.apiVersion}/role_assignments`),
|
||||
request.get(`${this.apiVersion}/projects`),
|
||||
request.get(this.getListUrl(), params),
|
||||
this.roleAssignmentClient.list(),
|
||||
this.projectClient.list(),
|
||||
this.client.list(params),
|
||||
]);
|
||||
const projectRoleUsers = {};
|
||||
const systemRoleUsers = {};
|
||||
@ -542,9 +589,9 @@ export class UserStore extends Base {
|
||||
(it) => it.id === project.id
|
||||
);
|
||||
if (projectRoleUsers[user_id]) {
|
||||
projectRoleUsers[user_id].push(projectData.name);
|
||||
projectRoleUsers[user_id].push(projectData);
|
||||
} else {
|
||||
projectRoleUsers[user_id] = [projectData.name];
|
||||
projectRoleUsers[user_id] = [projectData];
|
||||
}
|
||||
} else if (role_id === roleId && system) {
|
||||
systemRoleUsers[user_id] = system.all;
|
||||
@ -555,7 +602,7 @@ export class UserStore extends Base {
|
||||
const items = data
|
||||
.filter((it) => projectRoleUsers[it.id] || systemRoleUsers[it.id])
|
||||
.map((it) => ({
|
||||
projectScope: projectRoleUsers[it.id] || [],
|
||||
projects: projectRoleUsers[it.id] || [],
|
||||
systemScope: systemRoleUsers[it.id] || [],
|
||||
...it,
|
||||
}));
|
||||
|
@ -13,30 +13,34 @@
|
||||
// limitations under the License.
|
||||
|
||||
import { action } from 'mobx';
|
||||
import { neutronBase } from 'utils/constants';
|
||||
import client from 'client';
|
||||
import { isArray } from 'lodash';
|
||||
import Base from '../base';
|
||||
|
||||
export class NeutronAgentNetworkStore extends Base {
|
||||
get module() {
|
||||
return 'networks';
|
||||
get client() {
|
||||
return client.neutron.agents.dhcpNetworks;
|
||||
}
|
||||
|
||||
get apiVersion() {
|
||||
return neutronBase();
|
||||
get isSubResource() {
|
||||
return true;
|
||||
}
|
||||
|
||||
get responseKey() {
|
||||
return 'network';
|
||||
}
|
||||
getFatherResourceId = (params) => params.agentId;
|
||||
|
||||
get listFilterByProject() {
|
||||
return true;
|
||||
}
|
||||
|
||||
getListUrl = ({ agentId }) =>
|
||||
`${this.apiVersion}/agents/${agentId}/dhcp-networks`;
|
||||
|
||||
getDetailUrl = ({ agentId, id }) => `${this.getListUrl({ agentId })}/${id}`;
|
||||
get mapper() {
|
||||
return (data) => {
|
||||
const { created_at } = data;
|
||||
return {
|
||||
...data,
|
||||
standard_attr_id: created_at,
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
async listDidFetch(items, allProjects, filters) {
|
||||
const { agentId } = filters;
|
||||
@ -48,11 +52,16 @@ export class NeutronAgentNetworkStore extends Base {
|
||||
|
||||
@action
|
||||
remove = ({ agentId, id }) =>
|
||||
this.submitting(request.delete(this.getDetailUrl({ agentId, id })));
|
||||
this.submitting(this.client.delete(agentId, id));
|
||||
|
||||
@action
|
||||
add = ({ agentId }, body) =>
|
||||
this.submitting(request.post(this.getListUrl({ agentId }), body));
|
||||
add = ({ 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();
|
||||
|
@ -13,34 +13,28 @@
|
||||
// limitations under the License.
|
||||
|
||||
import { action } from 'mobx';
|
||||
import { neutronBase } from 'utils/constants';
|
||||
import client from 'client';
|
||||
import { isArray } from 'lodash';
|
||||
import Base from '../base';
|
||||
|
||||
export class NeutronAgentRouterStore extends Base {
|
||||
get module() {
|
||||
return 'routers';
|
||||
}
|
||||
|
||||
get apiVersion() {
|
||||
return neutronBase();
|
||||
}
|
||||
|
||||
get responseKey() {
|
||||
return 'router';
|
||||
get client() {
|
||||
return client.neutron.agents.l3Routers;
|
||||
}
|
||||
|
||||
get listFilterByProject() {
|
||||
return true;
|
||||
}
|
||||
|
||||
getListUrl = ({ agentId }) =>
|
||||
`${this.apiVersion}/agents/${agentId}/l3-routers`;
|
||||
get isSubResource() {
|
||||
return true;
|
||||
}
|
||||
|
||||
getDetailUrl = ({ agentId, id }) => `${this.getListUrl({ agentId })}/${id}`;
|
||||
getFatherResourceId = (params) => params.agentId;
|
||||
|
||||
get mapper() {
|
||||
return (data) => {
|
||||
const externalGateway = data.external_gateway_info;
|
||||
const { external_gateway_info: externalGateway, created_at } = data || {};
|
||||
return {
|
||||
...data,
|
||||
hasExternalGateway: !!externalGateway,
|
||||
@ -50,6 +44,7 @@ export class NeutronAgentRouterStore extends Base {
|
||||
(externalGateway && externalGateway.network_name) || '',
|
||||
externalFixedIps:
|
||||
(externalGateway && externalGateway.external_fixed_ips) || [],
|
||||
standard_attr_id: created_at,
|
||||
};
|
||||
};
|
||||
}
|
||||
@ -64,11 +59,16 @@ export class NeutronAgentRouterStore extends Base {
|
||||
|
||||
@action
|
||||
remove = ({ agentId, id }) =>
|
||||
this.submitting(request.delete(this.getDetailUrl({ agentId, id })));
|
||||
this.submitting(this.client.delete(agentId, id));
|
||||
|
||||
@action
|
||||
add = ({ agentId }, body) =>
|
||||
this.submitting(request.post(this.getListUrl({ agentId }), body));
|
||||
add = ({ 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();
|
||||
|
@ -12,20 +12,12 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { neutronBase } from 'utils/constants';
|
||||
import client from 'client';
|
||||
import Base from '../base';
|
||||
|
||||
export class NeutronAgentStore extends Base {
|
||||
get module() {
|
||||
return 'agents';
|
||||
}
|
||||
|
||||
get apiVersion() {
|
||||
return neutronBase();
|
||||
}
|
||||
|
||||
get responseKey() {
|
||||
return 'agent';
|
||||
get client() {
|
||||
return client.neutron.agents;
|
||||
}
|
||||
|
||||
get listFilterByProject() {
|
||||
|
@ -12,26 +12,25 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import { neutronBase } from 'utils/constants';
|
||||
import globalNetworkStore from 'stores/neutron/network';
|
||||
import globalFloatingIpsStore from 'stores/neutron/floatingIp';
|
||||
import client from 'client';
|
||||
import Base from '../base';
|
||||
|
||||
export class FixedIpStore extends Base {
|
||||
get module() {
|
||||
return 'ports';
|
||||
get client() {
|
||||
return client.neutron.ports;
|
||||
}
|
||||
|
||||
get apiVersion() {
|
||||
return neutronBase();
|
||||
get paramsFunc() {
|
||||
return ({ all_projects, ...rest }) => rest;
|
||||
}
|
||||
|
||||
get listResponseKey() {
|
||||
return 'ports';
|
||||
}
|
||||
|
||||
async getItemFloatingIPs(fixed_ip) {
|
||||
return globalFloatingIpsStore.pureFetchList({ fixed_ip_address: fixed_ip });
|
||||
async getItemFloatingIPs(fixed_ip, portId) {
|
||||
return globalFloatingIpsStore.pureFetchList({
|
||||
fixed_ip_address: fixed_ip,
|
||||
port_id: portId,
|
||||
});
|
||||
}
|
||||
|
||||
async listDidFetch(items) {
|
||||
@ -39,7 +38,7 @@ export class FixedIpStore extends Base {
|
||||
return [];
|
||||
}
|
||||
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 subnetResults = await Promise.all(
|
||||
subnets.map((item) => globalNetworkStore.fetchSubnetDetail({ id: item }))
|
||||
@ -49,7 +48,7 @@ export class FixedIpStore extends Base {
|
||||
subnetMap[result.id] = result;
|
||||
});
|
||||
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) => ({
|
||||
...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