]>
Commit | Line | Data |
---|---|---|
1774f148 DC |
1 | Ext.define('pve-fw-ipsets', { |
2 | extend: 'Ext.data.Model', | |
8058410f | 3 | fields: ['name', 'comment', 'digest'], |
f6710aac | 4 | idProperty: 'name', |
1774f148 DC |
5 | }); |
6 | ||
03ab9fba DM |
7 | Ext.define('PVE.IPSetList', { |
8 | extend: 'Ext.grid.Panel', | |
9 | alias: 'widget.pveIPSetList', | |
10 | ||
123e1c80 DC |
11 | stateful: true, |
12 | stateId: 'grid-firewall-ipsetlist', | |
13 | ||
03ab9fba DM |
14 | ipset_panel: undefined, |
15 | ||
16 | base_url: undefined, | |
17 | ||
18 | addBtn: undefined, | |
19 | removeBtn: undefined, | |
20 | editBtn: undefined, | |
21 | ||
22 | initComponent: function() { | |
03ab9fba DM |
23 | var me = this; |
24 | ||
202298c1 | 25 | if (typeof me.ipset_panel === 'undefined') { |
03ab9fba DM |
26 | throw "no rule panel specified"; |
27 | } | |
28 | ||
202298c1 | 29 | if (typeof me.ipset_panel === 'undefined') { |
03ab9fba DM |
30 | throw "no base_url specified"; |
31 | } | |
32 | ||
33 | var store = new Ext.data.Store({ | |
1774f148 | 34 | model: 'pve-fw-ipsets', |
03ab9fba | 35 | proxy: { |
56a353b9 | 36 | type: 'proxmox', |
f6710aac | 37 | url: "/api2/json" + me.base_url, |
03ab9fba | 38 | }, |
03ab9fba DM |
39 | sorters: { |
40 | property: 'name', | |
392e3cf1 | 41 | direction: 'ASC', |
f6710aac | 42 | }, |
03ab9fba DM |
43 | }); |
44 | ||
2e37e779 | 45 | var caps = Ext.state.Manager.get('GuiCap'); |
1056e10c | 46 | let canEdit = !!caps.vms['VM.Config.Network'] || !!caps.dc['Sys.Modify'] || !!caps.nodes['Sys.Modify']; |
2e37e779 | 47 | |
03ab9fba DM |
48 | var sm = Ext.create('Ext.selection.RowModel', {}); |
49 | ||
50 | var reload = function() { | |
51 | var oldrec = sm.getSelection()[0]; | |
52 | store.load(function(records, operation, success) { | |
53 | if (oldrec) { | |
8267aa63 | 54 | var rec = store.findRecord('name', oldrec.data.name, 0, false, true, true); |
03ab9fba DM |
55 | if (rec) { |
56 | sm.select(rec); | |
57 | } | |
58 | } | |
59 | }); | |
60 | }; | |
61 | ||
62 | var run_editor = function() { | |
63 | var rec = sm.getSelection()[0]; | |
1056e10c | 64 | if (!rec || !canEdit) { |
03ab9fba DM |
65 | return; |
66 | } | |
9fccc702 | 67 | var win = Ext.create('Proxmox.window.Edit', { |
03ab9fba DM |
68 | subject: "IPSet '" + rec.data.name + "'", |
69 | url: me.base_url, | |
70 | method: 'POST', | |
71 | digest: rec.data.digest, | |
72 | items: [ | |
73 | { | |
74 | xtype: 'hiddenfield', | |
75 | name: 'rename', | |
f6710aac | 76 | value: rec.data.name, |
03ab9fba DM |
77 | }, |
78 | { | |
79 | xtype: 'textfield', | |
80 | name: 'name', | |
81 | value: rec.data.name, | |
82 | fieldLabel: gettext('Name'), | |
f6710aac | 83 | allowBlank: false, |
03ab9fba DM |
84 | }, |
85 | { | |
86 | xtype: 'textfield', | |
87 | name: 'comment', | |
88 | value: rec.data.comment, | |
f6710aac TL |
89 | fieldLabel: gettext('Comment'), |
90 | }, | |
91 | ], | |
03ab9fba DM |
92 | }); |
93 | win.show(); | |
94 | win.on('destroy', reload); | |
95 | }; | |
96 | ||
5720fafa | 97 | me.editBtn = new Proxmox.button.Button({ |
03ab9fba DM |
98 | text: gettext('Edit'), |
99 | disabled: true, | |
1056e10c | 100 | enableFn: rec => canEdit, |
03ab9fba | 101 | selModel: sm, |
f6710aac | 102 | handler: run_editor, |
03ab9fba DM |
103 | }); |
104 | ||
5720fafa | 105 | me.addBtn = new Proxmox.button.Button({ |
03ab9fba DM |
106 | text: gettext('Create'), |
107 | handler: function() { | |
108 | sm.deselectAll(); | |
9fccc702 | 109 | var win = Ext.create('Proxmox.window.Edit', { |
03ab9fba DM |
110 | subject: 'IPSet', |
111 | url: me.base_url, | |
112 | method: 'POST', | |
113 | items: [ | |
114 | { | |
115 | xtype: 'textfield', | |
116 | name: 'name', | |
117 | value: '', | |
118 | fieldLabel: gettext('Name'), | |
f6710aac | 119 | allowBlank: false, |
03ab9fba DM |
120 | }, |
121 | { | |
122 | xtype: 'textfield', | |
123 | name: 'comment', | |
124 | value: '', | |
f6710aac TL |
125 | fieldLabel: gettext('Comment'), |
126 | }, | |
127 | ], | |
03ab9fba DM |
128 | }); |
129 | win.show(); | |
130 | win.on('destroy', reload); | |
f6710aac | 131 | }, |
03ab9fba DM |
132 | }); |
133 | ||
3b1ca3ff | 134 | me.removeBtn = Ext.create('Proxmox.button.StdRemoveButton', { |
1056e10c | 135 | enableFn: rec => canEdit, |
03ab9fba | 136 | selModel: sm, |
3b1ca3ff | 137 | baseurl: me.base_url + '/', |
f6710aac | 138 | callback: reload, |
03ab9fba DM |
139 | }); |
140 | ||
141 | Ext.apply(me, { | |
142 | store: store, | |
8058410f | 143 | tbar: ['<b>IPSet:</b>', me.addBtn, me.removeBtn, me.editBtn], |
03ab9fba DM |
144 | selModel: sm, |
145 | columns: [ | |
123e1c80 | 146 | { header: 'IPSet', dataIndex: 'name', width: '100' }, |
f6710aac | 147 | { header: gettext('Comment'), dataIndex: 'comment', renderer: Ext.String.htmlEncode, flex: 1 }, |
03ab9fba DM |
148 | ], |
149 | listeners: { | |
150 | itemdblclick: run_editor, | |
202298c1 | 151 | select: function(_, rec) { |
03ab9fba DM |
152 | var url = me.base_url + '/' + rec.data.name; |
153 | me.ipset_panel.setBaseUrl(url); | |
154 | }, | |
155 | deselect: function() { | |
156 | me.ipset_panel.setBaseUrl(undefined); | |
157 | }, | |
f6710aac TL |
158 | show: reload, |
159 | }, | |
03ab9fba DM |
160 | }); |
161 | ||
1056e10c | 162 | if (!canEdit) { |
2e37e779 AD |
163 | me.addBtn.setDisabled(true); |
164 | } | |
165 | ||
03ab9fba DM |
166 | me.callParent(); |
167 | ||
168 | store.load(); | |
f6710aac | 169 | }, |
03ab9fba DM |
170 | }); |
171 | ||
172 | Ext.define('PVE.IPSetCidrEdit', { | |
9fccc702 | 173 | extend: 'Proxmox.window.Edit', |
03ab9fba DM |
174 | |
175 | cidr: undefined, | |
176 | ||
8058410f | 177 | initComponent: function() { |
03ab9fba DM |
178 | var me = this; |
179 | ||
53e3ea84 | 180 | me.isCreate = me.cidr === undefined; |
03ab9fba DM |
181 | |
182 | ||
d5e771ce | 183 | if (me.isCreate) { |
03ab9fba DM |
184 | me.url = '/api2/extjs' + me.base_url; |
185 | me.method = 'POST'; | |
186 | } else { | |
187 | me.url = '/api2/extjs' + me.base_url + '/' + me.cidr; | |
188 | me.method = 'PUT'; | |
189 | } | |
190 | ||
191 | var column1 = []; | |
192 | ||
d5e771ce | 193 | if (me.isCreate) { |
03ab9fba DM |
194 | if (!me.list_refs_url) { |
195 | throw "no alias_base_url specified"; | |
196 | } | |
197 | ||
198 | column1.push({ | |
199 | xtype: 'pveIPRefSelector', | |
200 | name: 'cidr', | |
201 | ref_type: 'alias', | |
202 | autoSelect: false, | |
203 | editable: true, | |
204 | base_url: me.list_refs_url, | |
205 | value: '', | |
f6710aac | 206 | fieldLabel: gettext('IP/CIDR'), |
03ab9fba DM |
207 | }); |
208 | } else { | |
209 | column1.push({ | |
210 | xtype: 'displayfield', | |
211 | name: 'cidr', | |
03ab9fba | 212 | value: '', |
f6710aac | 213 | fieldLabel: gettext('IP/CIDR'), |
03ab9fba DM |
214 | }); |
215 | } | |
216 | ||
ef4ef788 | 217 | var ipanel = Ext.create('Proxmox.panel.InputPanel', { |
d5e771ce | 218 | isCreate: me.isCreate, |
03ab9fba DM |
219 | column1: column1, |
220 | column2: [ | |
221 | { | |
896c0d50 | 222 | xtype: 'proxmoxcheckbox', |
03ab9fba DM |
223 | name: 'nomatch', |
224 | checked: false, | |
03ab9fba | 225 | uncheckedValue: 0, |
f6710aac TL |
226 | fieldLabel: 'nomatch', |
227 | }, | |
03ab9fba DM |
228 | ], |
229 | columnB: [ | |
230 | { | |
231 | xtype: 'textfield', | |
232 | name: 'comment', | |
233 | value: '', | |
f6710aac TL |
234 | fieldLabel: gettext('Comment'), |
235 | }, | |
236 | ], | |
03ab9fba DM |
237 | }); |
238 | ||
239 | Ext.apply(me, { | |
240 | subject: gettext('IP/CIDR'), | |
8058410f | 241 | items: [ipanel], |
03ab9fba DM |
242 | }); |
243 | ||
244 | me.callParent(); | |
245 | ||
d5e771ce | 246 | if (!me.isCreate) { |
03ab9fba | 247 | me.load({ |
8058410f | 248 | success: function(response, options) { |
03ab9fba DM |
249 | var values = response.result.data; |
250 | ipanel.setValues(values); | |
f6710aac | 251 | }, |
03ab9fba DM |
252 | }); |
253 | } | |
f6710aac | 254 | }, |
03ab9fba DM |
255 | }); |
256 | ||
257 | Ext.define('PVE.IPSetGrid', { | |
258 | extend: 'Ext.grid.Panel', | |
259 | alias: 'widget.pveIPSetGrid', | |
260 | ||
123e1c80 DC |
261 | stateful: true, |
262 | stateId: 'grid-firewall-ipsets', | |
263 | ||
03ab9fba DM |
264 | base_url: undefined, |
265 | list_refs_url: undefined, | |
266 | ||
267 | addBtn: undefined, | |
268 | removeBtn: undefined, | |
269 | editBtn: undefined, | |
270 | ||
271 | setBaseUrl: function(url) { | |
272 | var me = this; | |
273 | ||
274 | me.base_url = url; | |
275 | ||
276 | if (url === undefined) { | |
277 | me.addBtn.setDisabled(true); | |
278 | me.store.removeAll(); | |
279 | } else { | |
1056e10c | 280 | if (me.canEdit) { |
2e37e779 AD |
281 | me.addBtn.setDisabled(false); |
282 | } | |
3b1ca3ff | 283 | me.removeBtn.baseurl = url + '/'; |
03ab9fba | 284 | me.store.setProxy({ |
56a353b9 | 285 | type: 'proxmox', |
f6710aac | 286 | url: '/api2/json' + url, |
03ab9fba DM |
287 | }); |
288 | ||
289 | me.store.load(); | |
290 | } | |
291 | }, | |
292 | ||
293 | initComponent: function() { | |
03ab9fba DM |
294 | var me = this; |
295 | ||
296 | if (!me.list_refs_url) { | |
297 | throw "no1 list_refs_url specified"; | |
298 | } | |
299 | ||
300 | var store = new Ext.data.Store({ | |
f6710aac | 301 | model: 'pve-ipset', |
03ab9fba DM |
302 | }); |
303 | ||
304 | var reload = function() { | |
305 | store.load(); | |
306 | }; | |
307 | ||
308 | var sm = Ext.create('Ext.selection.RowModel', {}); | |
309 | ||
2e37e779 | 310 | me.caps = Ext.state.Manager.get('GuiCap'); |
1056e10c | 311 | me.canEdit = !!me.caps.vms['VM.Config.Network'] || !!me.caps.dc['Sys.Modify'] || !!me.caps.nodes['Sys.Modify']; |
2e37e779 | 312 | |
03ab9fba DM |
313 | var run_editor = function() { |
314 | var rec = sm.getSelection()[0]; | |
1056e10c | 315 | if (!rec || !me.canEdit) { |
03ab9fba DM |
316 | return; |
317 | } | |
318 | var win = Ext.create('PVE.IPSetCidrEdit', { | |
319 | base_url: me.base_url, | |
f6710aac | 320 | cidr: rec.data.cidr, |
03ab9fba DM |
321 | }); |
322 | win.show(); | |
323 | win.on('destroy', reload); | |
324 | }; | |
325 | ||
5720fafa | 326 | me.editBtn = new Proxmox.button.Button({ |
03ab9fba DM |
327 | text: gettext('Edit'), |
328 | disabled: true, | |
1056e10c | 329 | enableFn: rec => me.canEdit, |
03ab9fba | 330 | selModel: sm, |
f6710aac | 331 | handler: run_editor, |
03ab9fba DM |
332 | }); |
333 | ||
5720fafa | 334 | me.addBtn = new Proxmox.button.Button({ |
03ab9fba DM |
335 | text: gettext('Add'), |
336 | disabled: true, | |
1056e10c | 337 | enableFn: rec => me.canEdit, |
03ab9fba DM |
338 | handler: function() { |
339 | if (!me.base_url) { | |
340 | return; | |
341 | } | |
342 | var win = Ext.create('PVE.IPSetCidrEdit', { | |
343 | base_url: me.base_url, | |
f6710aac | 344 | list_refs_url: me.list_refs_url, |
03ab9fba DM |
345 | }); |
346 | win.show(); | |
347 | win.on('destroy', reload); | |
f6710aac | 348 | }, |
03ab9fba DM |
349 | }); |
350 | ||
3b1ca3ff | 351 | me.removeBtn = Ext.create('Proxmox.button.StdRemoveButton', { |
2e37e779 | 352 | disabled: true, |
1056e10c | 353 | enableFn: rec => me.canEdit, |
03ab9fba | 354 | selModel: sm, |
3b1ca3ff | 355 | baseurl: me.base_url + '/', |
f6710aac | 356 | callback: reload, |
03ab9fba DM |
357 | }); |
358 | ||
359 | var render_errors = function(value, metaData, record) { | |
360 | var errors = record.data.errors; | |
361 | if (errors) { | |
362 | var msg = errors.cidr || errors.nomatch; | |
363 | if (msg) { | |
3ab7e0ec | 364 | metaData.tdCls = 'proxmox-invalid-row'; |
8058410f | 365 | var html = '<p>' + Ext.htmlEncode(msg) + '</p>'; |
2a4971d8 | 366 | metaData.tdAttr = 'data-qwidth=600 data-qtitle="ERROR" data-qtip="' + |
202298c1 | 367 | html.replace(/"/g, '"') + '"'; |
03ab9fba DM |
368 | } |
369 | } | |
370 | return value; | |
371 | }; | |
372 | ||
373 | Ext.apply(me, { | |
8058410f | 374 | tbar: ['<b>IP/CIDR:</b>', me.addBtn, me.removeBtn, me.editBtn], |
03ab9fba DM |
375 | store: store, |
376 | selModel: sm, | |
377 | listeners: { | |
f6710aac | 378 | itemdblclick: run_editor, |
03ab9fba DM |
379 | }, |
380 | columns: [ | |
381 | { | |
f6710aac | 382 | xtype: 'rownumberer', |
03ab9fba DM |
383 | }, |
384 | { | |
385 | header: gettext('IP/CIDR'), | |
386 | dataIndex: 'cidr', | |
387 | width: 150, | |
388 | renderer: function(value, metaData, record) { | |
389 | value = render_errors(value, metaData, record); | |
390 | if (record.data.nomatch) { | |
391 | return '<b>! </b>' + value; | |
392 | } | |
393 | return value; | |
f6710aac | 394 | }, |
03ab9fba DM |
395 | }, |
396 | { | |
397 | header: gettext('Comment'), | |
398 | dataIndex: 'comment', | |
399 | flex: 1, | |
400 | renderer: function(value) { | |
401 | return Ext.util.Format.htmlEncode(value); | |
f6710aac TL |
402 | }, |
403 | }, | |
404 | ], | |
03ab9fba DM |
405 | }); |
406 | ||
407 | me.callParent(); | |
408 | ||
409 | if (me.base_url) { | |
410 | me.setBaseUrl(me.base_url); // load | |
411 | } | |
f6710aac | 412 | }, |
03ab9fba | 413 | }, function() { |
03ab9fba DM |
414 | Ext.define('pve-ipset', { |
415 | extend: 'Ext.data.Model', | |
8058410f TL |
416 | fields: [{ name: 'nomatch', type: 'boolean' }, |
417 | 'cidr', 'comment', 'errors'], | |
f6710aac | 418 | idProperty: 'cidr', |
03ab9fba | 419 | }); |
03ab9fba DM |
420 | }); |
421 | ||
422 | Ext.define('PVE.IPSet', { | |
423 | extend: 'Ext.panel.Panel', | |
424 | alias: 'widget.pveIPSet', | |
425 | ||
426 | title: 'IPSet', | |
427 | ||
ba93a9c6 DC |
428 | onlineHelp: 'pve_firewall_ip_sets', |
429 | ||
03ab9fba DM |
430 | list_refs_url: undefined, |
431 | ||
432 | initComponent: function() { | |
433 | var me = this; | |
434 | ||
435 | if (!me.list_refs_url) { | |
436 | throw "no list_refs_url specified"; | |
437 | } | |
438 | ||
439 | var ipset_panel = Ext.createWidget('pveIPSetGrid', { | |
440 | region: 'center', | |
441 | list_refs_url: me.list_refs_url, | |
f6710aac | 442 | border: false, |
03ab9fba DM |
443 | }); |
444 | ||
445 | var ipset_list = Ext.createWidget('pveIPSetList', { | |
446 | region: 'west', | |
447 | ipset_panel: ipset_panel, | |
448 | base_url: me.base_url, | |
123e1c80 | 449 | width: '50%', |
03ab9fba | 450 | border: false, |
f6710aac | 451 | split: true, |
03ab9fba DM |
452 | }); |
453 | ||
454 | Ext.apply(me, { | |
455 | layout: 'border', | |
8058410f | 456 | items: [ipset_list, ipset_panel], |
03ab9fba DM |
457 | listeners: { |
458 | show: function() { | |
459 | ipset_list.fireEvent('show', ipset_list); | |
f6710aac TL |
460 | }, |
461 | }, | |
03ab9fba DM |
462 | }); |
463 | ||
464 | me.callParent(); | |
f6710aac | 465 | }, |
03ab9fba | 466 | }); |