feat: support zun quota in manage project quota and overview

1. Support manage zun quota
2. Show zun quota in overview

Change-Id: I18fa243ca4133be1a4592189ef287db44f4cc66d
This commit is contained in:
xusongfu 2022-07-11 10:22:12 +08:00
parent 15d5998e11
commit 3666358c95
7 changed files with 116 additions and 5 deletions

View File

@ -83,6 +83,7 @@ export const qosEndpoint = () => getOriginEndpoint('neutron_qos');
export const swiftEndpoint = () => getOriginEndpoint('swift'); export const swiftEndpoint = () => getOriginEndpoint('swift');
export const cinderEndpoint = () => getOriginEndpoint('cinder'); export const cinderEndpoint = () => getOriginEndpoint('cinder');
export const manilaEndpoint = () => getOriginEndpoint('manilav2'); export const manilaEndpoint = () => getOriginEndpoint('manilav2');
export const zunEndpoint = () => getOriginEndpoint('zun');
export const apiVersionMaps = { export const apiVersionMaps = {
nova: { nova: {

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
import { zunBase } from 'client/client/constants'; import { zunBase, zunEndpoint } from 'client/client/constants';
import Base from '../client/base'; import Base from '../client/base';
export class ZunClient extends Base { export class ZunClient extends Base {
@ -20,6 +20,10 @@ export class ZunClient extends Base {
return zunBase(); return zunBase();
} }
get enable() {
return !!zunEndpoint();
}
get resources() { get resources() {
return [ return [
{ {
@ -71,6 +75,10 @@ export class ZunClient extends Base {
key: 'hosts', key: 'hosts',
responseKey: 'host', responseKey: 'host',
}, },
{
name: 'quotas',
key: 'quotas',
},
]; ];
} }
} }

View File

@ -429,6 +429,7 @@
"Container Version": "Container Version", "Container Version": "Container Version",
"Containers": "Containers", "Containers": "Containers",
"Containers Info": "Containers Info", "Containers Info": "Containers Info",
"Containers Management": "Containers Management",
"Content": "Content", "Content": "Content",
"Content Type": "Content Type", "Content Type": "Content Type",
"Control Location": "Control Location", "Control Location": "Control Location",
@ -716,6 +717,7 @@
"Disconnect Subnet": "Disconnect Subnet", "Disconnect Subnet": "Disconnect Subnet",
"Discovery URL": "Discovery URL", "Discovery URL": "Discovery URL",
"Disk": "Disk", "Disk": "Disk",
"Disk (GiB)": "Disk (GiB)",
"Disk Format": "Disk Format", "Disk Format": "Disk Format",
"Disk Info": "Disk Info", "Disk Info": "Disk Info",
"Disk Tag": "Disk Tag", "Disk Tag": "Disk Tag",

View File

@ -429,6 +429,7 @@
"Container Version": "容器版本", "Container Version": "容器版本",
"Containers": "容器", "Containers": "容器",
"Containers Info": "容器信息", "Containers Info": "容器信息",
"Containers Management": "容器管理",
"Content": "内容", "Content": "内容",
"Content Type": "内容类型", "Content Type": "内容类型",
"Control Location": "控制端", "Control Location": "控制端",
@ -716,6 +717,7 @@
"Disconnect Subnet": "断开子网", "Disconnect Subnet": "断开子网",
"Discovery URL": "发现网址", "Discovery URL": "发现网址",
"Disk": "硬盘", "Disk": "硬盘",
"Disk (GiB)": "硬盘 (GiB)",
"Disk Format": "硬盘格式", "Disk Format": "硬盘格式",
"Disk Info": "硬盘信息", "Disk Info": "硬盘信息",
"Disk Tag": "硬盘标签", "Disk Tag": "硬盘标签",

View File

@ -104,6 +104,20 @@ export const shareQuotaCard = {
], ],
}; };
export const zunQuotaCard = {
text: t('Containers Management'),
type: 'zun',
value: [
{
text: t('Containers'),
key: 'zun_containers',
},
{ text: t('CPU'), key: 'zun_cpu' },
{ text: t('Memory (MiB)'), key: 'zun_memory' },
{ text: t('Disk (GiB)'), key: 'zun_disk' },
],
};
export const getVolumeTypeCards = (data) => { export const getVolumeTypeCards = (data) => {
const value = data.map((item, index) => { const value = data.map((item, index) => {
return { return {
@ -177,6 +191,10 @@ export class QuotaOverview extends Component {
return globalRootStore.checkEndpoint('manilav2'); return globalRootStore.checkEndpoint('manilav2');
} }
get enableZun() {
return globalRootStore.checkEndpoint('zun');
}
get volumeTypeData() { get volumeTypeData() {
const { volumeTypeData } = this.props; const { volumeTypeData } = this.props;
return volumeTypeData || this.volumeTypeStore.list.data; return volumeTypeData || this.volumeTypeStore.list.data;
@ -195,6 +213,9 @@ export class QuotaOverview extends Component {
if (this.enableShare) { if (this.enableShare) {
newList.push(shareQuotaCard); newList.push(shareQuotaCard);
} }
if (this.enableZun) {
newList.push(zunQuotaCard);
}
return newList; return newList;
} }

View File

@ -21,6 +21,7 @@ import {
quotaCardList, quotaCardList,
getVolumeTypeCards, getVolumeTypeCards,
shareQuotaCard, shareQuotaCard,
zunQuotaCard,
} from 'pages/base/containers/Overview/components/QuotaOverview'; } from 'pages/base/containers/Overview/components/QuotaOverview';
export class ManageQuota extends ModalAction { export class ManageQuota extends ModalAction {
@ -47,6 +48,10 @@ export class ManageQuota extends ModalAction {
return this.props.rootStore.checkEndpoint('manilav2'); return this.props.rootStore.checkEndpoint('manilav2');
} }
get enableZun() {
return this.props.rootStore.checkEndpoint('zun');
}
async getData() { async getData() {
const { id: project_id } = this.item; const { id: project_id } = this.item;
const promiseArr = [ const promiseArr = [
@ -130,10 +135,14 @@ export class ManageQuota extends ModalAction {
} }
get quotaCardList() { get quotaCardList() {
const newQuotaCardList = [...quotaCardList];
if (this.enableShare) { if (this.enableShare) {
return [...quotaCardList, shareQuotaCard]; newQuotaCardList.push(shareQuotaCard);
} }
return quotaCardList; if (this.enableZun) {
newQuotaCardList.push(zunQuotaCard);
}
return newQuotaCardList;
} }
getFormItemsByCards(cardType) { getFormItemsByCards(cardType) {
@ -184,6 +193,9 @@ export class ManageQuota extends ModalAction {
if (this.enableShare) { if (this.enableShare) {
form.push(...this.getFormItemsByCards('share')); form.push(...this.getFormItemsByCards('share'));
} }
if (this.enableZun) {
form.push(...this.getFormItemsByCards('zun'));
}
if (this.enableCinder) { if (this.enableCinder) {
const cinderFormItems = this.getFormItemsByCards('storage'); const cinderFormItems = this.getFormItemsByCards('storage');
const volumeTypeFormItems = this.getVolumeTypeFormItems(); const volumeTypeFormItems = this.getVolumeTypeFormItems();
@ -202,8 +214,16 @@ export class ManageQuota extends ModalAction {
getSubmitData(values) { getSubmitData(values) {
const { id: project_id } = this.item; const { id: project_id } = this.item;
const { more, compute, storage, networks, volumeTypes, share, ...others } = const {
values; more,
compute,
storage,
networks,
volumeTypes,
share,
zun,
...others
} = values;
return { return {
project_id, project_id,
data: others, data: others,

View File

@ -36,6 +36,9 @@ export class ProjectStore extends Base {
@observable @observable
shareQuota = {}; shareQuota = {};
@observable
zunQuota = {};
@observable @observable
groupRoleList = []; groupRoleList = [];
@ -75,6 +78,10 @@ export class ProjectStore extends Base {
return client.manila.quotaSets; return client.manila.quotaSets;
} }
get zunQuotaClient() {
return client.zun.quotas;
}
listFetchByClient(params, originParams) { listFetchByClient(params, originParams) {
const { userId } = originParams; const { userId } = originParams;
if (userId) { if (userId) {
@ -202,6 +209,10 @@ export class ProjectStore extends Base {
return globalRootStore.checkEndpoint('manilav2'); return globalRootStore.checkEndpoint('manilav2');
} }
get enableZun() {
return globalRootStore.checkEndpoint('zun');
}
@action @action
async enable({ id }) { async enable({ id }) {
const reqBody = { const reqBody = {
@ -248,12 +259,20 @@ export class ProjectStore extends Base {
promiseArr.push( promiseArr.push(
this.enableShare ? this.shareQuotaClient.showDetail(project_id) : null this.enableShare ? this.shareQuotaClient.showDetail(project_id) : null
); );
promiseArr.push(
this.enableZun
? this.zunQuotaClient.show(project_id, {
usages: true,
})
: null
);
promiseArr.push(withKeyPair ? globalKeypairStore.fetchList() : null); promiseArr.push(withKeyPair ? globalKeypairStore.fetchList() : null);
const [ const [
novaResult, novaResult,
neutronResult, neutronResult,
cinderResult, cinderResult,
shareResult, shareResult,
zunResult,
keyPairResult, keyPairResult,
] = await Promise.all(promiseArr); ] = await Promise.all(promiseArr);
this.isSubmitting = false; this.isSubmitting = false;
@ -261,17 +280,24 @@ export class ProjectStore extends Base {
const { quota_set: cinderQuota = {} } = cinderResult || {}; const { quota_set: cinderQuota = {} } = cinderResult || {};
const { quota: neutronQuota } = neutronResult; const { quota: neutronQuota } = neutronResult;
const { quota_set: shareQuota = {} } = shareResult || {}; const { quota_set: shareQuota = {} } = shareResult || {};
const zunQuota = zunResult || {};
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;
pre[key] = shareQuota[cur]; pre[key] = shareQuota[cur];
return pre; return pre;
}, {}); }, {});
const renameZunQuota = Object.keys(zunQuota).reduce((pre, cur) => {
const key = `zun_${cur}`;
pre[key] = zunQuota[cur];
return pre;
}, {});
const quota = { const quota = {
...novaQuota, ...novaQuota,
...cinderQuota, ...cinderQuota,
...neutronQuota, ...neutronQuota,
...renameShareQuota, ...renameShareQuota,
...renameZunQuota,
}; };
if (withKeyPair) { if (withKeyPair) {
const keyPairCount = (keyPairResult || []).length; const keyPairCount = (keyPairResult || []).length;
@ -381,11 +407,26 @@ export class ProjectStore extends Base {
return shareReqBody; return shareReqBody;
} }
getZunQuotaBody(data) {
if (!this.enableZun) {
return {};
}
const { zun_containers, zun_cpu, zun_memory, zun_disk } = data;
const zunReqBody = this.omitNil({
containers: zun_containers,
cpu: zun_cpu,
memory: zun_memory,
disk: zun_disk,
});
return zunReqBody;
}
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 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));
@ -399,6 +440,9 @@ export class ProjectStore extends Base {
if (!isEmpty(shareReqBody.quota_set)) { if (!isEmpty(shareReqBody.quota_set)) {
reqs.push(client.manila.quotaSets.update(project_id, shareReqBody)); reqs.push(client.manila.quotaSets.update(project_id, shareReqBody));
} }
if (!isEmpty(zunReqBody)) {
reqs.push(client.zun.quotas.update(project_id, zunReqBody));
}
const result = await Promise.all(reqs); const result = await Promise.all(reqs);
return result; return result;
} }
@ -524,6 +568,19 @@ export class ProjectStore extends Base {
this.shareQuota = shareQuota; this.shareQuota = shareQuota;
return shareQuota; return shareQuota;
} }
@action
async fetchProjectZunQuota(projectId) {
const quotas = await this.zunQuotaClient.show(
projectId || this.currentProjectId,
{
usages: true,
}
);
const zunQuota = this.updateQuotaData(quotas);
this.zunQuota = zunQuota;
return zunQuota;
}
} }
const globalProjectStore = new ProjectStore(); const globalProjectStore = new ProjectStore();