From 5a691a50449e2a1af13e764c6a5eb4a4048a3f8b Mon Sep 17 00:00:00 2001 From: Dietmar Maurer Date: Thu, 3 Mar 2016 10:51:31 +0100 Subject: [PATCH] copy lxc/Network.js from manager to manager6 --- www/manager6/lxc/Network.js | 554 ++++++++++++++++++++++++++++++++++++ 1 file changed, 554 insertions(+) create mode 100644 www/manager6/lxc/Network.js diff --git a/www/manager6/lxc/Network.js b/www/manager6/lxc/Network.js new file mode 100644 index 00000000..7d152cc8 --- /dev/null +++ b/www/manager6/lxc/Network.js @@ -0,0 +1,554 @@ +Ext.define('PVE.lxc.NetworkInputPanel', { + extend: 'PVE.panel.InputPanel', + alias: 'widget.pveLxcNetworkInputPanel', + + insideWizard: false, + + setNodename: function(nodename) { + var me = this; + + if (!nodename || (me.nodename === nodename)) { + return; + } + + me.nodename = nodename; + + var bridgesel = me.query("[isFormField][name=bridge]")[0]; + bridgesel.setNodename(nodename); + }, + + onGetValues: function(values) { + var me = this; + + var id; + if (me.create) { + id = values.id; + delete values.id; + } else { + id = me.ifname; + } + + if (!id) { + return {}; + } + + var newdata = {}; + + if (values['ipv6mode'] !== 'static') + values['ip6'] = values['ipv6mode']; + if (values['ipv4mode'] !== 'static') + values['ip'] = values['ipv4mode'] + newdata[id] = PVE.Parser.printLxcNetwork(values); + return newdata; + }, + + initComponent : function() { + var me = this; + + if (!me.dataCache) { + throw "no dataCache specified"; + } + + var cdata = {}; + + if (me.insideWizard) { + me.ifname = 'net0'; + cdata.name = 'eth0'; + } + + if (!me.create) { + if (!me.ifname) { + throw "no interface name specified"; + } + if (!me.dataCache[me.ifname]) { + throw "no such interface '" + me.ifname + "'"; + } + + cdata = PVE.Parser.parseLxcNetwork(me.dataCache[me.ifname]); + } + + var i, netlist = []; + for (i = 0; i < 10; i++) { + netlist.push({ "name": "net" + i }); + } + + var netliststore = Ext.create('Ext.data.Store', { + fields: ['name'], + data: netlist + }); + + var ifselector = { + xtype: 'combobox', + fieldLabel: gettext('ID'), + store: netliststore, + editable: false, + name: 'id', + value: me.ifname, + disabled: !me.create, + queryMode: 'local', + displayField: 'name', + valueField: 'name', + validator: function(value) { + if (me.create && me.dataCache[value]) { + return "Network ID already in use"; + } + return true; + } + }; + + me.column1 = [ + ifselector, + { + xtype: 'textfield', + name: 'name', + height: 22, // hack: set same height as text fields + fieldLabel: gettext('Name') + ' (i.e. eth0)', + allowBlank: false, + value: cdata.name, + validator: function(value) { + var result = true; + Ext.Object.each(me.dataCache, function(key, netstr) { + if (!key.match(/^net\d+/) || key === me.ifname) { + return; // continue + } + var net = PVE.Parser.parseLxcNetwork(netstr); + if (net.name === value) { + result = "interface name already in use"; + return false; + } + }); + return result; + } + }, + { + xtype: 'textfield', + name: 'hwaddr', + fieldLabel: gettext('MAC address'), + vtype: 'MacAddress', + value: cdata.hwaddr, + allowBlank: me.create, + emptyText: 'auto' + }, + { + xtype: 'PVE.form.BridgeSelector', + name: 'bridge', + nodename: me.nodename, + fieldLabel: gettext('Bridge'), + value: cdata.bridge, + allowBlank: false + }, + { + xtype: 'pveVlanField', + name: 'tag', + value: cdata.tag, + }, + { + xtype: 'pvecheckbox', + fieldLabel: gettext('Firewall'), + name: 'firewall', + checked: cdata.firewall, + } + ]; + + var dhcp4 = (cdata.ip === 'dhcp'); + if (dhcp4) { + cdata.ip = ''; + cdata.gw = ''; + } + + var auto6 = (cdata.ip6 === 'auto'); + var dhcp6 = (cdata.ip6 === 'dhcp'); + if (auto6 || dhcp6) { + cdata.ip6 = ''; + cdata.gw6 = ''; + } + + me.column2 = [ + { + layout: { + type: 'hbox', + align: 'middle' + }, + border: false, + margin: '0 0 5 0', + height: 22, // hack: set same height as text fields + items: [ + { + xtype: 'label', + text: gettext('IPv4') + ':', + }, + { + xtype: 'radiofield', + boxLabel: gettext('Static'), + name: 'ipv4mode', + inputValue: 'static', + checked: !dhcp4, + margin: '0 0 0 10', + listeners: { + change: function(cb, value) { + me.down('field[name=ip]').setDisabled(!value); + me.down('field[name=gw]').setDisabled(!value); + } + } + }, + { + xtype: 'radiofield', + boxLabel: gettext('DHCP'), + name: 'ipv4mode', + inputValue: 'dhcp', + checked: dhcp4, + margin: '0 0 0 10' + } + ] + }, + { + xtype: 'textfield', + name: 'ip', + vtype: 'IPCIDRAddress', + value: cdata.ip, + disabled: dhcp4, + fieldLabel: gettext('IPv4/CIDR') + }, + { + xtype: 'textfield', + name: 'gw', + value: cdata.gw, + vtype: 'IPAddress', + disabled: dhcp4, + fieldLabel: gettext('Gateway') + ' (' + gettext('IPv4') +')', + margin: '0 0 3 0' // override bottom margin to account for the menuseparator + }, + { + xtype: 'menuseparator', + height: '3', + margin: '0' + }, + { + layout: { + type: 'hbox', + align: 'middle' + }, + border: false, + margin: '0 0 5 0', + height: 22, // hack: set same height as text fields + items: [ + { + xtype: 'label', + text: gettext('IPv6') + ':', + }, + { + xtype: 'radiofield', + boxLabel: gettext('Static'), + name: 'ipv6mode', + inputValue: 'static', + checked: !(auto6 || dhcp6), + margin: '0 0 0 10', + listeners: { + change: function(cb, value) { + me.down('field[name=ip6]').setDisabled(!value); + me.down('field[name=gw6]').setDisabled(!value); + } + } + }, + { + xtype: 'radiofield', + boxLabel: gettext('DHCP'), + name: 'ipv6mode', + inputValue: 'dhcp', + checked: dhcp6, + margin: '0 0 0 10' + }, + { + xtype: 'radiofield', + boxLabel: gettext('SLAAC'), + name: 'ipv6mode', + inputValue: 'auto', + checked: auto6, + margin: '0 0 0 10' + } + ] + }, + { + xtype: 'textfield', + name: 'ip6', + value: cdata.ip6, + vtype: 'IP6CIDRAddress', + disabled: (dhcp6 || auto6), + fieldLabel: gettext('IPv6/CIDR') + }, + { + xtype: 'textfield', + name: 'gw6', + vtype: 'IP6Address', + value: cdata.gw6, + disabled: (dhcp6 || auto6), + fieldLabel: gettext('Gateway') + ' (' + gettext('IPv6') +')' + } + ]; + + me.callParent(); + } +}); + +/*jslint confusion: true */ +Ext.define('PVE.lxc.NetworkEdit', { + extend: 'PVE.window.Edit', + + isAdd: true, + + initComponent : function() { + var me = this; + + if (!me.dataCache) { + throw "no dataCache specified"; + } + + if (!me.nodename) { + throw "no node name specified"; + } + + var ipanel = Ext.create('PVE.lxc.NetworkInputPanel', { + ifname: me.ifname, + nodename: me.nodename, + dataCache: me.dataCache, + create: me.create + }); + + Ext.apply(me, { + subject: gettext('Network Device') + ' (veth)', + digest: me.dataCache.digest, + items: [ ipanel ] + }); + + me.callParent(); + } +}); + +Ext.define('PVE.lxc.NetworkView', { + extend: 'Ext.grid.GridPanel', + alias: ['widget.pveLxcNetworkView'], + + dataCache: {}, // used to store result of last load + + load: function() { + var me = this; + + PVE.Utils.setErrorMask(me, true); + + PVE.Utils.API2Request({ + url: me.url, + failure: function(response, opts) { + PVE.Utils.setErrorMask(me, gettext('Error') + ': ' + response.htmlStatus); + }, + success: function(response, opts) { + PVE.Utils.setErrorMask(me, false); + var result = Ext.decode(response.responseText); + var data = result.data || {}; + me.dataCache = data; + var records = []; + Ext.Object.each(data, function(key, value) { + if (!key.match(/^net\d+/)) { + return; // continue + } + var net = PVE.Parser.parseLxcNetwork(value); + net.id = key; + records.push(net); + }); + me.store.loadData(records); + } + }); + }, + + initComponent : function() { + var me = this; + + var nodename = me.pveSelNode.data.node; + if (!nodename) { + throw "no node name specified"; + } + + var vmid = me.pveSelNode.data.vmid; + if (!vmid) { + throw "no VM ID specified"; + } + + var caps = Ext.state.Manager.get('GuiCap'); + + me.url = '/nodes/' + nodename + '/lxc/' + vmid + '/config'; + + var store = new Ext.data.Store({ + model: 'pve-lxc-network', + sorters: [ + { + property : 'id', + direction: 'ASC' + } + ] + }); + + var sm = Ext.create('Ext.selection.RowModel', {}); + + var remove_btn = new PVE.button.Button({ + text: gettext('Remove'), + disabled: true, + selModel: sm, + enableFn: function(rec) { + return !!caps.vms['VM.Config.Network']; + }, + confirmMsg: function (rec) { + return Ext.String.format(gettext('Are you sure you want to remove entry {0}'), + "'" + rec.data.id + "'"); + }, + handler: function(btn, event, rec) { + PVE.Utils.API2Request({ + url: me.url, + waitMsgTarget: me, + method: 'PUT', + params: { 'delete': rec.data.id, digest: me.dataCache.digest }, + callback: function() { + me.load(); + }, + failure: function (response, opts) { + Ext.Msg.alert(gettext('Error'), response.htmlStatus); + } + }); + } + }); + + var run_editor = function() { + var rec = sm.getSelection()[0]; + if (!rec) { + return; + } + + if (!caps.vms['VM.Config.Network']) { + return false; + } + + var win = Ext.create('PVE.lxc.NetworkEdit', { + url: me.url, + nodename: nodename, + dataCache: me.dataCache, + ifname: rec.data.id + }); + win.on('destroy', me.load, me); + win.show(); + }; + + var edit_btn = new PVE.button.Button({ + text: gettext('Edit'), + selModel: sm, + disabled: true, + enableFn: function(rec) { + if (!caps.vms['VM.Config.Network']) { + return false; + } + return true; + }, + handler: run_editor + }); + + Ext.applyIf(me, { + store: store, + selModel: sm, + stateful: false, + tbar: [ + { + text: gettext('Add'), + disabled: !caps.vms['VM.Config.Network'], + handler: function() { + var win = Ext.create('PVE.lxc.NetworkEdit', { + url: me.url, + nodename: nodename, + create: true, + dataCache: me.dataCache + }); + win.on('destroy', me.load, me); + win.show(); + } + }, + remove_btn, + edit_btn + ], + columns: [ + { + header: gettext('ID'), + width: 50, + dataIndex: 'id' + }, + { + header: gettext('Name'), + width: 80, + dataIndex: 'name' + }, + { + header: gettext('Bridge'), + width: 80, + dataIndex: 'bridge' + }, + { + header: gettext('Firewall'), + width: 80, + dataIndex: 'firewall', + renderer: PVE.Utils.format_boolean + }, + { + header: gettext('VLAN Tag'), + width: 80, + dataIndex: 'tag' + }, + { + header: gettext('MAC address'), + width: 110, + dataIndex: 'hwaddr' + }, + { + header: gettext('IP address'), + width: 150, + dataIndex: 'ip', + renderer: function(value, metaData, rec) { + if (rec.data.ip && rec.data.ip6) { + return rec.data.ip + "
" + rec.data.ip6; + } else if (rec.data.ip6) { + return rec.data.ip6; + } else { + return rec.data.ip; + } + } + }, + { + header: gettext('Gateway'), + width: 150, + dataIndex: 'gw', + renderer: function(value, metaData, rec) { + if (rec.data.gw && rec.data.gw6) { + return rec.data.gw + "
" + rec.data.gw6; + } else if (rec.data.gw6) { + return rec.data.gw6; + } else { + return rec.data.gw; + } + } + } + ], + listeners: { + show: me.load, + itemdblclick: run_editor + } + }); + + me.callParent(); + + me.load(); + } +}, function() { + + Ext.define('pve-lxc-network', { + extend: "Ext.data.Model", + proxy: { type: 'memory' }, + fields: [ 'id', 'name', 'hwaddr', 'bridge', + 'ip', 'gw', 'ip6', 'gw6', 'tag', 'firewall' ] + }); + +}); +