]> git.proxmox.com Git - proxmox-widget-toolkit.git/blame - node/NetworkView.js
refactor info/link extraction from onlinehelp to utils
[proxmox-widget-toolkit.git] / node / NetworkView.js
CommitLineData
a58001dd
DM
1Ext.define('proxmox-networks', {
2 extend: 'Ext.data.Model',
3 fields: [
4 'iface', 'type', 'active', 'autostart',
5 'bridge_ports', 'slaves',
6 'address', 'netmask', 'gateway',
7 'address6', 'netmask6', 'gateway6',
d0c2b878 8 'cidr', 'cidr6',
a58001dd
DM
9 'comments'
10 ],
11 idProperty: 'iface'
12});
13
14Ext.define('Proxmox.node.NetworkView', {
15 extend: 'Ext.panel.Panel',
16
17 alias: ['widget.proxmoxNodeNetworkView'],
18
7c0e4c25
DC
19 // defines what types of network devices we want to create
20 // order is always the same
21 types: ['bridge', 'bond', 'ovs'],
22
a58001dd
DM
23 initComponent : function() {
24 var me = this;
25
26 if (!me.nodename) {
27 throw "no node name specified";
28 }
29
30 var baseUrl = '/nodes/' + me.nodename + '/network';
31
32 var store = Ext.create('Ext.data.Store', {
33 model: 'proxmox-networks',
34 proxy: {
35 type: 'proxmox',
36 url: '/api2/json' + baseUrl
37 },
38 sorters: [
39 {
40 property : 'iface',
41 direction: 'ASC'
42 }
43 ]
44 });
45
46 var reload = function() {
47 var changeitem = me.down('#changes');
48 Proxmox.Utils.API2Request({
49 url: baseUrl,
50 failure: function(response, opts) {
a58001dd 51 store.loadData({});
b81cf173
DM
52 Proxmox.Utils.setErrorMask(me, response.htmlStatus);
53 changeitem.update('');
89f57452 54 changeitem.setHidden(true);
a58001dd
DM
55 },
56 success: function(response, opts) {
57 var result = Ext.decode(response.responseText);
58 store.loadData(result.data);
59 var changes = result.changes;
60 if (changes === undefined || changes === '') {
61 changes = gettext("No changes");
89f57452
DM
62 changeitem.setHidden(true);
63 } else {
64 changeitem.update("<pre>" + Ext.htmlEncode(changes) + "</pre>");
65 changeitem.setHidden(false);
a58001dd 66 }
a58001dd
DM
67 }
68 });
69 };
70
71 var run_editor = function() {
72 var grid = me.down('gridpanel');
73 var sm = grid.getSelectionModel();
74 var rec = sm.getSelection()[0];
75 if (!rec) {
76 return;
77 }
78
79 var win = Ext.create('Proxmox.node.NetworkEdit', {
80 nodename: me.nodename,
81 iface: rec.data.iface,
82 iftype: rec.data.type
83 });
84 win.show();
85 win.on('destroy', reload);
86 };
87
88 var edit_btn = new Ext.Button({
89 text: gettext('Edit'),
90 disabled: true,
91 handler: run_editor
92 });
93
94 var del_btn = new Ext.Button({
95 text: gettext('Remove'),
96 disabled: true,
97 handler: function(){
98 var grid = me.down('gridpanel');
99 var sm = grid.getSelectionModel();
100 var rec = sm.getSelection()[0];
101 if (!rec) {
102 return;
103 }
104
105 var iface = rec.data.iface;
106
107 Proxmox.Utils.API2Request({
108 url: baseUrl + '/' + iface,
109 method: 'DELETE',
110 waitMsgTarget: me,
111 callback: function() {
112 reload();
113 },
114 failure: function(response, opts) {
115 Ext.Msg.alert(gettext('Error'), response.htmlStatus);
116 }
117 });
118 }
119 });
120
121 var set_button_status = function() {
122 var grid = me.down('gridpanel');
123 var sm = grid.getSelectionModel();
124 var rec = sm.getSelection()[0];
125
126 edit_btn.setDisabled(!rec);
127 del_btn.setDisabled(!rec);
128 };
129
a58001dd
DM
130 var render_ports = function(value, metaData, record) {
131 if (value === 'bridge') {
132 return record.data.bridge_ports;
133 } else if (value === 'bond') {
134 return record.data.slaves;
135 } else if (value === 'OVSBridge') {
136 return record.data.ovs_ports;
137 } else if (value === 'OVSBond') {
138 return record.data.ovs_bonds;
139 }
140 };
141
142 var find_next_iface_id = function(prefix) {
143 var next;
144 for (next = 0; next <= 9999; next++) {
145 if (!store.getById(prefix + next.toString())) {
146 break;
147 }
148 }
149 return prefix + next.toString();
150 };
151
7c0e4c25
DC
152 var menu_items = [];
153
154 if (me.types.indexOf('bridge') !== -1) {
155 menu_items.push({
156 text: Proxmox.Utils.render_network_iface_type('bridge'),
157 handler: function() {
158 var win = Ext.create('Proxmox.node.NetworkEdit', {
159 nodename: me.nodename,
160 iftype: 'bridge',
161 iface_default: find_next_iface_id('vmbr')
162 });
163 win.on('destroy', reload);
164 win.show();
165 }
166 });
167 }
168
169 if (me.types.indexOf('bond') !== -1) {
170 menu_items.push({
171 text: Proxmox.Utils.render_network_iface_type('bond'),
172 handler: function() {
173 var win = Ext.create('Proxmox.node.NetworkEdit', {
174 nodename: me.nodename,
175 iftype: 'bond',
176 iface_default: find_next_iface_id('bond')
177 });
178 win.on('destroy', reload);
179 win.show();
180 }
181 });
182 }
183
184 if (me.types.indexOf('ovs') !== -1) {
185 if (menu_items.length > 0) {
186 menu_items.push({ xtype: 'menuseparator' });
187 }
188
189 menu_items.push(
190 {
191 text: Proxmox.Utils.render_network_iface_type('OVSBridge'),
192 handler: function() {
193 var win = Ext.create('Proxmox.node.NetworkEdit', {
194 nodename: me.nodename,
195 iftype: 'OVSBridge',
196 iface_default: find_next_iface_id('vmbr')
197 });
198 win.on('destroy', reload);
199 win.show();
200 }
201 },
202 {
203 text: Proxmox.Utils.render_network_iface_type('OVSBond'),
204 handler: function() {
205 var win = Ext.create('Proxmox.node.NetworkEdit', {
206 nodename: me.nodename,
207 iftype: 'OVSBond',
208 iface_default: find_next_iface_id('bond')
209 });
210 win.on('destroy', reload);
211 win.show();
212 }
213 },
214 {
215 text: Proxmox.Utils.render_network_iface_type('OVSIntPort'),
216 handler: function() {
217 var win = Ext.create('Proxmox.node.NetworkEdit', {
218 nodename: me.nodename,
219 iftype: 'OVSIntPort'
220 });
221 win.on('destroy', reload);
222 win.show();
223 }
224 }
225 );
226 }
227
d0c2b878
DC
228 var renderer_generator = function(fieldname) {
229 return function(val, metaData, rec) {
230 var tmp = [];
231 if (rec.data[fieldname]) {
232 tmp.push(rec.data[fieldname]);
233 }
234 if (rec.data[fieldname + '6']) {
235 tmp.push(rec.data[fieldname + '6']);
236 }
237 return tmp.join('<br>') || '';
238 };
239 };
240
a58001dd
DM
241 Ext.apply(me, {
242 layout: 'border',
243 tbar: [
244 {
245 text: gettext('Create'),
7c0e4c25 246 menu: {
a58001dd 247 plain: true,
7c0e4c25
DC
248 items: menu_items
249 }
a58001dd
DM
250 }, ' ',
251 {
252 text: gettext('Revert'),
253 handler: function() {
254 Proxmox.Utils.API2Request({
255 url: baseUrl,
256 method: 'DELETE',
257 waitMsgTarget: me,
258 callback: function() {
259 reload();
260 },
261 failure: function(response, opts) {
262 Ext.Msg.alert(gettext('Error'), response.htmlStatus);
263 }
264 });
265 }
266 },
267 edit_btn,
268 del_btn
269 ],
270 items: [
271 {
272 xtype: 'gridpanel',
273 stateful: true,
274 stateId: 'grid-node-network',
275 store: store,
276 region: 'center',
277 border: false,
278 columns: [
279 {
280 header: gettext('Name'),
a58001dd
DM
281 sortable: true,
282 dataIndex: 'iface'
283 },
284 {
285 header: gettext('Type'),
a58001dd 286 sortable: true,
869439b1 287 width: 120,
a58001dd
DM
288 renderer: Proxmox.Utils.render_network_iface_type,
289 dataIndex: 'type'
290 },
291 {
292 xtype: 'booleancolumn',
293 header: gettext('Active'),
294 width: 80,
295 sortable: true,
296 dataIndex: 'active',
9b575917
WL
297 trueText: Proxmox.Utils.yesText,
298 falseText: Proxmox.Utils.noText,
299 undefinedText: Proxmox.Utils.noText,
a58001dd
DM
300 },
301 {
302 xtype: 'booleancolumn',
303 header: gettext('Autostart'),
304 width: 80,
305 sortable: true,
306 dataIndex: 'autostart',
9b575917
WL
307 trueText: Proxmox.Utils.yesText,
308 falseText: Proxmox.Utils.noText,
309 undefinedText: Proxmox.Utils.noText
a58001dd 310 },
8947a4fc
WL
311 {
312 xtype: 'booleancolumn',
313 header: gettext('VLAN aware'),
314 width: 80,
315 sortable: true,
316 dataIndex: 'bridge_vlan_aware',
317 trueText: Proxmox.Utils.yesText,
318 falseText: Proxmox.Utils.noText,
319 undefinedText: Proxmox.Utils.noText
320 },
a58001dd
DM
321 {
322 header: gettext('Ports/Slaves'),
323 dataIndex: 'type',
324 renderer: render_ports
325 },
326 {
327 header: gettext('IP address'),
328 sortable: true,
869439b1 329 width: 120,
a58001dd 330 dataIndex: 'address',
d0c2b878 331 renderer: renderer_generator('address'),
a58001dd
DM
332 },
333 {
334 header: gettext('Subnet mask'),
869439b1 335 width: 120,
a58001dd 336 sortable: true,
d0c2b878
DC
337 dataIndex: 'netmask',
338 renderer: renderer_generator('netmask'),
339 },
340 {
341 header: gettext('CIDR'),
342 width: 120,
343 sortable: true,
344 dataIndex: 'cidr',
345 renderer: renderer_generator('cidr'),
a58001dd
DM
346 },
347 {
348 header: gettext('Gateway'),
869439b1 349 width: 120,
a58001dd
DM
350 sortable: true,
351 dataIndex: 'gateway',
d0c2b878 352 renderer: renderer_generator('gateway'),
a58001dd
DM
353 },
354 {
355 header: gettext('Comment'),
356 dataIndex: 'comments',
869439b1 357 flex: 1,
a58001dd
DM
358 renderer: Ext.String.htmlEncode
359 }
360 ],
361 listeners: {
362 selectionchange: set_button_status,
363 itemdblclick: run_editor
364 }
365 },
366 {
367 border: false,
368 region: 'south',
369 autoScroll: true,
89f57452 370 hidden: true,
a58001dd
DM
371 itemId: 'changes',
372 tbar: [
373 gettext('Pending changes') + ' (' +
374 gettext('Please reboot to activate changes') + ')'
375 ],
376 split: true,
377 bodyPadding: 5,
378 flex: 0.6,
379 html: gettext("No changes")
380 }
381 ],
a58001dd
DM
382 });
383
384 me.callParent();
1a68e95d 385 reload();
a58001dd
DM
386 }
387});