From 731f0ca8528dbc80435e904ae05ead0f97e945af Mon Sep 17 00:00:00 2001 From: utchoang Date: Wed, 1 Jun 2022 08:52:13 +0700 Subject: [PATCH 1/5] add provider in creating primary storage when adding new zone --- ui/src/views/infra/zone/StaticInputsForm.vue | 42 ++++++--- .../infra/zone/ZoneWizardAddResources.vue | 88 ++++++++++++++++++- .../views/infra/zone/ZoneWizardLaunchZone.vue | 27 ++++++ 3 files changed, 144 insertions(+), 13 deletions(-) diff --git a/ui/src/views/infra/zone/StaticInputsForm.vue b/ui/src/views/infra/zone/StaticInputsForm.vue index 0c23a3ad0835..1895b7b0bcb0 100644 --- a/ui/src/views/infra/zone/StaticInputsForm.vue +++ b/ui/src/views/infra/zone/StaticInputsForm.vue @@ -35,7 +35,7 @@ :name="field.key" :ref="field.key" :label="$t(field.title)" - v-if="isDisplayInput(field.display)" + v-if="isDisplayInput(field)" v-bind="formItemLayout" :has-feedback="field.switch ? false : true"> + + { this.setRules(field) - const fieldExists = this.isDisplayInput(field.display) + const fieldExists = this.isDisplayInput(field) if (!fieldExists) { return } - if (field.key === 'agentUserName' && !this.getPrefilled(field.key)) { + if (field.key === 'agentUserName' && !this.getPrefilled(field)) { this.form[field.key] = 'Oracle' } else { - if (field.switch) { + if (field.switch || field.checkbox) { this.form[field.key] = this.isChecked(field) } else { - this.form[field.key] = this.getPrefilled(field.key) + this.form[field.key] = this.getPrefilled(field) } } }) @@ -179,8 +184,8 @@ export default { }) } }, - getPrefilled (key) { - return this.prefillContent?.[key] || null + getPrefilled (field) { + return this.prefillContent?.[field.key] || field.value || undefined }, handleSubmit () { this.formRef.value.validate().then(() => { @@ -207,7 +212,11 @@ export default { return Promise.resolve() } }, - isDisplayInput (conditions) { + isDisplayInput (field) { + if (!field.display && !field.hidden) { + return true + } + const conditions = field.display || field.hidden if (!conditions || Object.keys(conditions).length === 0) { return true } @@ -218,10 +227,19 @@ export default { const fieldVal = this.form[key] ? this.form[key] : (this.prefillContent?.[key] || null) - if (Array.isArray(condition) && !condition.includes(fieldVal)) { - isShow = false - } else if (!Array.isArray(condition) && fieldVal !== condition) { - isShow = false + + if (field.hidden) { + if (Array.isArray(condition) && condition.includes(fieldVal)) { + isShow = false + } else if (!Array.isArray(condition) && fieldVal === condition) { + isShow = false + } + } else if (field.display) { + if (Array.isArray(condition) && !condition.includes(fieldVal)) { + isShow = false + } else if (!Array.isArray(condition) && fieldVal !== condition) { + isShow = false + } } } }) diff --git a/ui/src/views/infra/zone/ZoneWizardAddResources.vue b/ui/src/views/infra/zone/ZoneWizardAddResources.vue index 8a52ec91007c..6d617b56a27b 100644 --- a/ui/src/views/infra/zone/ZoneWizardAddResources.vue +++ b/ui/src/views/infra/zone/ZoneWizardAddResources.vue @@ -499,6 +499,81 @@ export default { primaryStorageProtocol: 'Linstor' } }, + { + title: 'label.provider', + key: 'provider', + placeHolder: 'message.error.select', + value: 'DefaultPrimary', + select: true, + required: true, + options: this.primaryStorageProviders + }, + { + title: 'label.ismanaged', + key: 'managed', + checkbox: true, + hidden: { + provider: ['DefaultPrimary', 'PowerFlex', 'Linstor'] + } + }, + { + title: 'label.capacitybytes', + key: 'capacityBytes', + hidden: { + provider: ['DefaultPrimary', 'PowerFlex', 'Linstor'] + } + }, + { + title: 'label.capacityiops', + key: 'capacityIops', + hidden: { + provider: ['DefaultPrimary', 'PowerFlex', 'Linstor'] + } + }, + { + title: 'label.url', + key: 'url', + hidden: { + provider: ['DefaultPrimary', 'PowerFlex', 'Linstor'] + } + }, + { + title: 'label.powerflex.gateway', + key: 'powerflexGateway', + required: true, + placeHolder: 'message.error.input.value', + display: { + provider: 'PowerFlex' + } + }, + { + title: 'label.powerflex.gateway.username', + key: 'powerflexGatewayUsername', + required: true, + placeHolder: 'message.error.input.value', + display: { + provider: 'PowerFlex' + } + }, + { + title: 'label.powerflex.gateway.password', + key: 'powerflexGatewayPassword', + required: true, + placeHolder: 'message.error.input.value', + password: true, + display: { + provider: 'PowerFlex' + } + }, + { + title: 'label.powerflex.storage.pool', + key: 'powerflexStoragePool', + required: true, + placeHolder: 'message.error.input.value', + display: { + provider: 'PowerFlex' + } + }, { title: 'label.storage.tags', key: 'primaryStorageTags', @@ -721,9 +796,10 @@ export default { currentHypervisor: null, primaryStorageScopes: [], primaryStorageProtocols: [], + primaryStorageProviders: [], storageProviders: [], currentStep: null, - options: ['primaryStorageScope', 'primaryStorageProtocol', 'provider'] + options: ['primaryStorageScope', 'primaryStorageProtocol', 'provider', 'primaryStorageProvider'] } }, created () { @@ -800,6 +876,9 @@ export default { case 'provider': this.fetchProvider() break + case 'primaryStorageProvider': + this.fetchPrimaryStorageProvider() + break default: break } @@ -956,6 +1035,13 @@ export default { this.storageProviders = storageProviders }) }, + fetchPrimaryStorageProvider () { + this.primaryStorageProviders = [] + api('listStorageProviders', { type: 'primary' }).then(json => { + this.primaryStorageProviders = json.liststorageprovidersresponse.dataStoreProvider || [] + this.primaryStorageProviders.map((item, idx) => { this.primaryStorageProviders[idx].id = item.name }) + }) + }, submitLaunchZone () { this.$emit('submitLaunchZone') }, diff --git a/ui/src/views/infra/zone/ZoneWizardLaunchZone.vue b/ui/src/views/infra/zone/ZoneWizardLaunchZone.vue index 377afe700510..a7446c540162 100644 --- a/ui/src/views/infra/zone/ZoneWizardLaunchZone.vue +++ b/ui/src/views/infra/zone/ZoneWizardLaunchZone.vue @@ -1276,6 +1276,7 @@ export default { params.clusterid = this.stepData.clusterReturned.id params.name = this.prefillContent?.primaryStorageName || null params.scope = this.prefillContent?.primaryStorageScope || null + params.provider = this.prefillContent.provider if (params.scope === 'zone') { const hypervisor = this.prefillContent.hypervisor @@ -1366,6 +1367,27 @@ export default { } params.url = url + if (this.prefillContent.provider !== 'DefaultPrimary' && this.prefillContent.provider !== 'PowerFlex') { + if (this.prefillContent.managed) { + params.managed = true + } else { + params.managed = false + } + if (this.prefillContent.capacityBytes && this.prefillContent.capacityBytes.length > 0) { + params.capacityBytes = this.prefillContent.capacityBytes.split(',').join('') + } + if (this.prefillContent.capacityIops && this.prefillContent.capacityIops.length > 0) { + params.capacityIops = this.prefillContent.capacityIops.split(',').join('') + } + if (this.prefillContent.url && this.prefillContent.url.length > 0) { + params.url = this.prefillContent.url + } + } + if (this.prefillContent.provider === 'PowerFlex') { + params.url = this.powerflexURL(this.prefillContent.powerflexGateway, this.prefillContent.powerflexGatewayUsername, + this.prefillContent.powerflexGatewayPassword, this.prefillContent.powerflexStoragePool) + } + params.tags = this.prefillContent?.primaryStorageTags || '' try { @@ -2168,6 +2190,11 @@ export default { url = server + iqn + '/' + lun } return url + }, + powerflexURL (gateway, username, password, pool) { + var url = 'powerflex://' + encodeURIComponent(username) + ':' + encodeURIComponent(password) + '@' + + gateway + '/' + encodeURIComponent(pool) + return url } } } From 6a9f247336eecbc84d7e8b87e4fa2100ae64179b Mon Sep 17 00:00:00 2001 From: utchoang Date: Fri, 3 Jun 2022 08:35:56 +0700 Subject: [PATCH 2/5] add custom protocol for SolidFire/PowerFlex provider --- ui/src/views/infra/zone/StaticInputsForm.vue | 3 +++ .../views/infra/zone/ZoneWizardAddResources.vue | 16 +++++++++++++++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/ui/src/views/infra/zone/StaticInputsForm.vue b/ui/src/views/infra/zone/StaticInputsForm.vue index 1895b7b0bcb0..b4cfe81c9686 100644 --- a/ui/src/views/infra/zone/StaticInputsForm.vue +++ b/ui/src/views/infra/zone/StaticInputsForm.vue @@ -142,6 +142,9 @@ export default { const fieldsChanged = toRaw(changedFields) this.$emit('fieldsChanged', fieldsChanged) } + }, + 'prefillContent.primaryStorageProtocol' (val) { + this.form.primaryStorageProtocol = val } }, methods: { diff --git a/ui/src/views/infra/zone/ZoneWizardAddResources.vue b/ui/src/views/infra/zone/ZoneWizardAddResources.vue index 6d617b56a27b..1313e6f51b1d 100644 --- a/ui/src/views/infra/zone/ZoneWizardAddResources.vue +++ b/ui/src/views/infra/zone/ZoneWizardAddResources.vue @@ -826,6 +826,17 @@ export default { } } }, + watch: { + 'prefillContent.provider' (newVal, oldVal) { + if (['SolidFire', 'PowerFlex'].includes(newVal) && !['SolidFire', 'PowerFlex'].includes(oldVal)) { + this.$emit('fieldsChanged', { primaryStorageProtocol: undefined }) + } else if (!['SolidFire', 'PowerFlex'].includes(newVal) && ['SolidFire', 'PowerFlex'].includes(oldVal)) { + this.$emit('fieldsChanged', { primaryStorageProtocol: undefined }) + } + + this.fetchProtocol() + } + }, methods: { nextPressed () { if (this.currentStep === this.steps.length - 1) { @@ -905,8 +916,11 @@ export default { }, fetchProtocol () { const hypervisor = this.prefillContent?.hypervisor || null + const provider = this.prefillContent?.provider || null const protocols = [] - if (hypervisor === 'KVM') { + if (['SolidFire', 'PowerFlex'].includes(provider)) { + protocols.push({ id: 'custom', description: 'custom' }) + } else if (hypervisor === 'KVM') { protocols.push({ id: 'nfs', description: 'nfs' From f2fb2072a2233e6d9c4764c439aea175180296de Mon Sep 17 00:00:00 2001 From: utchoang Date: Tue, 7 Jun 2022 16:06:01 +0700 Subject: [PATCH 3/5] set the custom protocol option available with the rest of the protocol options --- ui/src/views/infra/zone/StaticInputsForm.vue | 5 +++++ ui/src/views/infra/zone/ZoneWizardAddResources.vue | 6 ++---- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/ui/src/views/infra/zone/StaticInputsForm.vue b/ui/src/views/infra/zone/StaticInputsForm.vue index b4cfe81c9686..4a6b28bc0687 100644 --- a/ui/src/views/infra/zone/StaticInputsForm.vue +++ b/ui/src/views/infra/zone/StaticInputsForm.vue @@ -145,6 +145,11 @@ export default { }, 'prefillContent.primaryStorageProtocol' (val) { this.form.primaryStorageProtocol = val + }, + 'prefillContent.provider' (val) { + if (['SolidFire', 'PowerFlex'].includes(val)) { + this.form.primaryStorageProtocol = 'custom' + } } }, methods: { diff --git a/ui/src/views/infra/zone/ZoneWizardAddResources.vue b/ui/src/views/infra/zone/ZoneWizardAddResources.vue index 1313e6f51b1d..ab05a9945fd2 100644 --- a/ui/src/views/infra/zone/ZoneWizardAddResources.vue +++ b/ui/src/views/infra/zone/ZoneWizardAddResources.vue @@ -916,11 +916,8 @@ export default { }, fetchProtocol () { const hypervisor = this.prefillContent?.hypervisor || null - const provider = this.prefillContent?.provider || null const protocols = [] - if (['SolidFire', 'PowerFlex'].includes(provider)) { - protocols.push({ id: 'custom', description: 'custom' }) - } else if (hypervisor === 'KVM') { + if (hypervisor === 'KVM') { protocols.push({ id: 'nfs', description: 'nfs' @@ -1005,6 +1002,7 @@ export default { }) } + protocols.push({ id: 'custom', description: 'custom' }) this.primaryStorageProtocols = protocols }, async fetchConfigurationSwitch () { From d815b9cf490ab27c9e341114d82415bde0805291 Mon Sep 17 00:00:00 2001 From: utchoang Date: Wed, 8 Jun 2022 08:34:15 +0700 Subject: [PATCH 4/5] fixes indexOf error & auto-select protocol --- ui/src/views/infra/zone/StaticInputsForm.vue | 3 --- ui/src/views/infra/zone/ZoneWizardLaunchZone.vue | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/ui/src/views/infra/zone/StaticInputsForm.vue b/ui/src/views/infra/zone/StaticInputsForm.vue index 4a6b28bc0687..5eb535f281a9 100644 --- a/ui/src/views/infra/zone/StaticInputsForm.vue +++ b/ui/src/views/infra/zone/StaticInputsForm.vue @@ -143,9 +143,6 @@ export default { this.$emit('fieldsChanged', fieldsChanged) } }, - 'prefillContent.primaryStorageProtocol' (val) { - this.form.primaryStorageProtocol = val - }, 'prefillContent.provider' (val) { if (['SolidFire', 'PowerFlex'].includes(val)) { this.form.primaryStorageProtocol = 'custom' diff --git a/ui/src/views/infra/zone/ZoneWizardLaunchZone.vue b/ui/src/views/infra/zone/ZoneWizardLaunchZone.vue index a7446c540162..88078e5300d0 100644 --- a/ui/src/views/infra/zone/ZoneWizardLaunchZone.vue +++ b/ui/src/views/infra/zone/ZoneWizardLaunchZone.vue @@ -1357,7 +1357,7 @@ export default { if (protocol === 'datastorecluster') { url = this.datastoreclusterURL('dummy', path) } - } else { + } else if (protocol === 'iscsi') { let iqn = this.prefillContent?.primaryStorageTargetIQN || '' if (iqn.substring(0, 1) !== '/') { iqn = '/' + iqn From c787bdb1a99c0271a4e6742f3019e458904ae4c7 Mon Sep 17 00:00:00 2001 From: utchoang Date: Wed, 8 Jun 2022 16:45:50 +0700 Subject: [PATCH 5/5] set server=localhost with SharedMountPoint protocol --- ui/src/views/infra/zone/ZoneWizardLaunchZone.vue | 1 + 1 file changed, 1 insertion(+) diff --git a/ui/src/views/infra/zone/ZoneWizardLaunchZone.vue b/ui/src/views/infra/zone/ZoneWizardLaunchZone.vue index 88078e5300d0..3630ddbe942f 100644 --- a/ui/src/views/infra/zone/ZoneWizardLaunchZone.vue +++ b/ui/src/views/infra/zone/ZoneWizardLaunchZone.vue @@ -1325,6 +1325,7 @@ export default { } url = this.ocfs2URL(server, path) } else if (protocol === 'SharedMountPoint') { + server = 'localhost' let path = this.prefillContent?.primaryStoragePath || '' if (path.substring(0, 1) !== '/') { path = '/' + path