]>
git.proxmox.com Git - pve-manager.git/blob - www/manager6/grid/FirewallRules.js
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
: 'pveKVComboBox',
93 comboItems
: [['in', 'in'], ['out', 'out']],
94 fieldLabel
: gettext('Direction'),
98 xtype
: 'pveKVComboBox',
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
: 'pvecheckbox',
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
: 'pvecheckbox',
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);
412 me
.groupBtn
.setDisabled(false);
416 url
: '/api2/json' + url
423 moveRule: function(from, to
) {
430 PVE
.Utils
.API2Request({
431 url
: me
.base_url
+ "/" + from,
433 params
: { moveto
: to
},
435 failure: function(response
, options
) {
436 Ext
.Msg
.alert(gettext('Error'), response
.htmlStatus
);
438 callback: function() {
444 updateRule: function(rule
) {
451 rule
.enable
= rule
.enable
? 1 : 0;
457 PVE
.Utils
.API2Request({
458 url
: me
.base_url
+ '/' + pos
.toString(),
462 failure: function(response
, options
) {
463 Ext
.Msg
.alert(gettext('Error'), response
.htmlStatus
);
465 callback: function() {
471 deleteRule: function(rule
) {
478 PVE
.Utils
.API2Request({
479 url
: me
.base_url
+ '/' + rule
.pos
.toString() +
480 '?digest=' + encodeURIComponent(rule
.digest
),
483 failure: function(response
, options
) {
484 Ext
.Msg
.alert(gettext('Error'), response
.htmlStatus
);
486 callback: function() {
492 initComponent: function() {
493 /*jslint confusion: true */
496 if (!me
.list_refs_url
) {
497 throw "no list_refs_url specified";
500 var store
= Ext
.create('Ext.data.Store',{
504 var reload = function() {
508 var sm
= Ext
.create('Ext.selection.RowModel', {});
510 var run_editor = function() {
511 var rec
= sm
.getSelection()[0];
515 var type
= rec
.data
.type
;
518 if (type
=== 'in' || type
=== 'out') {
519 editor
= 'PVE.FirewallRuleEdit';
520 } else if (type
=== 'group') {
521 editor
= 'PVE.FirewallGroupRuleEdit';
526 var win
= Ext
.create(editor
, {
527 digest
: rec
.data
.digest
,
528 allow_iface
: me
.allow_iface
,
529 base_url
: me
.base_url
,
530 list_refs_url
: me
.list_refs_url
,
531 rule_pos
: rec
.data
.pos
535 win
.on('destroy', reload
);
538 me
.editBtn
= Ext
.create('PVE.button.Button',{
539 text
: gettext('Edit'),
545 me
.addBtn
= Ext
.create('Ext.Button', {
546 text
: gettext('Add'),
548 handler: function() {
549 var win
= Ext
.create('PVE.FirewallRuleEdit', {
550 allow_iface
: me
.allow_iface
,
551 base_url
: me
.base_url
,
552 list_refs_url
: me
.list_refs_url
554 win
.on('destroy', reload
);
559 var run_copy_editor = function() {
560 var rec
= sm
.getSelection()[0];
565 var type
= rec
.data
.type
;
568 if (!(type
=== 'in' || type
=== 'out')) {
572 var win
= Ext
.create('PVE.FirewallRuleEdit', {
573 allow_iface
: me
.allow_iface
,
574 base_url
: me
.base_url
,
575 list_refs_url
: me
.list_refs_url
,
580 win
.on('destroy', reload
);
583 me
.copyBtn
= Ext
.create('PVE.button.Button',{
584 text
: gettext('Copy'),
586 enableFn: function(rec
) {
587 return (rec
.data
.type
=== 'in' || rec
.data
.type
=== 'out');
590 handler
: run_copy_editor
593 if (me
.allow_groups
) {
594 me
.groupBtn
= Ext
.create('Ext.Button', {
595 text
: gettext('Insert') + ': ' +
596 gettext('Security Group'),
598 handler: function() {
599 var win
= Ext
.create('PVE.FirewallGroupRuleEdit', {
600 allow_iface
: me
.allow_iface
,
601 base_url
: me
.base_url
603 win
.on('destroy', reload
);
609 me
.removeBtn
= Ext
.create('PVE.button.Button',{
610 text
: gettext('Remove'),
613 handler: function() {
614 var rec
= sm
.getSelection()[0];
618 me
.deleteRule(rec
.data
);
622 var tbar
= me
.tbar_prefix
? [ me
.tbar_prefix
] : [];
623 tbar
.push(me
.addBtn
, me
.copyBtn
);
625 tbar
.push(me
.groupBtn
);
627 tbar
.push(me
.removeBtn
, me
.editBtn
);
629 var render_errors = function(name
, value
, metaData
, record
) {
630 var errors
= record
.data
.errors
;
631 if (errors
&& errors
[name
]) {
632 metaData
.tdCls
= 'pve-invalid-row';
633 var html
= '<p>' + Ext
.htmlEncode(errors
[name
]) + '</p>';
634 metaData
.tdAttr
= 'data-qwidth=600 data-qtitle="ERROR" data-qtip="' +
635 html
.replace(/\"/g,'"') + '"';
642 // similar to xtype: 'rownumberer',
650 renderer: function(value
, metaData
, record
, rowIdx
, colIdx
, store
) {
651 metaData
.tdCls
= Ext
.baseCSSPrefix
+ 'grid-cell-special';
659 xtype
: 'checkcolumn',
660 header
: gettext('Enable'),
663 checkchange: function(column
, recordIndex
, checked
) {
664 var record
= me
.getStore().getData().items
[recordIndex
];
667 Ext
.Array
.forEach(record
.getFields(), function(field
) {
668 data
[field
.name
] = record
.get(field
.name
);
670 if (!me
.allow_iface
|| !data
.iface
) {
679 header
: gettext('Type'),
681 renderer: function(value
, metaData
, record
) {
682 return render_errors('type', value
, metaData
, record
);
687 header
: gettext('Action'),
689 renderer: function(value
, metaData
, record
) {
690 return render_errors('action', value
, metaData
, record
);
695 header
: gettext('Macro'),
697 renderer: function(value
, metaData
, record
) {
698 return render_errors('macro', value
, metaData
, record
);
704 if (me
.allow_iface
) {
706 header
: gettext('Interface'),
708 renderer: function(value
, metaData
, record
) {
709 return render_errors('iface', value
, metaData
, record
);
717 header
: gettext('Source'),
719 renderer: function(value
, metaData
, record
) {
720 return render_errors('source', value
, metaData
, record
);
725 header
: gettext('Destination'),
727 renderer: function(value
, metaData
, record
) {
728 return render_errors('dest', value
, metaData
, record
);
733 header
: gettext('Protocol'),
735 renderer: function(value
, metaData
, record
) {
736 return render_errors('proto', value
, metaData
, record
);
741 header
: gettext('Dest. port'),
743 renderer: function(value
, metaData
, record
) {
744 return render_errors('dport', value
, metaData
, record
);
749 header
: gettext('Source port'),
751 renderer: function(value
, metaData
, record
) {
752 return render_errors('sport', value
, metaData
, record
);
757 header
: gettext('Comment'),
758 dataIndex
: 'comment',
760 renderer: function(value
, metaData
, record
) {
761 return render_errors('comment', Ext
.util
.Format
.htmlEncode(value
), metaData
, record
);
773 ptype
: 'gridviewdragdrop',
774 dragGroup
: 'FWRuleDDGroup',
775 dropGroup
: 'FWRuleDDGroup'
779 beforedrop: function(node
, data
, dropRec
, dropPosition
) {
781 return false; // empty view
783 var moveto
= dropRec
.get('pos');
784 if (dropPosition
=== 'after') {
787 var pos
= data
.records
[0].get('pos');
788 me
.moveRule(pos
, moveto
);
791 itemdblclick
: run_editor
794 sortableColumns
: false,
801 me
.setBaseUrl(me
.base_url
); // load
806 Ext
.define('pve-fw-rule', {
807 extend
: 'Ext.data.Model',
808 fields
: [ { name
: 'enable', type
: 'boolean' },
809 'type', 'action', 'macro', 'source', 'dest', 'proto', 'iface',
810 'dport', 'sport', 'comment', 'pos', 'digest', 'errors' ],