]>
git.proxmox.com Git - pve-manager.git/blob - www/manager6/grid/FirewallRules.js
ec2d1c841e9d1932b0ad2dd6ef5dbb60d019eba8
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
: 'Proxmox.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', 'log'], 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')
211 me
.advancedColumn1
= [
213 xtype
: 'pveFirewallLogLevels'
222 fieldLabel
: gettext('Comment')
230 Ext
.define('PVE.FirewallRuleEdit', {
231 extend
: 'Proxmox.window.Edit',
234 list_refs_url
: undefined,
238 initComponent : function() {
243 throw "no base_url specified";
245 if (!me
.list_refs_url
) {
246 throw "no list_refs_url specified";
249 me
.isCreate
= (me
.rule_pos
=== undefined);
252 me
.url
= '/api2/extjs' + me
.base_url
;
255 me
.url
= '/api2/extjs' + me
.base_url
+ '/' + me
.rule_pos
.toString();
259 var ipanel
= Ext
.create('PVE.FirewallRulePanel', {
260 isCreate
: me
.isCreate
,
261 list_refs_url
: me
.list_refs_url
,
262 allow_iface
: me
.allow_iface
,
263 rule_pos
: me
.rule_pos
267 subject
: gettext('Rule'),
276 success: function(response
, options
) {
277 var values
= response
.result
.data
;
278 ipanel
.setValues(values
);
280 var field
= me
.query('[isFormField][name=modified_marker]')[0];
282 Ext
.Function
.defer(function() {
283 var form
= ipanel
.up('form').getForm();
284 form
.markInvalid(values
.errors
);
290 ipanel
.setValues(me
.rec
.data
);
295 Ext
.define('PVE.FirewallGroupRuleEdit', {
296 extend
: 'Proxmox.window.Edit',
302 initComponent : function() {
306 me
.isCreate
= (me
.rule_pos
=== undefined);
309 me
.url
= '/api2/extjs' + me
.base_url
;
312 me
.url
= '/api2/extjs' + me
.base_url
+ '/' + me
.rule_pos
.toString();
318 xtype
: 'hiddenfield',
323 xtype
: 'pveSecurityGroupsSelector',
326 fieldLabel
: gettext('Security Group'),
331 if (me
.allow_iface
) {
333 xtype
: 'proxmoxtextfield',
335 deleteEmpty
: !me
.isCreate
,
337 fieldLabel
: gettext('Interface')
341 var ipanel
= Ext
.create('Proxmox.panel.InputPanel', {
342 isCreate
: me
.isCreate
,
346 xtype
: 'proxmoxcheckbox',
350 fieldLabel
: gettext('Enable')
358 fieldLabel
: gettext('Comment')
364 subject
: gettext('Rule'),
373 success: function(response
, options
) {
374 var values
= response
.result
.data
;
375 ipanel
.setValues(values
);
382 Ext
.define('PVE.FirewallRules', {
383 extend
: 'Ext.grid.Panel',
384 alias
: 'widget.pveFirewallRules',
386 onlineHelp
: 'chapter_pve_firewall',
389 stateId
: 'grid-firewall-rules',
392 list_refs_url
: undefined,
395 removeBtn
: undefined,
399 tbar_prefix
: undefined,
404 setBaseUrl: function(url
) {
409 if (url
=== undefined) {
410 me
.addBtn
.setDisabled(true);
412 me
.groupBtn
.setDisabled(true);
414 me
.store
.removeAll();
416 me
.addBtn
.setDisabled(false);
417 me
.removeBtn
.baseurl
= url
+ '/';
419 me
.groupBtn
.setDisabled(false);
423 url
: '/api2/json' + url
430 moveRule: function(from, to
) {
437 Proxmox
.Utils
.API2Request({
438 url
: me
.base_url
+ "/" + from,
440 params
: { moveto
: to
},
442 failure: function(response
, options
) {
443 Ext
.Msg
.alert(gettext('Error'), response
.htmlStatus
);
445 callback: function() {
451 updateRule: function(rule
) {
458 rule
.enable
= rule
.enable
? 1 : 0;
464 Proxmox
.Utils
.API2Request({
465 url
: me
.base_url
+ '/' + pos
.toString(),
469 failure: function(response
, options
) {
470 Ext
.Msg
.alert(gettext('Error'), response
.htmlStatus
);
472 callback: function() {
479 initComponent: function() {
482 if (!me
.list_refs_url
) {
483 throw "no list_refs_url specified";
486 var store
= Ext
.create('Ext.data.Store',{
490 var reload = function() {
494 var sm
= Ext
.create('Ext.selection.RowModel', {});
496 var run_editor = function() {
497 var rec
= sm
.getSelection()[0];
501 var type
= rec
.data
.type
;
504 if (type
=== 'in' || type
=== 'out') {
505 editor
= 'PVE.FirewallRuleEdit';
506 } else if (type
=== 'group') {
507 editor
= 'PVE.FirewallGroupRuleEdit';
512 var win
= Ext
.create(editor
, {
513 digest
: rec
.data
.digest
,
514 allow_iface
: me
.allow_iface
,
515 base_url
: me
.base_url
,
516 list_refs_url
: me
.list_refs_url
,
517 rule_pos
: rec
.data
.pos
521 win
.on('destroy', reload
);
524 me
.editBtn
= Ext
.create('Proxmox.button.Button',{
525 text
: gettext('Edit'),
531 me
.addBtn
= Ext
.create('Ext.Button', {
532 text
: gettext('Add'),
534 handler: function() {
535 var win
= Ext
.create('PVE.FirewallRuleEdit', {
536 allow_iface
: me
.allow_iface
,
537 base_url
: me
.base_url
,
538 list_refs_url
: me
.list_refs_url
540 win
.on('destroy', reload
);
545 var run_copy_editor = function() {
546 var rec
= sm
.getSelection()[0];
551 var type
= rec
.data
.type
;
554 if (!(type
=== 'in' || type
=== 'out')) {
558 var win
= Ext
.create('PVE.FirewallRuleEdit', {
559 allow_iface
: me
.allow_iface
,
560 base_url
: me
.base_url
,
561 list_refs_url
: me
.list_refs_url
,
566 win
.on('destroy', reload
);
569 me
.copyBtn
= Ext
.create('Proxmox.button.Button',{
570 text
: gettext('Copy'),
572 enableFn: function(rec
) {
573 return (rec
.data
.type
=== 'in' || rec
.data
.type
=== 'out');
576 handler
: run_copy_editor
579 if (me
.allow_groups
) {
580 me
.groupBtn
= Ext
.create('Ext.Button', {
581 text
: gettext('Insert') + ': ' +
582 gettext('Security Group'),
584 handler: function() {
585 var win
= Ext
.create('PVE.FirewallGroupRuleEdit', {
586 allow_iface
: me
.allow_iface
,
587 base_url
: me
.base_url
589 win
.on('destroy', reload
);
595 me
.removeBtn
= Ext
.create('Proxmox.button.StdRemoveButton',{
597 baseurl
: me
.base_url
+ '/',
599 getRecordName: function(rec
) {
601 return rule
.pos
.toString() +
602 '?digest=' + encodeURIComponent(rule
.digest
);
604 callback: function() {
609 var tbar
= me
.tbar_prefix
? [ me
.tbar_prefix
] : [];
610 tbar
.push(me
.addBtn
, me
.copyBtn
);
612 tbar
.push(me
.groupBtn
);
614 tbar
.push(me
.removeBtn
, me
.editBtn
);
616 var render_errors = function(name
, value
, metaData
, record
) {
617 var errors
= record
.data
.errors
;
618 if (errors
&& errors
[name
]) {
619 metaData
.tdCls
= 'proxmox-invalid-row';
620 var html
= '<p>' + Ext
.htmlEncode(errors
[name
]) + '</p>';
621 metaData
.tdAttr
= 'data-qwidth=600 data-qtitle="ERROR" data-qtip="' +
622 html
.replace(/\"/g,'"') + '"';
629 // similar to xtype: 'rownumberer',
637 renderer: function(value
, metaData
, record
, rowIdx
, colIdx
, store
) {
638 metaData
.tdCls
= Ext
.baseCSSPrefix
+ 'grid-cell-special';
646 xtype
: 'checkcolumn',
647 header
: gettext('Enable'),
650 checkchange: function(column
, recordIndex
, checked
) {
651 var record
= me
.getStore().getData().items
[recordIndex
];
654 Ext
.Array
.forEach(record
.getFields(), function(field
) {
655 data
[field
.name
] = record
.get(field
.name
);
657 if (!me
.allow_iface
|| !data
.iface
) {
666 header
: gettext('Type'),
668 renderer: function(value
, metaData
, record
) {
669 return render_errors('type', value
, metaData
, record
);
674 header
: gettext('Action'),
676 renderer: function(value
, metaData
, record
) {
677 return render_errors('action', value
, metaData
, record
);
682 header
: gettext('Macro'),
684 renderer: function(value
, metaData
, record
) {
685 return render_errors('macro', value
, metaData
, record
);
691 if (me
.allow_iface
) {
693 header
: gettext('Interface'),
695 renderer: function(value
, metaData
, record
) {
696 return render_errors('iface', value
, metaData
, record
);
704 header
: gettext('Source'),
706 renderer: function(value
, metaData
, record
) {
707 return render_errors('source', value
, metaData
, record
);
712 header
: gettext('Destination'),
714 renderer: function(value
, metaData
, record
) {
715 return render_errors('dest', value
, metaData
, record
);
720 header
: gettext('Protocol'),
722 renderer: function(value
, metaData
, record
) {
723 return render_errors('proto', value
, metaData
, record
);
728 header
: gettext('Dest. port'),
730 renderer: function(value
, metaData
, record
) {
731 return render_errors('dport', value
, metaData
, record
);
736 header
: gettext('Source port'),
738 renderer: function(value
, metaData
, record
) {
739 return render_errors('sport', value
, metaData
, record
);
744 header
: gettext('Log level'),
746 renderer: function(value
, metaData
, record
) {
747 return render_errors('log', value
, metaData
, record
);
752 header
: gettext('Comment'),
753 dataIndex
: 'comment',
755 renderer: function(value
, metaData
, record
) {
756 return render_errors('comment', Ext
.util
.Format
.htmlEncode(value
), metaData
, record
);
768 ptype
: 'gridviewdragdrop',
769 dragGroup
: 'FWRuleDDGroup',
770 dropGroup
: 'FWRuleDDGroup'
774 beforedrop: function(node
, data
, dropRec
, dropPosition
) {
776 return false; // empty view
778 var moveto
= dropRec
.get('pos');
779 if (dropPosition
=== 'after') {
782 var pos
= data
.records
[0].get('pos');
783 me
.moveRule(pos
, moveto
);
786 itemdblclick
: run_editor
789 sortableColumns
: false,
796 me
.setBaseUrl(me
.base_url
); // load
801 Ext
.define('pve-fw-rule', {
802 extend
: 'Ext.data.Model',
803 fields
: [ { name
: 'enable', type
: 'boolean' },
804 'type', 'action', 'macro', 'source', 'dest', 'proto', 'iface',
805 'dport', 'sport', 'comment', 'pos', 'digest', 'errors' ],