]> review.fuel-infra Code Review - puppet-modules/puppetlabs-firewall.git/commitdiff
Add nftables wrapper support for RHEL8
authorAlex Schultz <aschultz@redhat.com>
Mon, 26 Nov 2018 21:41:40 +0000 (14:41 -0700)
committerAlex Schultz <aschultz@redhat.com>
Tue, 27 Nov 2018 14:42:33 +0000 (07:42 -0700)
In RHEL8, iptables is replaced with nftables under the covers. In order
to allow for the firewall module to continue to function, this change
updates the redhat firewall configuration to pull in the nftables
packages.

https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8-beta/html/8.0_beta_release_notes/new-features#networking_2

manifests/linux/redhat.pp
manifests/params.pp
spec/unit/classes/firewall_linux_redhat_spec.rb

index 65821f415f33c420c122d0d809e96bb7383a1f54..ba7010e296521bf24cc2fee9e52a8fcd2278ea4c 100644 (file)
@@ -10,7 +10,7 @@
 #
 # [*ensure_v6*]
 #   Ensure parameter passed onto Service[] resources.
-#   Default: running
+#   Default: undef
 #
 # [*enable*]
 #   Enable parameter passed onto Service[] resources.
 #
 # [*enable_v6*]
 #   Enable parameter passed onto Service[] resources.
-#   Default: true
+#   Default: undef
 #
+# [*sysconfig_manage*]
+#   Enable sysconfig configuration for iptables/ip6tables files. This is
+#   disabled for RedHat 8+ or CentOS 8+
+#   Default: true
 #
 class firewall::linux::redhat (
-  $ensure          = running,
-  $ensure_v6       = undef,
-  $enable          = true,
-  $enable_v6       = undef,
-  $service_name    = $::firewall::params::service_name,
-  $service_name_v6 = $::firewall::params::service_name_v6,
-  $package_name    = $::firewall::params::package_name,
-  $package_ensure  = $::firewall::params::package_ensure,
+  $ensure           = running,
+  $ensure_v6        = undef,
+  $enable           = true,
+  $enable_v6        = undef,
+  $service_name     = $::firewall::params::service_name,
+  $service_name_v6  = $::firewall::params::service_name_v6,
+  $package_name     = $::firewall::params::package_name,
+  $package_ensure   = $::firewall::params::package_ensure,
+  $sysconfig_manage = $::firewall::params::sysconfig_manage,
 ) inherits ::firewall::params {
   $_ensure_v6 = pick($ensure_v6, $ensure)
   $_enable_v6 = pick($enable_v6, $enable)
@@ -47,6 +52,12 @@ class firewall::linux::redhat (
     }
   }
 
+  # in RHEL 8 / CentOS 8 nftables provides a replacement iptables cli
+  # but there is no nftables specific for ipv6 so throw a warning
+  if !$service_name_v6 and ($ensure_v6 or $enable_v6) {
+    warning('No v6 service available, $ensure_v6 and $enable_v6 are ignored')
+  }
+
   if $package_name {
     package { $package_name:
       ensure => $package_ensure,
@@ -75,11 +86,13 @@ class firewall::linux::redhat (
       hasstatus => true,
       provider  => systemd,
     }
-    service { $service_name_v6:
-      ensure    => $_ensure_v6,
-      enable    => $_enable_v6,
-      hasstatus => true,
-      provider  => systemd,
+    if $service_name_v6 {
+      service { $service_name_v6:
+        ensure    => $_ensure_v6,
+        enable    => $_enable_v6,
+        hasstatus => true,
+        provider  => systemd,
+      }
     }
   } else {
     service { $service_name:
@@ -87,69 +100,79 @@ class firewall::linux::redhat (
       enable    => $enable,
       hasstatus => true,
     }
-    service { $service_name_v6:
-      ensure    => $_ensure_v6,
-      enable    => $_enable_v6,
-      hasstatus => true,
+    if $service_name_v6 {
+      service { $service_name_v6:
+        ensure    => $_ensure_v6,
+        enable    => $_enable_v6,
+        hasstatus => true,
+      }
     }
   }
 
-  file { "/etc/sysconfig/${service_name}":
-    ensure => present,
-    owner  => 'root',
-    group  => 'root',
-    mode   => '0600',
-  }
-  file { "/etc/sysconfig/${service_name_v6}":
-    ensure => present,
-    owner  => 'root',
-    group  => 'root',
-    mode   => '0600',
-  }
+  if $sysconfig_manage {
+    file { "/etc/sysconfig/${service_name}":
+      ensure => present,
+      owner  => 'root',
+      group  => 'root',
+      mode   => '0600',
+    }
+    if $service_name_v6 {
+      file { "/etc/sysconfig/${service_name_v6}":
+        ensure => present,
+        owner  => 'root',
+        group  => 'root',
+        mode   => '0600',
+      }
+    }
 
-  # Before puppet 4, the autobefore on the firewall type does not work - therefore
-  # we need to keep this workaround here
-  if versioncmp($::puppetversion, '4.0') <= 0 {
-    File["/etc/sysconfig/${service_name}"]    -> Service[$service_name]
-    File["/etc/sysconfig/${service_name_v6}"] -> Service[$service_name_v6]
-  }
+    # Before puppet 4, the autobefore on the firewall type does not work - therefore
+    # we need to keep this workaround here
+    if versioncmp($::puppetversion, '4.0') <= 0 {
+      File<| title == "/etc/sysconfig/${service_name}" |> -> Service<| title == $service_name |>
+      File<| title == "/etc/sysconfig/${service_name_v6}" |> -> Service<| title == $service_name_v6 |>
+    }
 
-  # Redhat 7 selinux user context for /etc/sysconfig/iptables is set to system_u
-  # Redhat 7 selinux type context for /etc/sysconfig/iptables is set to system_conf_t
-  case $::selinux {
-    #lint:ignore:quoted_booleans
-    'true',true: {
-      case $::operatingsystem {
-        'CentOS': {
-          case $::operatingsystemrelease {
-            /^6\..*/: {
-              File["/etc/sysconfig/${service_name}"] { seluser => 'unconfined_u', seltype => 'system_conf_t' }
-              File["/etc/sysconfig/${service_name_v6}"] { seluser => 'unconfined_u', seltype => 'system_conf_t' }
-            }
+    # Redhat 7 selinux user context for /etc/sysconfig/iptables is set to system_u
+    # Redhat 7 selinux type context for /etc/sysconfig/iptables is set to system_conf_t
+    case $::selinux {
+      #lint:ignore:quoted_booleans
+      'true',true: {
+        case $::operatingsystem {
+          'CentOS': {
+            case $::operatingsystemrelease {
+              /^6\..*/: {
+                $seluser = 'unconfined_u'
+                $seltype = 'system_conf_t'
+              }
 
-            /^7\..*/: {
-              File["/etc/sysconfig/${service_name}"] { seluser => 'system_u', seltype => 'system_conf_t' }
-              File["/etc/sysconfig/${service_name_v6}"] { seluser => 'system_u', seltype => 'system_conf_t' }
-            }
+              /^7\..*/: {
+                $seluser = 'system_u'
+                $seltype = 'system_conf_t'
+              }
 
-            default : {
-              File["/etc/sysconfig/${service_name}"] { seluser => 'unconfined_u', seltype => 'etc_t' }
-              File["/etc/sysconfig/${service_name_v6}"] { seluser => 'unconfined_u', seltype => 'etc_t' }
+              default : {
+                $seluser = 'unconfined_u'
+                $seltype = 'etc_t'
+              }
             }
+            File<| title == "/etc/sysconfig/${service_name}" |> { seluser => $seluser, seltype => $seltype }
+            File<| title == "/etc/sysconfig/${service_name_v6}" |> { seluser => $seluser, seltype => $seltype }
           }
-        }
 
-        # Fedora uses the same SELinux context as Redhat
-        'Fedora': {
-          File["/etc/sysconfig/${service_name}"] { seluser => 'system_u', seltype => 'system_conf_t' }
-          File["/etc/sysconfig/${service_name_v6}"] { seluser => 'system_u', seltype => 'system_conf_t' }
-        }
+          # Fedora uses the same SELinux context as Redhat
+          'Fedora': {
+            $seluser = 'system_u'
+            $seltype = 'system_conf_t'
+            File<| title == "/etc/sysconfig/${service_name}" |> { seluser => $seluser, seltype => $seltype }
+            File<| title == "/etc/sysconfig/${service_name_v6}" |> { seluser => $seluser, seltype => $seltype }
+          }
 
-        default: {}
+          default: {}
 
+        }
       }
+      default: {}
+      #lint:endignore
     }
-    default: {}
-    #lint:endignore
   }
 }
index b946c2f9e8bcd1513db99ee1f0ced70a3a5b8440..63c4cd68f8ab40c8378ad23601cc6bc76d123d7c 100644 (file)
@@ -3,24 +3,39 @@ class firewall::params {
   $package_ensure = 'present'
   case $::osfamily {
     'RedHat': {
-      $service_name = 'iptables'
-      $service_name_v6 = 'ip6tables'
       case $::operatingsystem {
         'Amazon': {
+          $service_name = 'iptables'
+          $service_name_v6 = 'ip6tables'
           $package_name = undef
+          $sysconfig_manage = true
         }
         'Fedora': {
+          $service_name = 'iptables'
+          $service_name_v6 = 'ip6tables'
           if versioncmp($::operatingsystemrelease, '15') >= 0 {
             $package_name = 'iptables-services'
           } else {
             $package_name = undef
           }
+          $sysconfig_manage = true
         }
         default: {
-          if versioncmp($::operatingsystemrelease, '7.0') >= 0 {
+          if versioncmp($::operatingsystemrelease, '8.0') >= 0 {
+            $service_name = 'nftables'
+            $service_name_v6 = undef
+            $package_name = 'nftables'
+            $sysconfig_manage = false
+          } elsif versioncmp($::operatingsystemrelease, '7.0') >= 0 {
+            $service_name = 'iptables'
+            $service_name_v6 = 'ip6tables'
             $package_name = 'iptables-services'
+            $sysconfig_manage = true
           } else {
+            $service_name = 'iptables'
+            $service_name_v6 = 'ip6tables'
             $package_name = 'iptables-ipv6'
+            $sysconfig_manage = true
           }
         }
       }
index 04a6d4534dca7c5e047d746c1ae9717e09e8095e..a1888bd29f8c819c066c6d873831c98c41535d3e 100644 (file)
@@ -35,6 +35,7 @@ describe 'firewall::linux::redhat', type: :class do
   ['RedHat', 'CentOS', 'Fedora'].each do |os|
     oldreleases = ((os == 'Fedora') ? ['14'] : ['6.5'])
     newreleases = ((os == 'Fedora') ? ['15', 'Rawhide'] : ['7.0.1406'])
+    nftablesreleases = ((os == 'Fedora') ? [] : ['8.0'])
 
     oldreleases.each do |osrel|
       context "os #{os} and osrel #{osrel}" do
@@ -50,6 +51,10 @@ describe 'firewall::linux::redhat', type: :class do
 
         it { is_expected.not_to contain_service('firewalld') }
         it { is_expected.not_to contain_package('iptables-services') }
+        it {
+          is_expected.to contain_file('/etc/sysconfig/iptables')
+          is_expected.to contain_file('/etc/sysconfig/ip6tables')
+        }
 
         it_behaves_like 'ensures iptables service'
       end
@@ -79,6 +84,10 @@ describe 'firewall::linux::redhat', type: :class do
             enable: 'true',
           )
         }
+        it {
+          is_expected.to contain_file('/etc/sysconfig/iptables')
+          is_expected.to contain_file('/etc/sysconfig/ip6tables')
+        }
 
         context 'with ensure => stopped' do
           let(:params) { { ensure: 'stopped' } }
@@ -138,5 +147,66 @@ describe 'firewall::linux::redhat', type: :class do
         it_behaves_like 'ensures iptables service'
       end
     end
+
+    nftablesreleases.each do |osrel|
+      context "os #{os} and osrel #{osrel}" do
+        let(:facts) do
+          {
+            operatingsystem: os,
+            operatingsystemrelease: osrel,
+            osfamily: 'RedHat',
+            selinux: false,
+            puppetversion: Puppet.version,
+          }
+        end
+
+        it {
+          is_expected.to contain_service('nftables').with(
+            ensure: 'running',
+            enable: 'true',
+          )
+          is_expected.not_to contain_service('iptables')
+        }
+
+        context 'with ensure => stopped' do
+          let(:params) { { ensure: 'stopped' } }
+
+          it {
+            is_expected.to contain_service('nftables').with(
+              ensure: 'stopped',
+            )
+          }
+        end
+
+        context 'with enable => false' do
+          let(:params) { { enable: 'false' } }
+
+          it {
+            is_expected.to contain_service('nftables').with(
+              enable: 'false',
+            )
+          }
+        end
+
+        it {
+          is_expected.to contain_service('firewalld').with(
+            ensure: 'stopped',
+            enable: false,
+            before: ['Package[nftables]', 'Service[nftables]'],
+          )
+        }
+
+        it {
+          is_expected.to contain_package('nftables').with(
+            ensure: 'present',
+            before: 'Service[nftables]',
+          )
+        }
+
+        it {
+          is_expected.not_to contain_file('/etc/sysconfig/nftables')
+        }
+      end
+    end
   end
 end