--- pvemanagerlib.js.orig 2023-12-30 15:36:27.913505863 -0500 +++ pvemanagerlib.js 2024-01-02 09:30:56.000000000 -0500 @@ -9228,6 +9228,7 @@ alias: ['widget.pveiScsiProviderSelector'], comboItems: [ ['comstar', 'Comstar'], + ['freenas', 'FreeNAS/TrueNAS API'], ['istgt', 'istgt'], ['iet', 'IET'], ['LIO', 'LIO'], @@ -58017,16 +58018,24 @@ me.callParent(); }, }); + Ext.define('PVE.storage.ZFSInputPanel', { extend: 'PVE.panel.StorageBase', viewModel: { parent: null, data: { +isComstar: true, + isFreeNAS: false, isLIO: false, - isComstar: true, + isToken: false, hasWriteCacheOption: true, }, +formulas: { + hideUsername: function(get) { + return (!get('isFreeNAS') || !(get('isFreeNAS') && !get('isToken'))); + }, + }, }, controller: { @@ -58034,13 +58043,42 @@ control: { 'field[name=iscsiprovider]': { change: 'changeISCSIProvider', +}, + 'field[name=truenas_token_auth]': { + change: 'changeUsername', }, }, changeISCSIProvider: function(f, newVal, oldVal) { +var me = this; var vm = this.getViewModel(); vm.set('isLIO', newVal === 'LIO'); vm.set('isComstar', newVal === 'comstar'); - vm.set('hasWriteCacheOption', newVal === 'comstar' || newVal === 'istgt'); + vm.set('isFreeNAS', newVal === 'freenas'); + vm.set('hasWriteCacheOption', newVal === 'comstar' || newVal === 'freenas' || newVal === 'istgt'); + if (newVal !== 'freenas') { + me.lookupReference('freenas_use_ssl_field').setValue(false); + me.lookupReference('truenas_token_auth_field').setValue(false); + me.lookupReference('freenas_apiv4_host_field').setValue(''); + me.lookupReference('freenas_user_field').setValue(''); + me.lookupReference('freenas_user_field').allowBlank = true; + me.lookupReference('truenas_secret_field').setValue(''); + me.lookupReference('truenas_secret_field').allowBlank = true; + me.lookupReference('truenas_confirm_secret_field').setValue(''); + me.lookupReference('truenas_confirm_secret_field').allowBlank = true; + } else { + me.lookupReference('freenas_user_field').allowBlank = false; + me.lookupReference('truenas_secret_field').allowBlank = false; + me.lookupReference('truenas_confirm_secret_field').allowBlank = false; + } + }, + changeUsername: function(f, newVal, oldVal) { + var me = this; + var vm = me.getViewModel(); + vm.set('isToken', newVal); + me.lookupReference('freenas_user_field').allowBlank = newVal; + if (newVal) { + me.lookupReference('freenas_user_field').setValue(''); + } }, }, @@ -58053,28 +58091,78 @@ values.nowritecache = values.writecache ? 0 : 1; delete values.writecache; + console.warn(values.freenas_password); + if (values.freenas_password) { + values.truenas_secret = values.freenas_password; + } + console.warn(values.truenas_secret); return me.callParent([values]); }, setValues: function(values) { - values.writecache = values.nowritecache ? 0 : 1; - this.callParent([values]); + if (values.freenas_password) { + values.truenas_secret = values.freenas_password; + } + values.truenas_confirm_secret = values.truenas_secret; + values.writecache = values.nowritecache ? 0 : 1; + this.callParent([values]); }, initComponent: function() { - var me = this; + var me = this; + + var tnsecret = Ext.create('Ext.form.TextField', { + xtype: 'proxmoxtextfield', + name: 'truenas_secret', + reference: 'truenas_secret_field', + inputType: me.isCreate ? '' : 'password', + value: '', + editable: true, + emptyText: Proxmox.Utils.noneText, + bind: { + hidden: '{!isFreeNAS}' + }, + fieldLabel: gettext('API Password'), + change: function(f, value) { + if (f.rendered) { + f.up().down('field[name=truenas_confirm_secret]').validate(); + } + }, + }); - me.column1 = [ - { - xtype: me.isCreate ? 'textfield' : 'displayfield', - name: 'portal', + var tnconfirmsecret = Ext.create('Ext.form.TextField', { + xtype: 'proxmoxtextfield', + name: 'truenas_confirm_secret', + reference: 'truenas_confirm_secret_field', + inputType: me.isCreate ? '' : 'password', + value: '', + editable: true, + submitValue: false, + emptyText: Proxmox.Utils.noneText, + bind: { + hidden: '{!isFreeNAS}' + }, + fieldLabel: gettext('Confirm API Password'), + validator: function(value) { + var pw = me.up().down('field[name=truenas_secret]').getValue(); + if (pw !== value) { + return "Secrets do not match!"; + } + return true; + }, + }); + + me.column1 = [ + { + xtype: me.isCreate ? 'textfield' : 'displayfield', + name: 'portal', value: '', fieldLabel: gettext('Portal'), allowBlank: false, }, { - xtype: me.isCreate ? 'textfield' : 'displayfield', + xtype: 'textfield', name: 'pool', value: '', fieldLabel: gettext('Pool'), @@ -58084,11 +58172,11 @@ xtype: me.isCreate ? 'textfield' : 'displayfield', name: 'blocksize', value: '4k', - fieldLabel: gettext('Block Size'), + fieldLabel: gettext('ZFS Block Size'), allowBlank: false, }, { - xtype: me.isCreate ? 'textfield' : 'displayfield', + xtype: 'textfield', name: 'target', value: '', fieldLabel: gettext('Target'), @@ -58099,8 +58187,59 @@ name: 'comstar_tg', value: '', fieldLabel: gettext('Target group'), - bind: me.isCreate ? { disabled: '{!isComstar}' } : { hidden: '{!isComstar}' }, + bind: { + hidden: '{!isComstar}' + }, allowBlank: true, +}, + { + xtype: 'proxmoxcheckbox', + name: 'freenas_use_ssl', + reference: 'freenas_use_ssl_field', + inputId: 'freenas_use_ssl_field', + checked: false, + bind: { + hidden: '{!isFreeNAS}' + }, + uncheckedValue: 0, + fieldLabel: gettext('API use SSL'), + }, + { + xtype: 'proxmoxcheckbox', + name: 'truenas_token_auth', + reference: 'truenas_token_auth_field', + inputId: 'truenas_use_token_auth_field', + checked: false, + listeners: { + change: function(field, newValue) { + if (newValue === true) { + tnsecret.labelEl.update('API Token'); + tnconfirmsecret.labelEl.update('Confirm API Token'); + me.lookupReference('freenas_user_field').setValue(''); + me.lookupReference('freenas_user_field').allowBlank = true; + } else { + tnsecret.labelEl.update('API Password'); + tnconfirmsecret.labelEl.update('Confirm API Password'); + me.lookupReference('freenas_user_field').allowBlank = false; + } + }, + }, + bind: { + hidden: '{!isFreeNAS}' + }, + uncheckedValue: 0, + fieldLabel: gettext('API Token Auth'), + }, + { + xtype: 'textfield', + name: 'freenas_user', + reference: 'freenas_user_field', + inputId: 'freenas_user_field', + value: '', + fieldLabel: gettext('API Username'), + bind: { + hidden: '{hideUsername}' + }, }, ]; @@ -58131,7 +58270,9 @@ xtype: me.isCreate ? 'textfield' : 'displayfield', name: 'comstar_hg', value: '', - bind: me.isCreate ? { disabled: '{!isComstar}' } : { hidden: '{!isComstar}' }, + bind: { + hidden: '{!isComstar}' + }, fieldLabel: gettext('Host group'), allowBlank: true, }, @@ -58139,15 +58280,32 @@ xtype: me.isCreate ? 'textfield' : 'displayfield', name: 'lio_tpg', value: '', - bind: me.isCreate ? { disabled: '{!isLIO}' } : { hidden: '{!isLIO}' }, - allowBlank: false, - fieldLabel: gettext('Target portal group'), + bind: { + hidden: '{!isLIO}' + }, + fieldLabel: gettext('Target portal group'), + allowBlank: true }, + { + xtype: 'proxmoxtextfield', + name: 'freenas_apiv4_host', + reference: 'freenas_apiv4_host_field', + value: '', + editable: true, + emptyText: Proxmox.Utils.noneText, + bind: { + hidden: '{!isFreeNAS}' + }, + fieldLabel: gettext('API IPv4 Host'), + }, + tnsecret, + tnconfirmsecret, ]; me.callParent(); }, }); + Ext.define('PVE.storage.ZFSPoolSelector', { extend: 'PVE.form.ComboBoxSetStoreNode', alias: 'widget.pveZFSPoolSelector',