1 Ext
.define('proxmox-networks', {
2 extend
: 'Ext.data.Model',
23 Ext
.define('Proxmox.node.NetworkView', {
24 extend
: 'Ext.panel.Panel',
26 alias
: ['widget.proxmoxNodeNetworkView'],
28 // defines what types of network devices we want to create
29 // order is always the same
30 types
: ['bridge', 'bond', 'vlan', 'ovs'],
34 initComponent: function() {
38 throw "no node name specified";
41 let baseUrl
= '/nodes/' + me
.nodename
+ '/network';
43 let store
= Ext
.create('Ext.data.Store', {
44 model
: 'proxmox-networks',
47 url
: '/api2/json' + baseUrl
,
57 let reload = function() {
58 let changeitem
= me
.down('#changes');
59 let apply_btn
= me
.down('#apply');
60 let revert_btn
= me
.down('#revert');
61 Proxmox
.Utils
.API2Request({
63 failure: function(response
, opts
) {
65 Proxmox
.Utils
.setErrorMask(me
, response
.htmlStatus
);
66 changeitem
.update('');
67 changeitem
.setHidden(true);
69 success: function(response
, opts
) {
70 let result
= Ext
.decode(response
.responseText
);
71 store
.loadData(result
.data
);
72 let changes
= result
.changes
;
73 if (changes
=== undefined || changes
=== '') {
74 changes
= gettext("No changes");
75 changeitem
.setHidden(true);
76 apply_btn
.setDisabled(true);
77 revert_btn
.setDisabled(true);
79 changeitem
.update("<pre>" + Ext
.htmlEncode(changes
) + "</pre>");
80 changeitem
.setHidden(false);
81 apply_btn
.setDisabled(false);
82 revert_btn
.setDisabled(false);
88 let run_editor = function() {
89 let grid
= me
.down('gridpanel');
90 let sm
= grid
.getSelectionModel();
91 let rec
= sm
.getSelection()[0];
96 let win
= Ext
.create('Proxmox.node.NetworkEdit', {
97 nodename
: me
.nodename
,
98 iface
: rec
.data
.iface
,
99 iftype
: rec
.data
.type
,
102 win
.on('destroy', reload
);
105 let edit_btn
= new Ext
.Button({
106 text
: gettext('Edit'),
111 let del_btn
= new Ext
.Button({
112 text
: gettext('Remove'),
114 handler: function() {
115 let grid
= me
.down('gridpanel');
116 let sm
= grid
.getSelectionModel();
117 let rec
= sm
.getSelection()[0];
122 let iface
= rec
.data
.iface
;
124 Proxmox
.Utils
.API2Request({
125 url
: baseUrl
+ '/' + iface
,
128 callback: function() {
131 failure: function(response
, opts
) {
132 Ext
.Msg
.alert(gettext('Error'), response
.htmlStatus
);
138 let apply_btn
= Ext
.create('Proxmox.button.Button', {
139 text
: gettext('Apply Configuration'),
142 confirmMsg
: 'Do you want to apply pending network changes?',
143 hidden
: !me
.showApplyBtn
,
144 handler: function() {
145 Proxmox
.Utils
.API2Request({
149 success: function(response
, opts
) {
150 let upid
= response
.result
.data
;
152 let win
= Ext
.create('Proxmox.window.TaskProgress', {
158 failure: function(response
, opts
) {
159 Ext
.Msg
.alert(gettext('Error'), response
.htmlStatus
);
165 let set_button_status = function() {
166 let grid
= me
.down('gridpanel');
167 let sm
= grid
.getSelectionModel();
168 let rec
= sm
.getSelection()[0];
170 edit_btn
.setDisabled(!rec
);
171 del_btn
.setDisabled(!rec
);
174 let render_ports = function(value
, metaData
, record
) {
175 if (value
=== 'bridge') {
176 return record
.data
.bridge_ports
;
177 } else if (value
=== 'bond') {
178 return record
.data
.slaves
;
179 } else if (value
=== 'OVSBridge') {
180 return record
.data
.ovs_ports
;
181 } else if (value
=== 'OVSBond') {
182 return record
.data
.ovs_bonds
;
187 let find_next_iface_id = function(prefix
) {
189 for (next
= 0; next
<= 9999; next
++) {
190 if (!store
.getById(prefix
+ next
.toString())) {
194 return prefix
+ next
.toString();
199 if (me
.types
.indexOf('bridge') !== -1) {
201 text
: Proxmox
.Utils
.render_network_iface_type('bridge'),
202 handler: function() {
203 let win
= Ext
.create('Proxmox.node.NetworkEdit', {
204 nodename
: me
.nodename
,
206 iface_default
: find_next_iface_id('vmbr'),
207 onlineHelp
: 'sysadmin_network_configuration',
209 win
.on('destroy', reload
);
215 if (me
.types
.indexOf('bond') !== -1) {
217 text
: Proxmox
.Utils
.render_network_iface_type('bond'),
218 handler: function() {
219 let win
= Ext
.create('Proxmox.node.NetworkEdit', {
220 nodename
: me
.nodename
,
222 iface_default
: find_next_iface_id('bond'),
223 onlineHelp
: 'sysadmin_network_configuration',
225 win
.on('destroy', reload
);
231 if (me
.types
.indexOf('vlan') !== -1) {
233 text
: Proxmox
.Utils
.render_network_iface_type('vlan'),
234 handler: function() {
235 let win
= Ext
.create('Proxmox.node.NetworkEdit', {
236 nodename
: me
.nodename
,
238 iface_default
: 'interfaceX.1',
239 onlineHelp
: 'sysadmin_network_configuration',
241 win
.on('destroy', reload
);
247 if (me
.types
.indexOf('ovs') !== -1) {
248 if (menu_items
.length
> 0) {
249 menu_items
.push({ xtype
: 'menuseparator' });
254 text
: Proxmox
.Utils
.render_network_iface_type('OVSBridge'),
255 handler: function() {
256 let win
= Ext
.create('Proxmox.node.NetworkEdit', {
257 nodename
: me
.nodename
,
259 iface_default
: find_next_iface_id('vmbr'),
261 win
.on('destroy', reload
);
266 text
: Proxmox
.Utils
.render_network_iface_type('OVSBond'),
267 handler: function() {
268 let win
= Ext
.create('Proxmox.node.NetworkEdit', {
269 nodename
: me
.nodename
,
271 iface_default
: find_next_iface_id('bond'),
273 win
.on('destroy', reload
);
278 text
: Proxmox
.Utils
.render_network_iface_type('OVSIntPort'),
279 handler: function() {
280 let win
= Ext
.create('Proxmox.node.NetworkEdit', {
281 nodename
: me
.nodename
,
282 iftype
: 'OVSIntPort',
284 win
.on('destroy', reload
);
291 let renderer_generator = function(fieldname
) {
292 return function(val
, metaData
, rec
) {
294 if (rec
.data
[fieldname
]) {
295 tmp
.push(rec
.data
[fieldname
]);
297 if (rec
.data
[fieldname
+ '6']) {
298 tmp
.push(rec
.data
[fieldname
+ '6']);
300 return tmp
.join('<br>') || '';
308 text
: gettext('Create'),
315 text
: gettext('Revert'),
317 handler: function() {
318 Proxmox
.Utils
.API2Request({
322 callback: function() {
325 failure: function(response
, opts
) {
326 Ext
.Msg
.alert(gettext('Error'), response
.htmlStatus
);
340 stateId
: 'grid-node-network',
346 header
: gettext('Name'),
351 header
: gettext('Type'),
354 renderer
: Proxmox
.Utils
.render_network_iface_type
,
358 xtype
: 'booleancolumn',
359 header
: gettext('Active'),
363 trueText
: Proxmox
.Utils
.yesText
,
364 falseText
: Proxmox
.Utils
.noText
,
365 undefinedText
: Proxmox
.Utils
.noText
,
368 xtype
: 'booleancolumn',
369 header
: gettext('Autostart'),
372 dataIndex
: 'autostart',
373 trueText
: Proxmox
.Utils
.yesText
,
374 falseText
: Proxmox
.Utils
.noText
,
375 undefinedText
: Proxmox
.Utils
.noText
,
378 xtype
: 'booleancolumn',
379 header
: gettext('VLAN aware'),
382 dataIndex
: 'bridge_vlan_aware',
383 trueText
: Proxmox
.Utils
.yesText
,
384 falseText
: Proxmox
.Utils
.noText
,
385 undefinedText
: Proxmox
.Utils
.noText
,
388 header
: gettext('Ports/Slaves'),
390 renderer
: render_ports
,
393 header
: gettext('Bond Mode'),
394 dataIndex
: 'bond_mode',
395 renderer
: Proxmox
.Utils
.render_bond_mode
,
398 header
: gettext('Hash Policy'),
400 dataIndex
: 'bond_xmit_hash_policy',
403 header
: gettext('IP address'),
407 dataIndex
: 'address',
408 renderer
: renderer_generator('address'),
411 header
: gettext('Subnet mask'),
415 dataIndex
: 'netmask',
416 renderer
: renderer_generator('netmask'),
419 header
: gettext('CIDR'),
423 renderer
: renderer_generator('cidr'),
426 header
: gettext('Gateway'),
429 dataIndex
: 'gateway',
430 renderer
: renderer_generator('gateway'),
433 header
: gettext('Comment'),
434 dataIndex
: 'comments',
436 renderer
: Ext
.String
.htmlEncode
,
440 selectionchange
: set_button_status
,
441 itemdblclick
: run_editor
,
451 gettext('Pending changes') + ' (' +
452 gettext("Either reboot or use 'Apply Configuration' (needs ifupdown2) to activate") + ')',
457 html
: gettext("No changes"),