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