]>
git.proxmox.com Git - pve-manager.git/blob - www/manager5/grid/FirewallRules.js
1 Ext
.define('PVE.form.FWMacroSelector', {
2 extend
: 'PVE.form.ComboGrid',
3 alias
: 'widget.pveFWMacroSelector',
5 initComponent: function() {
8 var store
= Ext
.create('Ext.data.Store', {
10 fields
: [ 'macro', 'descr' ],
14 url
: "/api2/json/cluster/firewall/macros"
27 displayField
: 'macro',
31 header
: gettext('Macro'),
37 header
: gettext('Description'),
49 Ext
.define('PVE.FirewallRulePanel', {
50 extend
: 'PVE.panel.InputPanel',
54 list_refs_url
: undefined,
56 onGetValues: function(values
) {
59 // hack: editable ComboGrid returns nothing when empty, so we need to set ''
60 // Also, disabled text fields return nothing, so we need to set ''
62 Ext
.Array
.each(['source', 'dest', 'proto', 'sport', 'dport'], function(key
) {
63 if (values
[key
] === undefined) {
68 delete values
.modified_marker
;
73 initComponent : function() {
76 if (!me
.list_refs_url
) {
77 throw "no list_refs_url specified";
82 // hack: we use this field to mark the form 'dirty' when the
83 // record has errors- so that the user can safe the unmodified
86 name
: 'modified_marker',
90 xtype
: 'pveKVComboBox',
93 data
: [['in', 'in'], ['out', 'out']],
94 fieldLabel
: gettext('Direction'),
98 xtype
: 'pveKVComboBox',
101 data
: [['ACCEPT', 'ACCEPT'], ['DROP', 'DROP'], ['REJECT', 'REJECT']],
102 fieldLabel
: gettext('Action'),
107 if (me
.allow_iface
) {
109 xtype
: 'pvetextfield',
111 deleteEmpty
: !me
.create
,
113 fieldLabel
: gettext('Interface')
117 xtype
: 'displayfield',
119 height
: 22, // hack: set same height as text fields
126 xtype
: 'displayfield',
132 xtype
: 'pveIPRefSelector',
136 base_url
: me
.list_refs_url
,
138 fieldLabel
: gettext('Source')
142 xtype
: 'pveIPRefSelector',
146 base_url
: me
.list_refs_url
,
148 fieldLabel
: gettext('Destination')
155 xtype
: 'pvecheckbox',
158 height
: 22, // hack: set same height as text fields
160 fieldLabel
: gettext('Enable')
163 xtype
: 'pveFWMacroSelector',
166 fieldLabel
: gettext('Macro'),
169 change: function(f
, value
) {
171 me
.down('field[name=proto]').setDisabled(false);
172 me
.down('field[name=sport]').setDisabled(false);
173 me
.down('field[name=dport]').setDisabled(false);
175 me
.down('field[name=proto]').setDisabled(true);
176 me
.down('field[name=proto]').setValue('');
177 me
.down('field[name=sport]').setDisabled(true);
178 me
.down('field[name=sport]').setValue('');
179 me
.down('field[name=dport]').setDisabled(true);
180 me
.down('field[name=dport]').setValue('');
186 xtype
: 'pveIPProtocolSelector',
191 fieldLabel
: gettext('Protocol')
194 xtype
: 'displayfield',
203 fieldLabel
: gettext('Source port')
208 height
: 22, // hack: set same height as text fields
210 fieldLabel
: gettext('Dest. port')
219 fieldLabel
: gettext('Comment')
227 Ext
.define('PVE.FirewallRuleEdit', {
228 extend
: 'PVE.window.Edit',
231 list_refs_url
: undefined,
235 initComponent : function() {
236 /*jslint confusion: true */
240 throw "no base_url specified";
242 if (!me
.list_refs_url
) {
243 throw "no list_refs_url specified";
246 me
.create
= (me
.rule_pos
=== undefined);
249 me
.url
= '/api2/extjs' + me
.base_url
;
252 me
.url
= '/api2/extjs' + me
.base_url
+ '/' + me
.rule_pos
.toString();
256 var ipanel
= Ext
.create('PVE.FirewallRulePanel', {
258 list_refs_url
: me
.list_refs_url
,
259 allow_iface
: me
.allow_iface
,
260 rule_pos
: me
.rule_pos
264 subject
: gettext('Rule'),
273 success: function(response
, options
) {
274 var values
= response
.result
.data
;
275 ipanel
.setValues(values
);
277 var field
= me
.query('[isFormField][name=modified_marker]')[0];
279 Ext
.Function
.defer(function() {
280 var form
= ipanel
.up('form').getForm();
281 form
.markInvalid(values
.errors
)
290 Ext
.define('PVE.FirewallGroupRuleEdit', {
291 extend
: 'PVE.window.Edit',
297 initComponent : function() {
298 /*jslint confusion: true */
301 me
.create
= (me
.rule_pos
=== undefined);
304 me
.url
= '/api2/extjs' + me
.base_url
;
307 me
.url
= '/api2/extjs' + me
.base_url
+ '/' + me
.rule_pos
.toString();
313 xtype
: 'hiddenfield',
318 xtype
: 'pveSecurityGroupsSelector',
321 fieldLabel
: gettext('Security Group'),
326 if (me
.allow_iface
) {
328 xtype
: 'pvetextfield',
330 deleteEmpty
: !me
.create
,
332 fieldLabel
: gettext('Interface')
336 var ipanel
= Ext
.create('PVE.panel.InputPanel', {
341 xtype
: 'pvecheckbox',
344 height
: 22, // hack: set same height as text fields
346 fieldLabel
: gettext('Enable')
354 fieldLabel
: gettext('Comment')
360 subject
: gettext('Rule'),
369 success: function(response
, options
) {
370 var values
= response
.result
.data
;
371 ipanel
.setValues(values
);
378 Ext
.define('PVE.FirewallRules', {
379 extend
: 'Ext.grid.Panel',
380 alias
: 'widget.pveFirewallRules',
383 list_refs_url
: undefined,
386 removeBtn
: undefined,
390 tbar_prefix
: undefined,
395 setBaseUrl: function(url
) {
400 if (url
=== undefined) {
401 me
.addBtn
.setDisabled(true);
403 me
.groupBtn
.setDisabled(true);
405 me
.store
.removeAll();
407 me
.addBtn
.setDisabled(false);
409 me
.groupBtn
.setDisabled(false);
413 url
: '/api2/json' + url
420 moveRule: function(from, to
) {
427 PVE
.Utils
.API2Request({
428 url
: me
.base_url
+ "/" + from,
430 params
: { moveto
: to
},
432 failure: function(response
, options
) {
433 Ext
.Msg
.alert(gettext('Error'), response
.htmlStatus
);
435 callback: function() {
441 updateRule: function(rule
) {
448 rule
.enable
= rule
.enable
? 1 : 0;
454 PVE
.Utils
.API2Request({
455 url
: me
.base_url
+ '/' + pos
.toString(),
459 failure: function(response
, options
) {
460 Ext
.Msg
.alert(gettext('Error'), response
.htmlStatus
);
462 callback: function() {
468 deleteRule: function(rule
) {
475 PVE
.Utils
.API2Request({
476 url
: me
.base_url
+ '/' + rule
.pos
.toString() +
477 '?digest=' + encodeURIComponent(rule
.digest
),
480 failure: function(response
, options
) {
481 Ext
.Msg
.alert(gettext('Error'), response
.htmlStatus
);
483 callback: function() {
489 initComponent: function() {
490 /*jslint confusion: true */
493 if (!me
.list_refs_url
) {
494 throw "no list_refs_url specified";
497 var store
= new Ext
.data
.Store({
501 var reload = function() {
505 var sm
= Ext
.create('Ext.selection.RowModel', {});
507 var run_editor = function() {
508 var rec
= sm
.getSelection()[0];
512 var type
= rec
.data
.type
;
515 if (type
=== 'in' || type
=== 'out') {
516 editor
= 'PVE.FirewallRuleEdit';
517 } else if (type
=== 'group') {
518 editor
= 'PVE.FirewallGroupRuleEdit';
523 var win
= Ext
.create(editor
, {
524 digest
: rec
.data
.digest
,
525 allow_iface
: me
.allow_iface
,
526 base_url
: me
.base_url
,
527 list_refs_url
: me
.list_refs_url
,
528 rule_pos
: rec
.data
.pos
532 win
.on('destroy', reload
);
535 me
.editBtn
= new PVE
.button
.Button({
536 text
: gettext('Edit'),
542 me
.addBtn
= Ext
.create('Ext.Button', {
543 text
: gettext('Add'),
545 handler: function() {
546 var win
= Ext
.create('PVE.FirewallRuleEdit', {
547 allow_iface
: me
.allow_iface
,
548 base_url
: me
.base_url
,
549 list_refs_url
: me
.list_refs_url
551 win
.on('destroy', reload
);
556 if (me
.allow_groups
) {
557 me
.groupBtn
= Ext
.create('Ext.Button', {
558 text
: gettext('Insert') + ': ' +
559 gettext('Security Group'),
561 handler: function() {
562 var win
= Ext
.create('PVE.FirewallGroupRuleEdit', {
563 allow_iface
: me
.allow_iface
,
564 base_url
: me
.base_url
566 win
.on('destroy', reload
);
572 me
.removeBtn
= new PVE
.button
.Button({
573 text
: gettext('Remove'),
576 handler: function() {
577 var rec
= sm
.getSelection()[0];
581 me
.deleteRule(rec
.data
);
585 var tbar
= me
.tbar_prefix
? [ me
.tbar_prefix
] : [];
586 tbar
.push(me
.addBtn
);
588 tbar
.push(me
.groupBtn
);
590 tbar
.push([ me
.removeBtn
, me
.editBtn
]);
592 var render_errors = function(name
, value
, metaData
, record
) {
593 var errors
= record
.data
.errors
;
594 if (errors
&& errors
[name
]) {
595 metaData
.tdCls
= 'x-form-invalid-field';
596 var html
= '<p>' + Ext
.htmlEncode(errors
[name
]) + '</p>';
597 metaData
.tdAttr
= 'data-qwidth=600 data-qtitle="ERROR" data-qtip="' +
598 html
.replace(/\"/g,'"') + '"';
605 // similar to xtype: 'rownumberer',
613 renderer: function(value
, metaData
, record
, rowIdx
, colIdx
, store
) {
614 metaData
.tdCls
= Ext
.baseCSSPrefix
+ 'grid-cell-special';
622 xtype
: 'checkcolumn',
623 header
: gettext('Enable'),
626 checkchange: function(column
, record
, checked
) {
629 record
.fields
.each(function(field
) {
630 data
[field
.name
] = record
.get(field
.name
);
632 if (!me
.allow_iface
|| !data
.iface
) {
641 header
: gettext('Type'),
643 renderer: function(value
, metaData
, record
) {
644 return render_errors('type', value
, metaData
, record
);
649 header
: gettext('Action'),
651 renderer: function(value
, metaData
, record
) {
652 return render_errors('action', value
, metaData
, record
);
657 header
: gettext('Macro'),
659 renderer: function(value
, metaData
, record
) {
660 return render_errors('macro', value
, metaData
, record
);
666 if (me
.allow_iface
) {
668 header
: gettext('Interface'),
670 renderer: function(value
, metaData
, record
) {
671 return render_errors('iface', value
, metaData
, record
);
679 header
: gettext('Source'),
681 renderer: function(value
, metaData
, record
) {
682 return render_errors('source', value
, metaData
, record
);
687 header
: gettext('Destination'),
689 renderer: function(value
, metaData
, record
) {
690 return render_errors('dest', value
, metaData
, record
);
695 header
: gettext('Protocol'),
697 renderer: function(value
, metaData
, record
) {
698 return render_errors('proto', value
, metaData
, record
);
703 header
: gettext('Dest. port'),
705 renderer: function(value
, metaData
, record
) {
706 return render_errors('dport', value
, metaData
, record
);
711 header
: gettext('Source port'),
713 renderer: function(value
, metaData
, record
) {
714 return render_errors('sport', value
, metaData
, record
);
719 header
: gettext('Comment'),
720 dataIndex
: 'comment',
722 renderer: function(value
, metaData
, record
) {
723 return render_errors('comment', Ext
.util
.Format
.htmlEncode(value
), metaData
, record
);
735 ptype
: 'gridviewdragdrop',
736 dragGroup
: 'FWRuleDDGroup',
737 dropGroup
: 'FWRuleDDGroup'
741 beforedrop: function(node
, data
, dropRec
, dropPosition
) {
743 return false; // empty view
745 var moveto
= dropRec
.get('pos');
746 if (dropPosition
=== 'after') {
749 var pos
= data
.records
[0].get('pos');
750 me
.moveRule(pos
, moveto
);
753 itemdblclick
: run_editor
756 sortableColumns
: false,
763 me
.setBaseUrl(me
.base_url
); // load
768 Ext
.define('pve-fw-rule', {
769 extend
: 'Ext.data.Model',
770 fields
: [ { name
: 'enable', type
: 'boolean' },
771 'type', 'action', 'macro', 'source', 'dest', 'proto', 'iface',
772 'dport', 'sport', 'comment', 'pos', 'digest', 'errors' ],