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