diff --git a/src/client/client/constants.js b/src/client/client/constants.js index 5f9da290..4c13d0b6 100644 --- a/src/client/client/constants.js +++ b/src/client/client/constants.js @@ -83,6 +83,7 @@ export const qosEndpoint = () => getOriginEndpoint('neutron_qos'); export const swiftEndpoint = () => getOriginEndpoint('swift'); export const cinderEndpoint = () => getOriginEndpoint('cinder'); export const manilaEndpoint = () => getOriginEndpoint('manilav2'); +export const zunEndpoint = () => getOriginEndpoint('zun'); export const apiVersionMaps = { nova: { diff --git a/src/client/zun/index.js b/src/client/zun/index.js index e8464ebd..5586a842 100644 --- a/src/client/zun/index.js +++ b/src/client/zun/index.js @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { zunBase } from 'client/client/constants'; +import { zunBase, zunEndpoint } from 'client/client/constants'; import Base from '../client/base'; export class ZunClient extends Base { @@ -20,6 +20,10 @@ export class ZunClient extends Base { return zunBase(); } + get enable() { + return !!zunEndpoint(); + } + get resources() { return [ { @@ -71,6 +75,10 @@ export class ZunClient extends Base { key: 'hosts', responseKey: 'host', }, + { + name: 'quotas', + key: 'quotas', + }, ]; } } diff --git a/src/locales/en.json b/src/locales/en.json index 10ae1749..df446a4f 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -429,6 +429,7 @@ "Container Version": "Container Version", "Containers": "Containers", "Containers Info": "Containers Info", + "Containers Management": "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)": "Disk (GiB)", "Disk Format": "Disk Format", "Disk Info": "Disk Info", "Disk Tag": "Disk Tag", diff --git a/src/locales/zh.json b/src/locales/zh.json index 63db1f18..eb87e694 100644 --- a/src/locales/zh.json +++ b/src/locales/zh.json @@ -429,6 +429,7 @@ "Container Version": "容器版本", "Containers": "容器", "Containers Info": "容器信息", + "Containers Management": "容器管理", "Content": "内容", "Content Type": "内容类型", "Control Location": "控制端", @@ -716,6 +717,7 @@ "Disconnect Subnet": "断开子网", "Discovery URL": "发现网址", "Disk": "硬盘", + "Disk (GiB)": "硬盘 (GiB)", "Disk Format": "硬盘格式", "Disk Info": "硬盘信息", "Disk Tag": "硬盘标签", diff --git a/src/pages/base/containers/Overview/components/QuotaOverview.jsx b/src/pages/base/containers/Overview/components/QuotaOverview.jsx index c51748d4..1d2eab7b 100644 --- a/src/pages/base/containers/Overview/components/QuotaOverview.jsx +++ b/src/pages/base/containers/Overview/components/QuotaOverview.jsx @@ -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) => { const value = data.map((item, index) => { return { @@ -177,6 +191,10 @@ export class QuotaOverview extends Component { return globalRootStore.checkEndpoint('manilav2'); } + get enableZun() { + return globalRootStore.checkEndpoint('zun'); + } + get volumeTypeData() { const { volumeTypeData } = this.props; return volumeTypeData || this.volumeTypeStore.list.data; @@ -195,6 +213,9 @@ export class QuotaOverview extends Component { if (this.enableShare) { newList.push(shareQuotaCard); } + if (this.enableZun) { + newList.push(zunQuotaCard); + } return newList; } diff --git a/src/pages/identity/containers/Project/actions/ManageQuota.jsx b/src/pages/identity/containers/Project/actions/ManageQuota.jsx index ae59aae7..fe0c6f1a 100644 --- a/src/pages/identity/containers/Project/actions/ManageQuota.jsx +++ b/src/pages/identity/containers/Project/actions/ManageQuota.jsx @@ -21,6 +21,7 @@ import { quotaCardList, getVolumeTypeCards, shareQuotaCard, + zunQuotaCard, } from 'pages/base/containers/Overview/components/QuotaOverview'; export class ManageQuota extends ModalAction { @@ -47,6 +48,10 @@ export class ManageQuota extends ModalAction { return this.props.rootStore.checkEndpoint('manilav2'); } + get enableZun() { + return this.props.rootStore.checkEndpoint('zun'); + } + async getData() { const { id: project_id } = this.item; const promiseArr = [ @@ -130,10 +135,14 @@ export class ManageQuota extends ModalAction { } get quotaCardList() { + const newQuotaCardList = [...quotaCardList]; if (this.enableShare) { - return [...quotaCardList, shareQuotaCard]; + newQuotaCardList.push(shareQuotaCard); } - return quotaCardList; + if (this.enableZun) { + newQuotaCardList.push(zunQuotaCard); + } + return newQuotaCardList; } getFormItemsByCards(cardType) { @@ -184,6 +193,9 @@ export class ManageQuota extends ModalAction { if (this.enableShare) { form.push(...this.getFormItemsByCards('share')); } + if (this.enableZun) { + form.push(...this.getFormItemsByCards('zun')); + } if (this.enableCinder) { const cinderFormItems = this.getFormItemsByCards('storage'); const volumeTypeFormItems = this.getVolumeTypeFormItems(); @@ -202,8 +214,16 @@ export class ManageQuota extends ModalAction { getSubmitData(values) { const { id: project_id } = this.item; - const { more, compute, storage, networks, volumeTypes, share, ...others } = - values; + const { + more, + compute, + storage, + networks, + volumeTypes, + share, + zun, + ...others + } = values; return { project_id, data: others, diff --git a/src/stores/keystone/project.js b/src/stores/keystone/project.js index dd5cc4b1..eb47f5c5 100644 --- a/src/stores/keystone/project.js +++ b/src/stores/keystone/project.js @@ -36,6 +36,9 @@ export class ProjectStore extends Base { @observable shareQuota = {}; + @observable + zunQuota = {}; + @observable groupRoleList = []; @@ -75,6 +78,10 @@ export class ProjectStore extends Base { return client.manila.quotaSets; } + get zunQuotaClient() { + return client.zun.quotas; + } + listFetchByClient(params, originParams) { const { userId } = originParams; if (userId) { @@ -202,6 +209,10 @@ export class ProjectStore extends Base { return globalRootStore.checkEndpoint('manilav2'); } + get enableZun() { + return globalRootStore.checkEndpoint('zun'); + } + @action async enable({ id }) { const reqBody = { @@ -248,12 +259,20 @@ export class ProjectStore extends Base { promiseArr.push( 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); const [ novaResult, neutronResult, cinderResult, shareResult, + zunResult, keyPairResult, ] = await Promise.all(promiseArr); this.isSubmitting = false; @@ -261,17 +280,24 @@ export class ProjectStore extends Base { const { quota_set: cinderQuota = {} } = cinderResult || {}; const { quota: neutronQuota } = neutronResult; const { quota_set: shareQuota = {} } = shareResult || {}; + const zunQuota = zunResult || {}; this.updateNovaQuota(novaQuota); const renameShareQuota = Object.keys(shareQuota).reduce((pre, cur) => { const key = !cur.includes('share') ? `share_${cur}` : cur; pre[key] = shareQuota[cur]; return pre; }, {}); + const renameZunQuota = Object.keys(zunQuota).reduce((pre, cur) => { + const key = `zun_${cur}`; + pre[key] = zunQuota[cur]; + return pre; + }, {}); const quota = { ...novaQuota, ...cinderQuota, ...neutronQuota, ...renameShareQuota, + ...renameZunQuota, }; if (withKeyPair) { const keyPairCount = (keyPairResult || []).length; @@ -381,11 +407,26 @@ export class ProjectStore extends Base { 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) { const novaReqBody = this.getNovaQuotaBody(data); const cinderReqBody = this.getCinderQuotaBody(data); const neutronReqBody = this.getNeutronQuotaBody(data); const shareReqBody = this.getShareQuotaBody(data); + const zunReqBody = this.getZunQuotaBody(data); const reqs = []; if (!isEmpty(novaReqBody.quota_set)) { reqs.push(client.nova.quotaSets.update(project_id, novaReqBody)); @@ -399,6 +440,9 @@ export class ProjectStore extends Base { if (!isEmpty(shareReqBody.quota_set)) { 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); return result; } @@ -524,6 +568,19 @@ export class ProjectStore extends Base { this.shareQuota = 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();