X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=Utils.js;h=cae25b231efcb74cd9da48355a01aa76cc1ee544;hb=ac6184986ca3621569f87c46bafebd41309a9705;hp=7a4c1d63b81fea10313a903400774575d90b6e30;hpb=0247a07a1e473ab898b404a7ec94585beff6894a;p=proxmox-widget-toolkit.git diff --git a/Utils.js b/Utils.js index 7a4c1d6..cae25b2 100644 --- a/Utils.js +++ b/Utils.js @@ -42,6 +42,7 @@ Ext.define('Proxmox.Utils', { utilities: { enabledText: gettext('Enabled'), disabledText: gettext('Disabled'), noneText: gettext('none'), + NoneText: gettext('None'), errorText: gettext('Error'), unknownText: gettext('Unknown'), defaultText: gettext('Default'), @@ -57,26 +58,28 @@ Ext.define('Proxmox.Utils', { utilities: { groupText: gettext('Group'), language_map: { - zh_CN: 'Chinese (Simplified)', - zh_TW: 'Chinese (Traditional)', + ar: 'Arabic', ca: 'Catalan', da: 'Danish', + de: 'German', en: 'English', + es: 'Spanish', eu: 'Euskera (Basque)', + fa: 'Persian (Farsi)', fr: 'French', - de: 'German', + he: 'Hebrew', it: 'Italian', - es: 'Spanish', ja: 'Japanese', nb: 'Norwegian (Bokmal)', nn: 'Norwegian (Nynorsk)', - fa: 'Persian (Farsi)', pl: 'Polish', pt_BR: 'Portuguese (Brazil)', ru: 'Russian', sl: 'Slovenian', sv: 'Swedish', - tr: 'Turkish' + tr: 'Turkish', + zh_CN: 'Chinese (Simplified)', + zh_TW: 'Chinese (Traditional)', }, render_language: function (value) { @@ -99,9 +102,21 @@ Ext.define('Proxmox.Utils', { utilities: { return data; }, + bond_mode_gettext_map: { + '802.3ad': 'LACP (802.3ad)', + 'lacp-balance-slb': 'LACP (balance-slb)', + 'lacp-balance-tcp': 'LACP (balance-tcp)', + }, + + render_bond_mode: value => Proxmox.Utils.bond_mode_gettext_map[value] || value || '', + + bond_mode_array: function(modes) { + return modes.map(mode => [mode, Proxmox.Utils.render_bond_mode(mode)]); + }, + getNoSubKeyHtml: function(url) { // url http://www.proxmox.com/products/proxmox-ve/subscription-service-plans - return Ext.String.format('You do not have a valid subscription for this server. Please visit www.proxmox.com to get a list of available options.', url || 'http://www.proxmox.com'); + return Ext.String.format('You do not have a valid subscription for this server. Please visit www.proxmox.com to get a list of available options.', url || 'https://www.proxmox.com'); }, format_boolean_with_default: function(value) { @@ -179,11 +194,27 @@ Ext.define('Proxmox.Utils', { utilities: { return min < width ? width : min; }, + setAuthData: function(data) { + Proxmox.CSRFPreventionToken = data.CSRFPreventionToken; + Proxmox.UserName = data.username; + Proxmox.LoggedOut = data.LoggedOut; + // creates a session cookie (expire = null) + // that way the cookie gets deleted after the browser window is closed + Ext.util.Cookies.set(Proxmox.Setup.auth_cookie_name, data.ticket, null, '/', null, true); + }, + authOK: function() { - return (Proxmox.UserName !== '') && Ext.util.Cookies.get(Proxmox.Setup.auth_cookie_name); + if (Proxmox.LoggedOut) { + return undefined; + } + let cookie = Ext.util.Cookies.get(Proxmox.Setup.auth_cookie_name); + return (Proxmox.UserName !== '') && (cookie && !cookie.startsWith("PVE:tfa!")); }, authClear: function() { + if (Proxmox.LoggedOut) { + return undefined; + } Ext.util.Cookies.clear(Proxmox.Setup.auth_cookie_name); }, @@ -205,6 +236,23 @@ Ext.define('Proxmox.Utils', { utilities: { } }, + getResponseErrorMessage: (err) => { + if (!err.statusText) { + return gettext('Connection error'); + } + let msg = `${err.statusText} (${err.status})`; + if (err.response && err.response.responseText) { + let txt = err.response.responseText; + try { + let res = JSON.parse(txt) + for (let [key, value] of Object.entries(res.errors)) { + msg += `
${key}: ${value}`; + } + } catch (e) { /* TODO? */ } + } + return msg; + }, + monStoreErrors: function(me, store, clearMaskBeforeLoad) { if (clearMaskBeforeLoad) { me.mon(store, 'beforeload', function(s, operation, eOpts) { @@ -228,15 +276,8 @@ Ext.define('Proxmox.Utils', { utilities: { return; } - var msg; - /*jslint nomen: true */ - var operation = request._operation; - var error = operation.getError(); - if (error.statusText) { - msg = error.statusText + ' (' + error.status + ')'; - } else { - msg = gettext('Connection error'); - } + let error = request._operation.getError(); + let msg = Proxmox.Utils.getResponseErrorMessage(error); Proxmox.Utils.setErrorMask(me, msg); }); }, @@ -353,7 +394,7 @@ Ext.define('Proxmox.Utils', { utilities: { Ext.Msg.show({ title: gettext('No valid subscription'), icon: Ext.Msg.WARNING, - msg: Proxmox.Utils.getNoSubKeyHtml(data.url), + message: Proxmox.Utils.getNoSubKeyHtml(data.url), buttons: Ext.Msg.OK, callback: function(btn) { if (btn !== 'ok') { @@ -405,6 +446,7 @@ Ext.define('Proxmox.Utils', { utilities: { eth: gettext("Network Device"), bridge: 'Linux Bridge', bond: 'Linux Bond', + vlan: 'Linux VLAN', OVSBridge: 'OVS Bridge', OVSBond: 'OVS Bond', OVSPort: 'OVS Port', @@ -424,6 +466,8 @@ Ext.define('Proxmox.Utils', { utilities: { acmerefresh: [ 'ACME Account', gettext('Refresh') ], acmerenew: [ 'SRV', gettext('Renew Certificate') ], acmerevoke: [ 'SRV', gettext('Revoke Certificate') ], + 'auth-realm-sync': [ gettext('Realm'), gettext('Sync') ], + 'auth-realm-sync-test': [ gettext('Realm'), gettext('Sync Preview')], 'move_volume': [ 'CT', gettext('Move Volume') ], clustercreate: [ '', gettext('Create Cluster') ], clusterjoin: [ '', gettext('Join Cluster') ], @@ -446,7 +490,9 @@ Ext.define('Proxmox.Utils', { utilities: { qmstop: [ 'VM', gettext('Stop') ], qmreset: [ 'VM', gettext('Reset') ], qmshutdown: [ 'VM', gettext('Shutdown') ], - qmsuspend: [ 'VM', gettext('Suspend') ], + qmreboot: [ 'VM', gettext('Reboot') ], + qmsuspend: [ 'VM', gettext('Hibernate') ], + qmpause: [ 'VM', gettext('Pause') ], qmresume: [ 'VM', gettext('Resume') ], qmconfig: [ 'VM', gettext('Configure') ], vzsnapshot: [ 'CT', gettext('Snapshot') ], @@ -463,11 +509,15 @@ Ext.define('Proxmox.Utils', { utilities: { vzmount: ['CT', gettext('Mount') ], vzumount: ['CT', gettext('Unmount') ], vzshutdown: ['CT', gettext('Shutdown') ], + vzreboot: ['CT', gettext('Reboot') ], vzsuspend: [ 'CT', gettext('Suspend') ], vzresume: [ 'CT', gettext('Resume') ], + push_file: ['CT', gettext('Push file')], + pull_file: ['CT', gettext('Pull file')], hamigrate: [ 'HA', gettext('Migrate') ], hastart: [ 'HA', gettext('Start') ], hastop: [ 'HA', gettext('Stop') ], + hashutdown: [ 'HA', gettext('Shutdown') ], srvstart: ['SRV', gettext('Start') ], srvstop: ['SRV', gettext('Stop') ], srvrestart: ['SRV', gettext('Restart') ], @@ -480,27 +530,36 @@ Ext.define('Proxmox.Utils', { utilities: { cephdestroyosd: ['Ceph OSD', gettext('Destroy') ], cephcreatepool: ['Ceph Pool', gettext('Create') ], cephdestroypool: ['Ceph Pool', gettext('Destroy') ], + cephfscreate: ['CephFS', gettext('Create') ], + cephcreatemds: ['Ceph Metadata Server', gettext('Create') ], + cephdestroymds: ['Ceph Metadata Server', gettext('Destroy') ], imgcopy: ['', gettext('Copy data') ], imgdel: ['', gettext('Erase data') ], + unknownimgdel: ['', gettext('Destroy image from unknown guest') ], download: ['', gettext('Download') ], - vzdump: ['', gettext('Backup') ], + vzdump: ['VM/CT', gettext('Backup') ], aptupdate: ['', gettext('Update package database') ], startall: [ '', gettext('Start all VMs and Containers') ], stopall: [ '', gettext('Stop all VMs and Containers') ], - migrateall: [ '', gettext('Migrate all VMs and Containers') ] + migrateall: [ '', gettext('Migrate all VMs and Containers') ], + dircreate: [ gettext('Directory Storage'), gettext('Create') ], + lvmcreate: [ gettext('LVM Storage'), gettext('Create') ], + lvmthincreate: [ gettext('LVM-Thin Storage'), gettext('Create') ], + zfscreate: [ gettext('ZFS Storage'), gettext('Create') ] }, format_task_description: function(type, id) { var farray = Proxmox.Utils.task_desc_table[type]; + var text; if (!farray) { - var text = type; + text = type; if (id) { type += ' ' + id; } return text; } var prefix = farray[0]; - var text = farray[1]; + text = farray[1]; if (prefix) { return prefix + ' ' + id + ' - ' + text; } @@ -545,17 +604,20 @@ Ext.define('Proxmox.Utils', { utilities: { parse_task_upid: function(upid) { var task = {}; - var res = upid.match(/^UPID:(\S+):([0-9A-Fa-f]{8}):([0-9A-Fa-f]{8,9}):([0-9A-Fa-f]{8}):([^:\s]+):([^:\s]*):([^:\s]+):$/); + var res = upid.match(/^UPID:([^\s:]+):([0-9A-Fa-f]{8}):([0-9A-Fa-f]{8,9}):(([0-9A-Fa-f]{8,16}):)?([0-9A-Fa-f]{8}):([^:\s]+):([^:\s]*):([^:\s]+):$/); if (!res) { throw "unable to parse upid '" + upid + "'"; } task.node = res[1]; task.pid = parseInt(res[2], 16); task.pstart = parseInt(res[3], 16); - task.starttime = parseInt(res[4], 16); - task.type = res[5]; - task.id = res[6]; - task.user = res[7]; + if (res[5] !== undefined) { + task.task_id = parseInt(res[5], 16); + } + task.starttime = parseInt(res[6], 16); + task.type = res[7]; + task.id = res[8]; + task.user = res[9]; task.desc = Proxmox.Utils.format_task_description(task.type, task.id); @@ -567,16 +629,43 @@ Ext.define('Proxmox.Utils', { utilities: { return Ext.Date.format(servertime, 'Y-m-d H:i:s'); }, - openXtermJsViewer: function(vmtype, vmid, nodename, vmname) { - var url = Ext.urlEncode({ + get_help_info: function(section) { + var helpMap; + if (typeof proxmoxOnlineHelpInfo !== 'undefined') { + helpMap = proxmoxOnlineHelpInfo; + } else if (typeof pveOnlineHelpInfo !== 'undefined') { + // be backward compatible with older pve-doc-generators + helpMap = pveOnlineHelpInfo; + } else { + throw "no global OnlineHelpInfo map declared"; + } + + return helpMap[section]; + }, + + get_help_link: function(section) { + var info = Proxmox.Utils.get_help_info(section); + if (!info) { + return; + } + + return window.location.origin + info.link; + }, + + openXtermJsViewer: function(vmtype, vmid, nodename, vmname, cmd) { + var url = Ext.Object.toQueryString({ console: vmtype, // kvm, lxc, upgrade or shell xtermjs: 1, vmid: vmid, vmname: vmname, - node: nodename + node: nodename, + cmd: cmd, + }); var nw = window.open("?" + url, '_blank', 'toolbar=no,location=no,status=no,menubar=no,resizable=yes,width=800,height=420'); - nw.focus(); + if (nw) { + nw.focus(); + } } }, @@ -590,10 +679,12 @@ Ext.define('Proxmox.Utils', { utilities: { var IPV4_REGEXP = "(?:(?:" + IPV4_OCTET + "\\.){3}" + IPV4_OCTET + ")"; var IPV6_H16 = "(?:[0-9a-fA-F]{1,4})"; var IPV6_LS32 = "(?:(?:" + IPV6_H16 + ":" + IPV6_H16 + ")|" + IPV4_REGEXP + ")"; + var IPV4_CIDR_MASK = "([0-9]{1,2})"; + var IPV6_CIDR_MASK = "([0-9]{1,3})"; me.IP4_match = new RegExp("^(?:" + IPV4_REGEXP + ")$"); - me.IP4_cidr_match = new RegExp("^(?:" + IPV4_REGEXP + ")\/([0-9]{1,2})$"); + me.IP4_cidr_match = new RegExp("^(?:" + IPV4_REGEXP + ")\/" + IPV4_CIDR_MASK + "$"); var IPV6_REGEXP = "(?:" + "(?:(?:" + "(?:" + IPV6_H16 + ":){6})" + IPV6_LS32 + ")|" + @@ -608,10 +699,11 @@ Ext.define('Proxmox.Utils', { utilities: { ")"; me.IP6_match = new RegExp("^(?:" + IPV6_REGEXP + ")$"); - me.IP6_cidr_match = new RegExp("^(?:" + IPV6_REGEXP + ")\/([0-9]{1,3})$"); + me.IP6_cidr_match = new RegExp("^(?:" + IPV6_REGEXP + ")\/" + IPV6_CIDR_MASK + "$"); me.IP6_bracket_match = new RegExp("^\\[(" + IPV6_REGEXP + ")\\]"); me.IP64_match = new RegExp("^(?:" + IPV6_REGEXP + "|" + IPV4_REGEXP + ")$"); + me.IP64_cidr_match = new RegExp("^(?:" + IPV6_REGEXP + "\/" + IPV6_CIDR_MASK + ")|(?:" + IPV4_REGEXP + "\/" + IPV4_CIDR_MASK + ")$"); var DnsName_REGEXP = "(?:(([a-zA-Z0-9]([a-zA-Z0-9\\-]*[a-zA-Z0-9])?)\\.)*([A-Za-z0-9]([A-Za-z0-9\\-]*[A-Za-z0-9])?))"; me.DnsName_match = new RegExp("^" + DnsName_REGEXP + "$"); @@ -619,5 +711,7 @@ Ext.define('Proxmox.Utils', { utilities: { me.HostPort_match = new RegExp("^(" + IPV4_REGEXP + "|" + DnsName_REGEXP + ")(:\\d+)?$"); me.HostPortBrackets_match = new RegExp("^\\[(?:" + IPV6_REGEXP + "|" + IPV4_REGEXP + "|" + DnsName_REGEXP + ")\\](:\\d+)?$"); me.IP6_dotnotation_match = new RegExp("^" + IPV6_REGEXP + "(\\.\\d+)?$"); + me.Vlan_match = new RegExp('^vlan(\\d+)'); + me.VlanInterface_match = new RegExp('(\\w+)\\.(\\d+)'); } });