]>
git.proxmox.com Git - pve-manager.git/blob - www/manager6/grid/FirewallRules.js
ee618d90b082d3b685630d85dd6693e7ebf961a5
1 Ext
.define('PVE.form.FWMacroSelector', {
2 extend
: 'Proxmox.form.ComboGrid',
3 alias
: 'widget.pveFWMacroSelector',
11 header
: gettext('Macro'),
17 header
: gettext('Description'),
18 renderer
: Ext
.String
.htmlEncode
,
24 initComponent: function() {
27 var store
= Ext
.create('Ext.data.Store', {
29 fields
: [ 'macro', 'descr' ],
33 url
: "/api2/json/cluster/firewall/macros"
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', 'macro', '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
: 'proxmoxKVComboBox',
93 comboItems
: [['in', 'in'], ['out', 'out']],
94 fieldLabel
: gettext('Direction'),
98 xtype
: 'proxmoxKVComboBox',
101 comboItems
: [['ACCEPT', 'ACCEPT'], ['DROP', 'DROP'], ['REJECT', 'REJECT']],
102 fieldLabel
: gettext('Action'),
107 if (me
.allow_iface
) {
109 xtype
: 'proxmoxtextfield',
111 deleteEmpty
: !me
.isCreate
,
113 fieldLabel
: gettext('Interface')
117 xtype
: 'displayfield',
125 xtype
: 'displayfield',
131 xtype
: 'pveIPRefSelector',
135 base_url
: me
.list_refs_url
,
137 fieldLabel
: gettext('Source')
141 xtype
: 'pveIPRefSelector',
145 base_url
: me
.list_refs_url
,
147 fieldLabel
: gettext('Destination')
154 xtype
: 'proxmoxcheckbox',
158 fieldLabel
: gettext('Enable')
161 xtype
: 'pveFWMacroSelector',
163 fieldLabel
: gettext('Macro'),
167 change: function(f
, value
) {
168 if (value
=== null) {
169 me
.down('field[name=proto]').setDisabled(false);
170 me
.down('field[name=sport]').setDisabled(false);
171 me
.down('field[name=dport]').setDisabled(false);
173 me
.down('field[name=proto]').setDisabled(true);
174 me
.down('field[name=proto]').setValue('');
175 me
.down('field[name=sport]').setDisabled(true);
176 me
.down('field[name=sport]').setValue('');
177 me
.down('field[name=dport]').setDisabled(true);
178 me
.down('field[name=dport]').setValue('');
184 xtype
: 'pveIPProtocolSelector',
189 fieldLabel
: gettext('Protocol')
192 xtype
: 'displayfield',
201 fieldLabel
: gettext('Source port')
207 fieldLabel
: gettext('Dest. port')
216 fieldLabel
: gettext('Comment')
224 Ext
.define('PVE.FirewallRuleEdit', {
225 extend
: 'PVE.window.Edit',
228 list_refs_url
: undefined,
232 initComponent : function() {
237 throw "no base_url specified";
239 if (!me
.list_refs_url
) {
240 throw "no list_refs_url specified";
243 me
.isCreate
= (me
.rule_pos
=== undefined);
246 me
.url
= '/api2/extjs' + me
.base_url
;
249 me
.url
= '/api2/extjs' + me
.base_url
+ '/' + me
.rule_pos
.toString();
253 var ipanel
= Ext
.create('PVE.FirewallRulePanel', {
254 isCreate
: me
.isCreate
,
255 list_refs_url
: me
.list_refs_url
,
256 allow_iface
: me
.allow_iface
,
257 rule_pos
: me
.rule_pos
261 subject
: gettext('Rule'),
270 success: function(response
, options
) {
271 var values
= response
.result
.data
;
272 ipanel
.setValues(values
);
274 var field
= me
.query('[isFormField][name=modified_marker]')[0];
276 Ext
.Function
.defer(function() {
277 var form
= ipanel
.up('form').getForm();
278 form
.markInvalid(values
.errors
);
284 ipanel
.setValues(me
.rec
.data
);
289 Ext
.define('PVE.FirewallGroupRuleEdit', {
290 extend
: 'PVE.window.Edit',
296 initComponent : function() {
300 me
.isCreate
= (me
.rule_pos
=== undefined);
303 me
.url
= '/api2/extjs' + me
.base_url
;
306 me
.url
= '/api2/extjs' + me
.base_url
+ '/' + me
.rule_pos
.toString();
312 xtype
: 'hiddenfield',
317 xtype
: 'pveSecurityGroupsSelector',
320 fieldLabel
: gettext('Security Group'),
325 if (me
.allow_iface
) {
327 xtype
: 'proxmoxtextfield',
329 deleteEmpty
: !me
.isCreate
,
331 fieldLabel
: gettext('Interface')
335 var ipanel
= Ext
.create('PVE.panel.InputPanel', {
336 isCreate
: me
.isCreate
,
340 xtype
: 'proxmoxcheckbox',
344 fieldLabel
: gettext('Enable')
352 fieldLabel
: gettext('Comment')
358 subject
: gettext('Rule'),
367 success: function(response
, options
) {
368 var values
= response
.result
.data
;
369 ipanel
.setValues(values
);
376 Ext
.define('PVE.FirewallRules', {
377 extend
: 'Ext.grid.Panel',
378 alias
: 'widget.pveFirewallRules',
380 onlineHelp
: 'chapter_pve_firewall',
383 stateId
: 'grid-firewall-rules',
386 list_refs_url
: undefined,
389 removeBtn
: undefined,
393 tbar_prefix
: undefined,
398 setBaseUrl: function(url
) {
403 if (url
=== undefined) {
404 me
.addBtn
.setDisabled(true);
406 me
.groupBtn
.setDisabled(true);
408 me
.store
.removeAll();
410 me
.addBtn
.setDisabled(false);
411 me
.removeBtn
.baseurl
= url
+ '/';
413 me
.groupBtn
.setDisabled(false);
417 url
: '/api2/json' + url
424 moveRule: function(from, to
) {
431 Proxmox
.Utils
.API2Request({
432 url
: me
.base_url
+ "/" + from,
434 params
: { moveto
: to
},
436 failure: function(response
, options
) {
437 Ext
.Msg
.alert(gettext('Error'), response
.htmlStatus
);
439 callback: function() {
445 updateRule: function(rule
) {
452 rule
.enable
= rule
.enable
? 1 : 0;
458 Proxmox
.Utils
.API2Request({
459 url
: me
.base_url
+ '/' + pos
.toString(),
463 failure: function(response
, options
) {
464 Ext
.Msg
.alert(gettext('Error'), response
.htmlStatus
);
466 callback: function() {
473 initComponent: function() {
474 /*jslint confusion: true */
477 if (!me
.list_refs_url
) {
478 throw "no list_refs_url specified";
481 var store
= Ext
.create('Ext.data.Store',{
485 var reload = function() {
489 var sm
= Ext
.create('Ext.selection.RowModel', {});
491 var run_editor = function() {
492 var rec
= sm
.getSelection()[0];
496 var type
= rec
.data
.type
;
499 if (type
=== 'in' || type
=== 'out') {
500 editor
= 'PVE.FirewallRuleEdit';
501 } else if (type
=== 'group') {
502 editor
= 'PVE.FirewallGroupRuleEdit';
507 var win
= Ext
.create(editor
, {
508 digest
: rec
.data
.digest
,
509 allow_iface
: me
.allow_iface
,
510 base_url
: me
.base_url
,
511 list_refs_url
: me
.list_refs_url
,
512 rule_pos
: rec
.data
.pos
516 win
.on('destroy', reload
);
519 me
.editBtn
= Ext
.create('Proxmox.button.Button',{
520 text
: gettext('Edit'),
526 me
.addBtn
= Ext
.create('Ext.Button', {
527 text
: gettext('Add'),
529 handler: function() {
530 var win
= Ext
.create('PVE.FirewallRuleEdit', {
531 allow_iface
: me
.allow_iface
,
532 base_url
: me
.base_url
,
533 list_refs_url
: me
.list_refs_url
535 win
.on('destroy', reload
);
540 var run_copy_editor = function() {
541 var rec
= sm
.getSelection()[0];
546 var type
= rec
.data
.type
;
549 if (!(type
=== 'in' || type
=== 'out')) {
553 var win
= Ext
.create('PVE.FirewallRuleEdit', {
554 allow_iface
: me
.allow_iface
,
555 base_url
: me
.base_url
,
556 list_refs_url
: me
.list_refs_url
,
561 win
.on('destroy', reload
);
564 me
.copyBtn
= Ext
.create('Proxmox.button.Button',{
565 text
: gettext('Copy'),
567 enableFn: function(rec
) {
568 return (rec
.data
.type
=== 'in' || rec
.data
.type
=== 'out');
571 handler
: run_copy_editor
574 if (me
.allow_groups
) {
575 me
.groupBtn
= Ext
.create('Ext.Button', {
576 text
: gettext('Insert') + ': ' +
577 gettext('Security Group'),
579 handler: function() {
580 var win
= Ext
.create('PVE.FirewallGroupRuleEdit', {
581 allow_iface
: me
.allow_iface
,
582 base_url
: me
.base_url
584 win
.on('destroy', reload
);
590 me
.removeBtn
= Ext
.create('Proxmox.button.StdRemoveButton',{
592 baseurl
: me
.base_url
+ '/',
594 getRecordName: function(rec
) {
596 return rule
.pos
.toString() +
597 '?digest=' + encodeURIComponent(rule
.digest
);
599 callback: function() {
604 var tbar
= me
.tbar_prefix
? [ me
.tbar_prefix
] : [];
605 tbar
.push(me
.addBtn
, me
.copyBtn
);
607 tbar
.push(me
.groupBtn
);
609 tbar
.push(me
.removeBtn
, me
.editBtn
);
611 var render_errors = function(name
, value
, metaData
, record
) {
612 var errors
= record
.data
.errors
;
613 if (errors
&& errors
[name
]) {
614 metaData
.tdCls
= 'proxmox-invalid-row';
615 var html
= '<p>' + Ext
.htmlEncode(errors
[name
]) + '</p>';
616 metaData
.tdAttr
= 'data-qwidth=600 data-qtitle="ERROR" data-qtip="' +
617 html
.replace(/\"/g,'"') + '"';
624 // similar to xtype: 'rownumberer',
632 renderer: function(value
, metaData
, record
, rowIdx
, colIdx
, store
) {
633 metaData
.tdCls
= Ext
.baseCSSPrefix
+ 'grid-cell-special';
641 xtype
: 'checkcolumn',
642 header
: gettext('Enable'),
645 checkchange: function(column
, recordIndex
, checked
) {
646 var record
= me
.getStore().getData().items
[recordIndex
];
649 Ext
.Array
.forEach(record
.getFields(), function(field
) {
650 data
[field
.name
] = record
.get(field
.name
);
652 if (!me
.allow_iface
|| !data
.iface
) {
661 header
: gettext('Type'),
663 renderer: function(value
, metaData
, record
) {
664 return render_errors('type', value
, metaData
, record
);
669 header
: gettext('Action'),
671 renderer: function(value
, metaData
, record
) {
672 return render_errors('action', value
, metaData
, record
);
677 header
: gettext('Macro'),
679 renderer: function(value
, metaData
, record
) {
680 return render_errors('macro', value
, metaData
, record
);
686 if (me
.allow_iface
) {
688 header
: gettext('Interface'),
690 renderer: function(value
, metaData
, record
) {
691 return render_errors('iface', value
, metaData
, record
);
699 header
: gettext('Source'),
701 renderer: function(value
, metaData
, record
) {
702 return render_errors('source', value
, metaData
, record
);
707 header
: gettext('Destination'),
709 renderer: function(value
, metaData
, record
) {
710 return render_errors('dest', value
, metaData
, record
);
715 header
: gettext('Protocol'),
717 renderer: function(value
, metaData
, record
) {
718 return render_errors('proto', value
, metaData
, record
);
723 header
: gettext('Dest. port'),
725 renderer: function(value
, metaData
, record
) {
726 return render_errors('dport', value
, metaData
, record
);
731 header
: gettext('Source port'),
733 renderer: function(value
, metaData
, record
) {
734 return render_errors('sport', value
, metaData
, record
);
739 header
: gettext('Comment'),
740 dataIndex
: 'comment',
742 renderer: function(value
, metaData
, record
) {
743 return render_errors('comment', Ext
.util
.Format
.htmlEncode(value
), metaData
, record
);
755 ptype
: 'gridviewdragdrop',
756 dragGroup
: 'FWRuleDDGroup',
757 dropGroup
: 'FWRuleDDGroup'
761 beforedrop: function(node
, data
, dropRec
, dropPosition
) {
763 return false; // empty view
765 var moveto
= dropRec
.get('pos');
766 if (dropPosition
=== 'after') {
769 var pos
= data
.records
[0].get('pos');
770 me
.moveRule(pos
, moveto
);
773 itemdblclick
: run_editor
776 sortableColumns
: false,
783 me
.setBaseUrl(me
.base_url
); // load
788 Ext
.define('pve-fw-rule', {
789 extend
: 'Ext.data.Model',
790 fields
: [ { name
: 'enable', type
: 'boolean' },
791 'type', 'action', 'macro', 'source', 'dest', 'proto', 'iface',
792 'dport', 'sport', 'comment', 'pos', 'digest', 'errors' ],