Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] IPU: Firewalld actors for el9 to el10 #1303

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from leapp.actors import Actor
from leapp.libraries.actor.private_firewalldcollectdirectconfig import read_config
from leapp.models import FirewalldDirectConfig
from leapp.tags import FactsPhaseTag, IPUWorkflowTag


class FirewalldCollectDirectConfig(Actor):
"""
This actor reads firewalld's configuration and produces Model
FirewalldDirectConfig.
"""

name = 'firewalld_collect_direct_config'
consumes = ()
produces = (FirewalldDirectConfig,)
tags = (FactsPhaseTag, IPUWorkflowTag)

def process(self):
self.produce(read_config())
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from leapp.models import FirewalldDirectConfig

try:
from firewall.core.fw import Firewall
except ImportError:
pass


def read_config():
try:
fw = Firewall(offline=True)
except NameError:
# import failure missing means firewalld is not installed. Just return
# the defaults.
return FirewalldDirectConfig()

# This does not actually start firewalld. It just loads the configuration a
# la firewall-offline-cmd.
fw.start()

conf = fw.config.get_direct().export_config()

conf_dict = {}
conf_dict['has_permanent_configuration'] = any(conf)

return FirewalldDirectConfig(**conf_dict)
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from leapp.actors import Actor
from leapp.libraries.actor.private_firewalldcollectglobalconfig import read_config
from leapp.models import FirewalldGlobalConfig
from leapp.tags import FactsPhaseTag, IPUWorkflowTag


class FirewalldCollectGlobalConfig(Actor):
"""
This actor reads firewalld's configuration and produces Model
FirewalldGlobalConfig.
"""

name = 'firewalld_collect_global_config'
consumes = ()
produces = (FirewalldGlobalConfig,)
tags = (FactsPhaseTag, IPUWorkflowTag)

def process(self):
self.produce(read_config())
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
from leapp.models import FirewalldGlobalConfig

try:
from firewall.core.fw import Firewall
except ImportError:
pass


def as_bool(value):
if isinstance(value, bool):
return value
if isinstance(value, str):
if value in ["no", "false"]:
return False
return True

return False


def read_config():
try:
fw = Firewall(offline=True)
except NameError:
# import failure missing means firewalld is not installed. Just return
# the defaults.
return FirewalldGlobalConfig()

# This does not actually start firewalld. It just loads the configuration a
# la firewall-offline-cmd.
fw.start()

conf = fw.config.get_firewalld_conf()

conf_dict = {}
conf_dict['defaultzone'] = conf.get('DefaultZone')
conf_dict['cleanuponexit'] = as_bool(conf.get('CleanupOnExit'))
conf_dict['cleanupmodulesonexit'] = as_bool(conf.get('CleanupModulesOnExit'))
conf_dict['ipv6_rpfilter'] = conf.get('IPv6_rpfilter')
conf_dict['individualcalls'] = as_bool(conf.get('IndividualCalls'))
conf_dict['logdenied'] = "off" if conf.get('LogDenied') in [None, "no"] else conf.get('LogDenied')
conf_dict['firewallbackend'] = conf.get('FirewallBackend')
conf_dict['flushallonreload'] = as_bool(conf.get('FlushAllOnReload'))
conf_dict['reloadpolicy'] = conf.get('ReloadPolicy')
conf_dict['rfc3964_ipv4'] = as_bool(conf.get('RFC3964_IPv4'))
conf_dict['nftablesflowtable'] = conf.get('NftablesFlowtable')
conf_dict['nftablescounters'] = as_bool(conf.get('NftablesCounters'))
conf_dict['nftablestableowner'] = as_bool(conf.get('NftablesTableOwner'))

# These have been removed in RHEL-10.
#
conf_dict['allowzonedrifting'] = False
conf_dict['lockdown'] = False

return FirewalldGlobalConfig(**conf_dict)
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
from leapp.actors import Actor
from leapp.models import FirewalldDirectConfig, FirewalldGlobalConfig, FirewallsFacts, RpmTransactionTasks
from leapp.tags import ChecksPhaseTag, IPUWorkflowTag


class FirewalldIptablesModules(Actor):
"""
This actor cause kernel-modules-extra to be installed if firewalld is using
iptables.
"""

name = 'firewalld_iptables_modules'
consumes = (FirewallsFacts, FirewalldGlobalConfig, FirewalldDirectConfig)
produces = (RpmTransactionTasks,)
tags = (ChecksPhaseTag, IPUWorkflowTag)

def process(self):
# If firewalld is not enabled then don't bother the user about its
# configuration.
for facts in self.consume(FirewallsFacts):
if not facts.firewalld.enabled:
return

flag = False

for config in self.consume(FirewalldGlobalConfig):
if config.firewallbackend == "iptables":
flag = True
break

for config in self.consume(FirewalldDirectConfig):
if config.has_permanent_configuration:
flag = True
break

if flag:
self.produce(RpmTransactionTasks(to_install=['kernel-modules-extra']))
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
from leapp.models import (
FirewalldDirectConfig,
FirewalldGlobalConfig,
FirewallsFacts,
FirewallStatus,
RpmTransactionTasks
)


def test_produce(current_actor_context):
status = FirewallStatus(enabled=True, active=True)
current_actor_context.feed(FirewallsFacts(firewalld=status,
iptables=status,
ip6tables=status))
current_actor_context.feed(FirewalldGlobalConfig(firewallbackend='iptables'))
current_actor_context.run()
assert current_actor_context.consume(RpmTransactionTasks)[0].to_install[0] == 'kernel-modules-extra'


def test_produce_02(current_actor_context):
status = FirewallStatus(enabled=True, active=True)
current_actor_context.feed(FirewallsFacts(firewalld=status,
iptables=status,
ip6tables=status))
current_actor_context.feed(FirewalldDirectConfig(has_permanent_configuration=True))
current_actor_context.run()
assert current_actor_context.consume(RpmTransactionTasks)[0].to_install[0] == 'kernel-modules-extra'


def test_no_produce_negative(current_actor_context):
current_actor_context.feed(FirewalldGlobalConfig())
current_actor_context.run()
assert not current_actor_context.consume(RpmTransactionTasks)


def test_no_produce_negative_02(current_actor_context):
status = FirewallStatus(enabled=False, active=True)
current_actor_context.feed(FirewallsFacts(firewalld=status,
iptables=status,
ip6tables=status))
current_actor_context.feed(FirewalldGlobalConfig(firewallbackend='iptables'))
current_actor_context.run()
assert not current_actor_context.consume(RpmTransactionTasks)


def test_no_produce_negative_03(current_actor_context):
current_actor_context.feed(FirewalldDirectConfig())
current_actor_context.run()
assert not current_actor_context.consume(RpmTransactionTasks)
12 changes: 12 additions & 0 deletions repos/system_upgrade/el9toel10/models/firewallddirectconfig.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from leapp.models import fields, Model
from leapp.topics import SystemInfoTopic


class FirewalldDirectConfig(Model):
"""
The model contains firewalld direct configuration. The configuration is
usually located at /etc/firewalld/direct.xml.
"""
topic = SystemInfoTopic

has_permanent_configuration = fields.Boolean(default=False)
31 changes: 31 additions & 0 deletions repos/system_upgrade/el9toel10/models/firewalldglobalconfig.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from leapp.models import fields, Model
from leapp.topics import SystemInfoTopic


class FirewalldGlobalConfig(Model):
"""
The model contains firewalld global configuration. The configuration is
usually located at /etc/firewalld/firewalld.conf.
"""
topic = SystemInfoTopic

# Defaults for RHEL-10.
#
defaultzone = fields.String(default='public')
cleanuponexit = fields.Boolean(default=True)
cleanupmodulesonexit = fields.Boolean(default=False)
ipv6_rpfilter = fields.String(default='yes')
individualcalls = fields.Boolean(default=False)
logdenied = fields.String(default='off')
firewallbackend = fields.String(default='nftables')
flushallonreload = fields.Boolean(default=True)
reloadpolicy = fields.String(default='INPUT:DROP,FORWARD:DROP,OUTPUT:DROP')
rfc3964_ipv4 = fields.Boolean(default=True)
nftablesflowtable = fields.String(default='off')
nftablescounters = fields.Boolean(default=False)
nftablestableowner = fields.Boolean(default=False)

# These are deprecated and other values are ignored in RHEL-10.
#
allowzonedrifting = fields.Boolean(default=False)
erig0 marked this conversation as resolved.
Show resolved Hide resolved
lockdown = fields.Boolean(default=False)