luci-app-firewall: add SNAT config migration
authorJo-Philipp Wich <jo@mein.io>
Sun, 19 Jan 2020 18:37:28 +0000 (19:37 +0100)
committerJo-Philipp Wich <jo@mein.io>
Tue, 28 Jan 2020 17:34:34 +0000 (18:34 +0100)
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
(backported from commit f1771d14aaa5f489d925f4ae775ae54a74ed7b81)

applications/luci-app-firewall/htdocs/luci-static/resources/tools/firewall.js
applications/luci-app-firewall/htdocs/luci-static/resources/view/firewall/forwards.js
applications/luci-app-firewall/htdocs/luci-static/resources/view/firewall/rules.js
applications/luci-app-firewall/htdocs/luci-static/resources/view/firewall/snats.js
applications/luci-app-firewall/htdocs/luci-static/resources/view/firewall/zones.js

index c60bfd028c484b460543a6afb85752bbf4dc1fff..cfa6c836510e3df7762efa1ebe549854ad6c060e 100644 (file)
@@ -590,5 +590,64 @@ return L.Class.extend({
 
                        return widget.render();
                }
-       })
+       }),
+
+       checkLegacySNAT: function() {
+               var redirects = uci.sections('firewall', 'redirect');
+
+               for (var i = 0; i < redirects.length; i++)
+                       if ((redirects[i]['target'] || '').toLowerCase() == 'snat')
+                               return true;
+
+               return false;
+       },
+
+       handleMigration: function(ev) {
+               var redirects = uci.sections('firewall', 'redirect'),
+                   tasks = [];
+
+               var mapping = {
+                       dest: 'src',
+                       reflection: null,
+                       reflection_src: null,
+                       src_dip: 'snat_ip',
+                       src_dport: 'snat_port',
+                       src: null
+               };
+
+               for (var i = 0; i < redirects.length; i++) {
+                       if ((redirects[i]['target'] || '').toLowerCase() != 'snat')
+                               continue;
+
+                       var sid = uci.add('firewall', 'nat');
+
+                       for (var opt in redirects[i]) {
+                               if (opt.charAt(0) == '.')
+                                       continue;
+
+                               if (mapping[opt] === null)
+                                       continue;
+
+                               uci.set('firewall', sid, mapping[opt] || opt, redirects[i][opt]);
+                       }
+
+                       uci.remove('firewall', redirects[i]['.name']);
+               }
+
+               return uci.save()
+                       .then(L.bind(ui.changes.init, ui.changes))
+                       .then(L.bind(ui.changes.apply, ui.changes));
+       },
+
+       renderMigration: function() {
+               ui.showModal(_('Firewall configuration migration'), [
+                       E('p', _('The existing firewall configuration needs to be changed for LuCI to function properly.')),
+                       E('p', _('Upon pressing "Continue", "redirect" sections with target "SNAT" will be converted to "nat" sections and the firewall will be restarted to apply the updated configuration.')),
+                       E('div', { 'class': 'right' },
+                               E('button', {
+                                       'class': 'btn cbi-button-action important',
+                                       'click': ui.createHandlerFn(this, 'handleMigration')
+                               }, _('Continue')))
+               ]);
+       },
 });
index 096124fccafa18340fd7ae1f398e22415a68b225..916a32fcaf64888c14f57a508f94064712bfe14f 100644 (file)
@@ -107,11 +107,19 @@ return L.view.extend({
                return Promise.all([
                        this.callHostHints(),
                        this.callConntrackHelpers(),
-                       this.callNetworkDevices()
+                       this.callNetworkDevices(),
+                       uci.load('firewall')
                ]);
        },
 
        render: function(data) {
+               if (fwtool.checkLegacySNAT())
+                       return fwtool.renderMigration();
+               else
+                       return this.renderForwards(data);
+       },
+
+       renderForwards: function(data) {
                var hosts = data[0],
                    ctHelpers = data[1],
                    devs = data[2],
index cc85e667695f13eef9a3fe700745b17bbf6fc852..b68f428d952fc41855a72fb0d8af79788e559bae 100644 (file)
@@ -152,11 +152,19 @@ return L.view.extend({
        load: function() {
                return Promise.all([
                        this.callHostHints(),
-                       this.callConntrackHelpers()
+                       this.callConntrackHelpers(),
+                       uci.load('firewall')
                ]);
        },
 
        render: function(data) {
+               if (fwtool.checkLegacySNAT())
+                       return fwtool.renderMigration();
+               else
+                       return this.renderRules(data);
+       },
+
+       renderRules: function(data) {
                var hosts = data[0],
                    ctHelpers = data[1],
                    m, s, o;
index 2db02d9444c18e4bc2507f944d9bb342426f46ca..9efa1a7497dfe0179a08ee42ab96bbd9362b74b7 100644 (file)
@@ -106,11 +106,19 @@ return L.view.extend({
        load: function() {
                return Promise.all([
                        this.callHostHints(),
-                       this.callNetworkDevices()
+                       this.callNetworkDevices(),
+                       uci.load('firewall')
                ]);
        },
 
        render: function(data) {
+               if (fwtool.checkLegacySNAT())
+                       return fwtool.renderMigration();
+               else
+                       return this.renderNats(data);
+       },
+
+       renderNats: function(data) {
                var hosts = data[0],
                    devs = data[1],
                    m, s, o;
index 4f8dad23d32ab54a010f34ae07cd4ba7af2bcb3a..89de8f46b56b7e8e52a52450a0d99b4181f17d4c 100644 (file)
@@ -4,6 +4,7 @@
 'require form';
 'require network';
 'require firewall';
+'require tools.firewall as fwtool';
 'require tools.widgets as widgets';
 
 return L.view.extend({
@@ -21,6 +22,13 @@ return L.view.extend({
        },
 
        render: function(data) {
+               if (fwtool.checkLegacySNAT())
+                       return fwtool.renderMigration();
+               else
+                       return this.renderZones(data);
+       },
+
+       renderZones: function(data) {
                var ctHelpers = data[0],
                    fwDefaults = data[1],
                    m, s, o, inp, out;