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