feat: support trove quota

1. support trove quota in manage project quota
2. support trove quota in overview page

Change-Id: Iac2ea282744239fc043df2bdc456b7daba05de9b
This commit is contained in:
xusongfu 2022-07-22 12:41:43 +08:00
parent 70fd56a9b1
commit e16951bde0
7 changed files with 110 additions and 2 deletions

View File

@ -108,6 +108,11 @@ export class TroveClient extends Base {
}, },
], ],
}, },
{
name: 'quotas',
key: 'mgmt/quotas',
responseKey: 'quota',
},
]; ];
} }
} }

View File

@ -433,6 +433,7 @@
"Container Stopping": "Container Stopping", "Container Stopping": "Container Stopping",
"Container Version": "Container Version", "Container Version": "Container Version",
"Containers": "Containers", "Containers": "Containers",
"Containers Disk (GiB)": "Containers Disk (GiB)",
"Containers Info": "Containers Info", "Containers Info": "Containers Info",
"Containers Management": "Containers Management", "Containers Management": "Containers Management",
"Content": "Content", "Content": "Content",
@ -593,6 +594,7 @@
"Data Source Type": "Data Source Type", "Data Source Type": "Data Source Type",
"Database": "Database", "Database": "Database",
"Database Backup Detail": "Database Backup Detail", "Database Backup Detail": "Database Backup Detail",
"Database Disk (GiB)": "Database Disk (GiB)",
"Database Flavor": "Database Flavor", "Database Flavor": "Database Flavor",
"Database Instance": "Database Instance", "Database Instance": "Database Instance",
"Database Instance Detail": "Database Instance Detail", "Database Instance Detail": "Database Instance Detail",

View File

@ -433,6 +433,7 @@
"Container Stopping": "容器关闭中", "Container Stopping": "容器关闭中",
"Container Version": "容器版本", "Container Version": "容器版本",
"Containers": "容器", "Containers": "容器",
"Containers Disk (GiB)": "容器硬盘 (GiB)",
"Containers Info": "容器信息", "Containers Info": "容器信息",
"Containers Management": "容器管理", "Containers Management": "容器管理",
"Content": "内容", "Content": "内容",
@ -593,6 +594,7 @@
"Data Source Type": "数据源类型", "Data Source Type": "数据源类型",
"Database": "数据库", "Database": "数据库",
"Database Backup Detail": "数据库备份详情", "Database Backup Detail": "数据库备份详情",
"Database Disk (GiB)": "数据库硬盘 (GiB)",
"Database Flavor": "数据库实例类型", "Database Flavor": "数据库实例类型",
"Database Instance": "数据库实例", "Database Instance": "数据库实例",
"Database Instance Detail": "数据库实例详情", "Database Instance Detail": "数据库实例详情",

View File

@ -114,7 +114,22 @@ export const zunQuotaCard = {
}, },
{ text: t('CPUs'), key: 'zun_cpu' }, { text: t('CPUs'), key: 'zun_cpu' },
{ text: t('Memory (MiB)'), key: 'zun_memory' }, { text: t('Memory (MiB)'), key: 'zun_memory' },
{ text: t('Disk (GiB)'), key: 'zun_disk' }, { text: t('Containers Disk (GiB)'), key: 'zun_disk' },
],
};
export const troveQuotaCard = {
text: t('Database'),
type: 'trove',
value: [
{
text: t('Database Instance'),
key: 'trove_instances',
},
{
text: t('Database Disk (GiB)'),
key: 'trove_volumes',
},
], ],
}; };
@ -195,6 +210,12 @@ export class QuotaOverview extends Component {
return globalRootStore.checkEndpoint('zun'); return globalRootStore.checkEndpoint('zun');
} }
get enableTrove() {
return (
globalRootStore.checkEndpoint('trove') && globalRootStore.hasAdminOnlyRole
);
}
get volumeTypeData() { get volumeTypeData() {
const { volumeTypeData } = this.props; const { volumeTypeData } = this.props;
return volumeTypeData || this.volumeTypeStore.list.data; return volumeTypeData || this.volumeTypeStore.list.data;
@ -216,6 +237,9 @@ export class QuotaOverview extends Component {
if (this.enableZun) { if (this.enableZun) {
newList.push(zunQuotaCard); newList.push(zunQuotaCard);
} }
if (this.enableTrove) {
newList.push(troveQuotaCard);
}
return newList; return newList;
} }

View File

@ -22,6 +22,7 @@ import {
getVolumeTypeCards, getVolumeTypeCards,
shareQuotaCard, shareQuotaCard,
zunQuotaCard, zunQuotaCard,
troveQuotaCard,
} from 'pages/base/containers/Overview/components/QuotaOverview'; } from 'pages/base/containers/Overview/components/QuotaOverview';
export class ManageQuota extends ModalAction { export class ManageQuota extends ModalAction {
@ -52,6 +53,13 @@ export class ManageQuota extends ModalAction {
return this.props.rootStore.checkEndpoint('zun'); return this.props.rootStore.checkEndpoint('zun');
} }
get enableTrove() {
return (
this.props.rootStore.checkEndpoint('trove') &&
this.props.rootStore.hasAdminOnlyRole
);
}
async getData() { async getData() {
const { id: project_id } = this.item; const { id: project_id } = this.item;
const promiseArr = [ const promiseArr = [
@ -142,6 +150,9 @@ export class ManageQuota extends ModalAction {
if (this.enableZun) { if (this.enableZun) {
newQuotaCardList.push(zunQuotaCard); newQuotaCardList.push(zunQuotaCard);
} }
if (this.enableTrove) {
newQuotaCardList.push(troveQuotaCard);
}
return newQuotaCardList; return newQuotaCardList;
} }
@ -196,6 +207,9 @@ export class ManageQuota extends ModalAction {
if (this.enableZun) { if (this.enableZun) {
form.push(...this.getFormItemsByCards('zun')); form.push(...this.getFormItemsByCards('zun'));
} }
if (this.enableTrove) {
form.push(...this.getFormItemsByCards('trove'));
}
if (this.enableCinder) { if (this.enableCinder) {
const cinderFormItems = this.getFormItemsByCards('storage'); const cinderFormItems = this.getFormItemsByCards('storage');
const volumeTypeFormItems = this.getVolumeTypeFormItems(); const volumeTypeFormItems = this.getVolumeTypeFormItems();

View File

@ -39,6 +39,9 @@ export class ProjectStore extends Base {
@observable @observable
zunQuota = {}; zunQuota = {};
@observable
troveQuota = {};
@observable @observable
groupRoleList = []; groupRoleList = [];
@ -82,6 +85,10 @@ export class ProjectStore extends Base {
return client.zun.quotas; return client.zun.quotas;
} }
get troveQuotaClient() {
return client.trove.quotas;
}
listFetchByClient(params, originParams) { listFetchByClient(params, originParams) {
const { userId } = originParams; const { userId } = originParams;
if (userId) { if (userId) {
@ -213,6 +220,12 @@ export class ProjectStore extends Base {
return globalRootStore.checkEndpoint('zun'); return globalRootStore.checkEndpoint('zun');
} }
get enableTrove() {
return (
globalRootStore.checkEndpoint('trove') && globalRootStore.hasAdminOnlyRole
);
}
@action @action
async enable({ id }) { async enable({ id }) {
const reqBody = { const reqBody = {
@ -266,6 +279,9 @@ export class ProjectStore extends Base {
}) })
: null : null
); );
promiseArr.push(
this.enableTrove ? this.troveQuotaClient.show(project_id) : null
);
promiseArr.push(withKeyPair ? globalKeypairStore.fetchList() : null); promiseArr.push(withKeyPair ? globalKeypairStore.fetchList() : null);
const [ const [
novaResult, novaResult,
@ -273,6 +289,7 @@ export class ProjectStore extends Base {
cinderResult, cinderResult,
shareResult, shareResult,
zunResult, zunResult,
troveResult,
keyPairResult, keyPairResult,
] = await Promise.all(promiseArr); ] = await Promise.all(promiseArr);
this.isSubmitting = false; this.isSubmitting = false;
@ -281,6 +298,7 @@ export class ProjectStore extends Base {
const { quota: neutronQuota } = neutronResult; const { quota: neutronQuota } = neutronResult;
const { quota_set: shareQuota = {} } = shareResult || {}; const { quota_set: shareQuota = {} } = shareResult || {};
const zunQuota = zunResult || {}; const zunQuota = zunResult || {};
const { quotas: troveQuota = [] } = troveResult || {};
this.updateNovaQuota(novaQuota); this.updateNovaQuota(novaQuota);
const renameShareQuota = Object.keys(shareQuota).reduce((pre, cur) => { const renameShareQuota = Object.keys(shareQuota).reduce((pre, cur) => {
const key = !cur.includes('share') ? `share_${cur}` : cur; const key = !cur.includes('share') ? `share_${cur}` : cur;
@ -292,12 +310,18 @@ export class ProjectStore extends Base {
pre[key] = zunQuota[cur]; pre[key] = zunQuota[cur];
return pre; return pre;
}, {}); }, {});
const renameTroveQuota = troveQuota.reduce((pre, cur) => {
const key = `trove_${cur.resource}`;
pre[key] = cur;
return pre;
}, {});
const quota = { const quota = {
...novaQuota, ...novaQuota,
...cinderQuota, ...cinderQuota,
...neutronQuota, ...neutronQuota,
...renameShareQuota, ...renameShareQuota,
...renameZunQuota, ...renameZunQuota,
...renameTroveQuota,
}; };
if (withKeyPair) { if (withKeyPair) {
const keyPairCount = (keyPairResult || []).length; const keyPairCount = (keyPairResult || []).length;
@ -353,7 +377,8 @@ export class ProjectStore extends Base {
(key.includes('volumes') || (key.includes('volumes') ||
key.includes('gigabytes') || key.includes('gigabytes') ||
key.includes('snapshots')) && key.includes('snapshots')) &&
!key.includes('share') !key.includes('share') &&
!key.includes('trove')
) { ) {
rest[key] = others[key]; rest[key] = others[key];
} }
@ -421,12 +446,27 @@ export class ProjectStore extends Base {
return zunReqBody; return zunReqBody;
} }
getTroveQuotaBody(data) {
if (!this.enableTrove) {
return {};
}
const { trove_instances, trove_volumes } = data;
const troveReqBody = this.omitNil({
quotas: {
instances: trove_instances,
volumes: trove_volumes,
},
});
return troveReqBody;
}
async updateQuota(project_id, data) { async updateQuota(project_id, data) {
const novaReqBody = this.getNovaQuotaBody(data); const novaReqBody = this.getNovaQuotaBody(data);
const cinderReqBody = this.getCinderQuotaBody(data); const cinderReqBody = this.getCinderQuotaBody(data);
const neutronReqBody = this.getNeutronQuotaBody(data); const neutronReqBody = this.getNeutronQuotaBody(data);
const shareReqBody = this.getShareQuotaBody(data); const shareReqBody = this.getShareQuotaBody(data);
const zunReqBody = this.getZunQuotaBody(data); const zunReqBody = this.getZunQuotaBody(data);
const troveReqBody = this.getTroveQuotaBody(data);
const reqs = []; const reqs = [];
if (!isEmpty(novaReqBody.quota_set)) { if (!isEmpty(novaReqBody.quota_set)) {
reqs.push(client.nova.quotaSets.update(project_id, novaReqBody)); reqs.push(client.nova.quotaSets.update(project_id, novaReqBody));
@ -443,6 +483,9 @@ export class ProjectStore extends Base {
if (!isEmpty(zunReqBody)) { if (!isEmpty(zunReqBody)) {
reqs.push(client.zun.quotas.update(project_id, zunReqBody)); reqs.push(client.zun.quotas.update(project_id, zunReqBody));
} }
if (!isEmpty(troveReqBody)) {
reqs.push(client.trove.quotas.update(project_id, troveReqBody));
}
const result = await Promise.all(reqs); const result = await Promise.all(reqs);
return result; return result;
} }
@ -581,6 +624,20 @@ export class ProjectStore extends Base {
this.zunQuota = zunQuota; this.zunQuota = zunQuota;
return zunQuota; return zunQuota;
} }
@action
async fetchProjectTroveQuota(projectId) {
const { quotas = [] } = await this.troveQuotaClient.show(
projectId || this.currentProjectId
);
const quotasObject = quotas.reduce((pre, cur) => {
pre[cur.resource] = cur;
return pre;
}, {});
const troveQuota = this.updateQuotaData(quotasObject);
this.troveQuota = troveQuota;
return troveQuota;
}
} }
const globalProjectStore = new ProjectStore(); const globalProjectStore = new ProjectStore();

View File

@ -48,6 +48,9 @@ export class RootStore {
@observable @observable
hasAdminPageRole = false; hasAdminPageRole = false;
@observable
hasAdminOnlyRole = false;
@observable @observable
openKeys = []; openKeys = [];
@ -135,6 +138,7 @@ export class RootStore {
this.baseDomains = base_domains; this.baseDomains = base_domains;
this.hasAdminPageRole = await this.getUserSystemRoles(userInfo); this.hasAdminPageRole = await this.getUserSystemRoles(userInfo);
this.hasAdminRole = this.hasAdminPageRole; this.hasAdminRole = this.hasAdminPageRole;
this.hasAdminOnlyRole = roles.some((it) => it.name === 'admin');
} }
@action @action