URL: https://github.com/freeipa/freeipa/pull/4506
Author: stanislavlevin
 Title: #4506: ipatests: Mark firewalld commands as no-op on non-firewalld 
distros
Action: opened

PR body:
"""
The FreeIPA integration tests strictly require Firewalld.
But not all the distros have such or any other high-level tool
for managing a firewall. Thus, to run integration tests on such systems
NoOpFirewall class has been added, which provides no-op firewalld
commands.

Fixes: https://pagure.io/freeipa/issue/8261
"""

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/4506/head:pr4506
git checkout pr4506
From 8502fa721fb94c2e721c28cf40d528da74b51f2d Mon Sep 17 00:00:00 2001
From: Stanislav Levin <s...@altlinux.org>
Date: Tue, 17 Mar 2020 16:56:35 +0300
Subject: [PATCH] ipatests: Mark firewalld commands as no-op on non-firewalld
 distros

The FreeIPA integration tests strictly require Firewalld.
But not all the distros have such or any other high-level tool
for managing a firewall. Thus, to run integration tests on such systems
NoOpFirewall class has been added, which provides no-op firewalld
commands.

Fixes: https://pagure.io/freeipa/issue/8261
Signed-off-by: Stanislav Levin <s...@altlinux.org>
---
 ipatests/pytest_ipa/integration/firewall.py | 160 +++++++++++++++++++-
 1 file changed, 157 insertions(+), 3 deletions(-)

diff --git a/ipatests/pytest_ipa/integration/firewall.py b/ipatests/pytest_ipa/integration/firewall.py
index 7315a68eaf..0dd6fe8582 100644
--- a/ipatests/pytest_ipa/integration/firewall.py
+++ b/ipatests/pytest_ipa/integration/firewall.py
@@ -4,14 +4,115 @@
 
 """Firewall class for integration testing using firewalld"""
 
+import abc
+
 from ipapython import ipautil
 
 
-class Firewall:
+class FirewallBase(abc.ABC):
+    def __init__(self, host):
+        """Initialize with host where firewall changes should be applied"""
+
+    @abc.abstractmethod
+    def run(self):
+        """Enable and start firewall service"""
+
+    @abc.abstractmethod
+    def enable_service(self, service):
+        """Enable firewall rules for service"""
+
+    @abc.abstractmethod
+    def disable_service(self, service):
+        """Disable firewall rules for service"""
+
+    @abc.abstractmethod
+    def enable_services(self, services):
+        """Enable firewall rules for list of services"""
+
+    @abc.abstractmethod
+    def disable_services(self, services):
+        """Disable firewall rules for list of services"""
+
+    @abc.abstractmethod
+    def passthrough_rule(self, rule, ipv=None):
+        """Generic method to get direct passthrough rules to
+        rule is an ip[6]tables rule without using the ip[6]tables command.
+        The rule will per default be added to the IPv4 and IPv6 firewall.
+        If there are IP version specific parts in the rule, please make sure
+        that ipv is adapted properly.
+        The rule is added to the direct sub chain of the chain that is used
+        in the rule"""
+
+    @abc.abstractmethod
+    def add_passthrough_rules(self, rules, ipv=None):
+        """Add passthough rules to the end of the chain
+        rules is a list of ip[6]tables rules, where the first entry of each
+        rule is the chain. No --append/-A, --delete/-D should be added before
+        the chain name, beacuse these are added by the method.
+        If there are IP version specific parts in the rule, please make sure
+        that ipv is adapted properly.
+        """
+
+    @abc.abstractmethod
+    def prepend_passthrough_rules(self, rules, ipv=None):
+        """Insert passthough rules starting at position 1 as a block
+        rules is a list of ip[6]tables rules, where the first entry of each
+        rule is the chain. No --append/-A, --delete/-D should be added before
+        the chain name, beacuse these are added by the method.
+        If there are IP version specific parts in the rule, please make sure
+        that ipv is adapted properly.
+        """
+
+    @abc.abstractmethod
+    def remove_passthrough_rules(self, rules, ipv=None):
+        """Remove passthrough rules
+        rules is a list of ip[6]tables rules, where the first entry of each
+        rule is the chain. No --append/-A, --delete/-D should be added before
+        the chain name, beacuse these are added by the method.
+        If there are IP version specific parts in the rule, please make sure
+        that ipv is adapted properly.
+        """
+
+
+class NoOpFirewall(FirewallBase):
+    """
+    no-op firewall is intended for platforms which haven't high level firewall
+    backend.
+    """
+    def run(self):
+        pass
+
+    def enable_service(self, service):
+        pass
+
+    def disable_service(self, service):
+        pass
+
+    def enable_services(self, services):
+        pass
+
+    def disable_services(self, services):
+        pass
+
+    def passthrough_rule(self, rule, ipv=None):
+        pass
+
+    def add_passthrough_rules(self, rules, ipv=None):
+        pass
+
+    def prepend_passthrough_rules(self, rules, ipv=None):
+        pass
+
+    def remove_passthrough_rules(self, rules, ipv=None):
+        pass
+
+
+class FirewallD(FirewallBase):
     def __init__(self, host):
-        """Initialize with host where firewall changes should be applied
-        Unmasks, enables and starts firewalld."""
+        """Initialize with host where firewall changes should be applied"""
         self.host = host
+
+    def run(self):
         # Unmask firewalld service
         self.host.run_command(["systemctl", "unmask", "firewalld"])
         # Enable firewalld service
@@ -120,3 +221,56 @@ def remove_passthrough_rules(self, rules, ipv=None):
         """
         for rule in rules:
             self.passthrough_rule(["-D"] + rule, ipv)
+
+
+class Firewall(FirewallBase):
+    """
+    Depending on the ipaplatform proxy firewall tasks to the actual backend.
+    Current supported backends: firewalld and no-op firewall.
+    """
+    def __init__(self, host):
+        """Initialize with host where firewall changes should be applied"""
+        # break circular dependency
+        from .tasks import get_platform
+
+        self.host = host
+        platform = get_platform(host)
+
+        firewalls = {
+            'rhel': FirewallD,
+            'fedora': FirewallD,
+            'ubuntu': FirewallD,
+            'altlinux': NoOpFirewall,
+        }
+        if platform not in firewalls:
+            raise ValueError(
+                "Platform {} hasn't supported Firewall".format(platform))
+        self.firewall = firewalls[platform](self.host)
+        self.run()
+
+    def run(self):
+        self.firewall.run()
+
+    def enable_service(self, service):
+        self.firewall.enable_service(service)
+
+    def disable_service(self, service):
+        self.firewall.disable_service(service)
+
+    def enable_services(self, services):
+        self.firewall.enable_services(services)
+
+    def disable_services(self, services):
+        self.firewall.disable_services(services)
+
+    def passthrough_rule(self, rule, ipv=None):
+        self.firewall.passthrough_rule(rule, ipv)
+
+    def add_passthrough_rules(self, rules, ipv=None):
+        self.firewall.add_passthrough_rules(rules, ipv)
+
+    def prepend_passthrough_rules(self, rules, ipv=None):
+        self.firewall.prepend_passthrough_rules(rules, ipv)
+
+    def remove_passthrough_rules(self, rules, ipv=None):
+        self.firewall.remove_passthrough_rules(rules, ipv)
_______________________________________________
FreeIPA-devel mailing list -- freeipa-devel@lists.fedorahosted.org
To unsubscribe send an email to freeipa-devel-le...@lists.fedorahosted.org
Fedora Code of Conduct: 
https://docs.fedoraproject.org/en-US/project/code-of-conduct/
List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines
List Archives: 
https://lists.fedorahosted.org/archives/list/freeipa-devel@lists.fedorahosted.org

Reply via email to