diff --git a/ui/src/views/infra/zone/StaticInputsForm.vue b/ui/src/views/infra/zone/StaticInputsForm.vue index c5a296a42b37..082f9d87246a 100644 --- a/ui/src/views/infra/zone/StaticInputsForm.vue +++ b/ui/src/views/infra/zone/StaticInputsForm.vue @@ -215,6 +215,12 @@ export default { message: this.$t(field.message) }) } + if (field.number) { + this.rules[field.key].push({ + validator: this.checkNumberFormat, + message: this.$t('message.error.number') + }) + } }, getPrefilled (field) { if (field.key === 'authmethod' && this.hypervisor !== 'KVM') { @@ -247,6 +253,15 @@ export default { return Promise.resolve() } }, + async checkNumberFormat (rule, value) { + if (!value || value === '') { + return Promise.resolve() + } else if (!/^\d+$/.test(String(value).replace(/,/g, ''))) { + return Promise.reject(rule.message) + } else { + return Promise.resolve() + } + }, isDisplayInput (field) { if (!field.display && !field.hidden) { return true diff --git a/ui/src/views/infra/zone/ZoneWizardAddResources.vue b/ui/src/views/infra/zone/ZoneWizardAddResources.vue index 318986913ce2..bbcc460aed1a 100644 --- a/ui/src/views/infra/zone/ZoneWizardAddResources.vue +++ b/ui/src/views/infra/zone/ZoneWizardAddResources.vue @@ -589,14 +589,14 @@ export default { title: 'label.capacityiops', key: 'capacityIops', hidden: { - provider: ['DefaultPrimary', 'PowerFlex', 'Linstor'] + provider: ['DefaultPrimary', 'PowerFlex', 'Linstor', 'NetApp ONTAP'] } }, { title: 'label.url', key: 'url', hidden: { - provider: ['DefaultPrimary', 'PowerFlex', 'Linstor'] + provider: ['DefaultPrimary', 'PowerFlex', 'Linstor', 'NetApp ONTAP'] } }, { @@ -636,6 +636,43 @@ export default { provider: 'PowerFlex' } }, + { + title: 'label.ontap.ip', + key: 'ontapIP', + required: true, + placeHolder: 'message.error.input.value', + display: { + provider: 'NetApp ONTAP' + } + }, + { + title: 'label.username', + key: 'ontapUsername', + required: true, + placeHolder: 'message.error.input.value', + display: { + provider: 'NetApp ONTAP' + } + }, + { + title: 'label.password', + key: 'ontapPassword', + required: true, + placeHolder: 'message.error.input.value', + password: true, + display: { + provider: 'NetApp ONTAP' + } + }, + { + title: 'label.ontap.svm.name', + key: 'ontapSvmName', + required: true, + placeHolder: 'message.error.input.value', + display: { + provider: 'NetApp ONTAP' + } + }, { title: 'label.storage.tags', key: 'primaryStorageTags', @@ -909,9 +946,9 @@ export default { }, watch: { 'prefillContent.provider' (newVal, oldVal) { - if (['SolidFire', 'PowerFlex'].includes(newVal) && !['SolidFire', 'PowerFlex'].includes(oldVal)) { + if (['SolidFire', 'PowerFlex', 'NetApp ONTAP'].includes(newVal) && !['SolidFire', 'PowerFlex', 'NetApp ONTAP'].includes(oldVal)) { this.$emit('fieldsChanged', { primaryStorageProtocol: undefined }) - } else if (!['SolidFire', 'PowerFlex'].includes(newVal) && ['SolidFire', 'PowerFlex'].includes(oldVal)) { + } else if (!['SolidFire', 'PowerFlex', 'NetApp ONTAP'].includes(newVal) && ['SolidFire', 'PowerFlex', 'NetApp ONTAP'].includes(oldVal)) { this.$emit('fieldsChanged', { primaryStorageProtocol: undefined }) } @@ -996,6 +1033,17 @@ export default { this.primaryStorageScopes = scope }, fetchProtocol () { + const provider = this.prefillContent?.provider || null + if (provider === 'NetApp ONTAP') { + this.primaryStorageProtocols = [ + { id: 'NFS3', description: 'NFS3' }, + { id: 'ISCSI', description: 'ISCSI' } + ] + if (!['NFS3', 'ISCSI'].includes(this.prefillContent?.primaryStorageProtocol)) { + this.$emit('fieldsChanged', { primaryStorageProtocol: 'NFS3' }) + } + return + } const hypervisor = this.prefillContent?.hypervisor || null const protocols = [] if (hypervisor === 'KVM') { diff --git a/ui/src/views/infra/zone/ZoneWizardLaunchZone.vue b/ui/src/views/infra/zone/ZoneWizardLaunchZone.vue index e16afbcf89e3..76dda3a40acd 100644 --- a/ui/src/views/infra/zone/ZoneWizardLaunchZone.vue +++ b/ui/src/views/infra/zone/ZoneWizardLaunchZone.vue @@ -1584,7 +1584,7 @@ export default { } params.url = url - if (this.prefillContent.provider !== 'DefaultPrimary' && this.prefillContent.provider !== 'PowerFlex') { + if (this.prefillContent.provider !== 'DefaultPrimary' && this.prefillContent.provider !== 'PowerFlex' && this.prefillContent.provider !== 'NetApp ONTAP') { if (this.prefillContent.managed) { params.managed = true } else { @@ -1604,6 +1604,18 @@ export default { params.url = this.powerflexURL(this.prefillContent.powerflexGateway, this.prefillContent.powerflexGatewayUsername, this.prefillContent.powerflexGatewayPassword, this.prefillContent.powerflexStoragePool) } + if (this.prefillContent.provider === 'NetApp ONTAP') { + params['details[0].storageIP'] = this.prefillContent.ontapIP + params['details[0].username'] = this.prefillContent.ontapUsername + params['details[0].password'] = btoa(this.prefillContent.ontapPassword) + params['details[0].svmName'] = this.prefillContent.ontapSvmName + params['details[0].protocol'] = this.prefillContent.primaryStorageProtocol + params.managed = true + params.url = this.ontapURL(this.prefillContent.ontapIP) + if (this.prefillContent.capacityBytes && this.prefillContent.capacityBytes.length > 0) { + params.capacityBytes = this.prefillContent.capacityBytes.split(',').join('') + } + } params.tags = this.prefillContent?.primaryStorageTags || '' @@ -2486,6 +2498,10 @@ export default { var url = 'powerflex://' + encodeURIComponent(username) + ':' + encodeURIComponent(password) + '@' + gateway + '/' + encodeURIComponent(pool) return url + }, + ontapURL (ontapIp) { + var url = 'https://' + ontapIp + return url } } }