Skip to content

Commit

Permalink
Handle firewall related cleaner failure
Browse files Browse the repository at this point in the history
  • Loading branch information
badrogger committed Jan 22, 2025
1 parent 241ab43 commit 9e33f82
Show file tree
Hide file tree
Showing 10 changed files with 61 additions and 33 deletions.
25 changes: 7 additions & 18 deletions core/schains/cleaner.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,9 @@

from core.node import get_current_nodes, get_skale_node_version
from core.schains.checks import SChainChecks
from core.schains.config.file_manager import ConfigFileManager
from core.schains.config.directory import schain_config_dir
from core.schains.dkg.utils import get_secret_key_share_filepath
from core.schains.firewall.utils import get_default_rule_controller
from core.schains.config.helper import (
get_base_port_from_config,
get_node_ips_from_config,
get_own_ip_from_config,
)
from core.schains.firewall.utils import cleanup_firewall_for_schain, get_default_rule_controller
from core.schains.process import ProcessReport, terminate_process
from core.schains.runner import get_container_name, is_exited
from core.schains.external_config import ExternalConfig
Expand Down Expand Up @@ -152,8 +146,10 @@ def get_schains_on_node(dutils=None):
schains_with_container = get_schains_with_containers(dutils)
schains_active_records = get_schains_names()
schains_firewall_configs = list(
map(lambda name: name.removeprefix('skale-'),
get_schains_firewall_configs())
map(
lambda name: name.removeprefix('skale-'),
get_schains_firewall_configs()
)
)
logger.info(
'dirs %s, containers: %s, records: %s, firewall configs: %s',
Expand Down Expand Up @@ -281,15 +277,8 @@ def cleanup_schain(
if check_status['volume']:
remove_schain_volume(schain_name, dutils=dutils)
if any(checks.firewall_rules.data):
conf = ConfigFileManager(schain_name).skaled_config
base_port = get_base_port_from_config(conf)
own_ip = get_own_ip_from_config(conf)
node_ips = get_node_ips_from_config(conf)
ranges = []
if estate is not None:
ranges = estate.ranges
rc.configure(base_port=base_port, own_ip=own_ip, node_ips=node_ips, sync_ip_ranges=ranges)
rc.cleanup()
logger.info('Cleaning firewall for %s', schain_name)
cleanup_firewall_for_schain(schain_name)

if estate is not None and estate.ima_linked:
if check_status.get('ima_container', False) or is_exited(
Expand Down
11 changes: 7 additions & 4 deletions core/schains/firewall/firewall_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,15 +87,14 @@ def remove_rules(self, rules: Iterable[SChainRule]) -> None:
for rule in rules:
self.host_controller.remove_rule(rule)

def flush(self) -> None:
self.remove_rules(self.rules)
self.host_controller.cleanup()


class IptablesSChainFirewallManager(SChainFirewallManager):
def create_host_controller(self) -> IptablesController:
return IptablesController()

def cleanup(self) -> None:
self.remove_rules(self.rules)

Check warning on line 96 in core/schains/firewall/firewall_manager.py

View check run for this annotation

Codecov / codecov/patch

core/schains/firewall/firewall_manager.py#L96

Added line #L96 was not covered by tests


class NFTSchainFirewallManager(SChainFirewallManager):
def create_host_controller(self) -> NFTablesController:
Expand All @@ -111,3 +110,7 @@ def rules_saved(self) -> bool:
def base_config_applied(self) -> bool:
return self.host_controller.has_chain(self.host_controller.chain) and \

Check warning on line 111 in core/schains/firewall/firewall_manager.py

View check run for this annotation

Codecov / codecov/patch

core/schains/firewall/firewall_manager.py#L111

Added line #L111 was not covered by tests
self.host_controller.has_drop_rule(self.first_port, self.last_port)

def cleanup(self) -> None:
self.host_controller.cleanup()
self.host_controller.remove_saved_rules()

Check warning on line 116 in core/schains/firewall/firewall_manager.py

View check run for this annotation

Codecov / codecov/patch

core/schains/firewall/firewall_manager.py#L115-L116

Added lines #L115 - L116 were not covered by tests
5 changes: 2 additions & 3 deletions core/schains/firewall/nftables.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class NFTablesController(IHostFirewallController):
plock = multiprocessing.Lock()
FAMILY = 'inet'

def __init__(self, table: str = TABLE, chain: str = CHAIN) -> None:
def __init__(self, chain: str, table: str = TABLE) -> None:
self.table = table
self.chain = f'skale-{chain}'
self._nftables = importlib.import_module('nftables')
Expand Down Expand Up @@ -384,9 +384,8 @@ def get_saved_rules(self) -> str:
return nft_chain_file.read()

Check warning on line 384 in core/schains/firewall/nftables.py

View check run for this annotation

Codecov / codecov/patch

core/schains/firewall/nftables.py#L381-L384

Added lines #L381 - L384 were not covered by tests

def remove_saved_rules(self) -> None:
if os.isfile(self.nft_chain_path):
if os.path.isfile(self.nft_chain_path):
os.remove(self.nft_chain_path)

Check warning on line 388 in core/schains/firewall/nftables.py

View check run for this annotation

Codecov / codecov/patch

core/schains/firewall/nftables.py#L387-L388

Added lines #L387 - L388 were not covered by tests

def cleanup(self) -> None:
self.remove_saved_rules()
self.delete_chain()
10 changes: 7 additions & 3 deletions core/schains/firewall/rule_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,9 +202,6 @@ def sync(self) -> None:
logger.debug('Syncing firewall rules with %s', erules)
self.firewall_manager.update_rules(erules)

def cleanup(self) -> None:
self.firewall_manager.flush()


class IptablesSChainRuleController(SChainRuleController):
@configured_only
Expand All @@ -223,6 +220,10 @@ def is_persistent(self) -> bool:
def is_inited(self) -> bool:
return True

Check warning on line 221 in core/schains/firewall/rule_controller.py

View check run for this annotation

Codecov / codecov/patch

core/schains/firewall/rule_controller.py#L221

Added line #L221 was not covered by tests

@configured_only
def cleanup(self) -> None:
self.firewall_manager.cleanup()

Check warning on line 225 in core/schains/firewall/rule_controller.py

View check run for this annotation

Codecov / codecov/patch

core/schains/firewall/rule_controller.py#L225

Added line #L225 was not covered by tests


class NFTSchainRuleController(SChainRuleController):
@configured_only
Expand All @@ -240,3 +241,6 @@ def is_persistent(self) -> bool:
@configured_only
def is_inited(self) -> bool:
return self.firewall_manager.base_config_applied()

Check warning on line 243 in core/schains/firewall/rule_controller.py

View check run for this annotation

Codecov / codecov/patch

core/schains/firewall/rule_controller.py#L243

Added line #L243 was not covered by tests

def cleanup(self) -> None:
self.firewall_manager.cleanup()

Check warning on line 246 in core/schains/firewall/rule_controller.py

View check run for this annotation

Codecov / codecov/patch

core/schains/firewall/rule_controller.py#L246

Added line #L246 was not covered by tests
2 changes: 1 addition & 1 deletion core/schains/firewall/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ def update_rules(self, rules: Iterable[SChainRule]) -> None: # pragma: no cover
pass

@abstractmethod
def flush(self) -> None: # pragma: no cover # noqa
def cleanup(self) -> None: # pragma: no cover # noqa
pass


Expand Down
7 changes: 7 additions & 0 deletions core/schains/firewall/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from skale import Skale

from .types import IpRange
from .nftables import NFTablesController
from .rule_controller import IptablesSChainRuleController, NFTSchainRuleController


Expand Down Expand Up @@ -101,3 +102,9 @@ def save_sync_ranges(sync_agent_ranges: List[IpRange], path: str) -> None:

def ranges_from_plain_tuples(plain_ranges: List[Tuple]) -> List[IpRange]:
return list(sorted(map(lambda r: IpRange(*r), plain_ranges)))


def cleanup_firewall_for_schain(schain_name: str) -> None:
nft = NFTablesController(chain=schain_name)
nft.cleanup()
nft.remove_saved_rules()

Check warning on line 110 in core/schains/firewall/utils.py

View check run for this annotation

Codecov / codecov/patch

core/schains/firewall/utils.py#L108-L110

Added lines #L108 - L110 were not covered by tests
4 changes: 2 additions & 2 deletions tests/firewall/firewall_manager_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def test_firewall_manager_update_existed():
assert fm.host_controller.remove_rule.call_count == 0


def test_firewall_manager_flush():
def test_firewall_manager_cleanup():
fm = SChainTestFirewallManager('test', 10000, 10064)
rules = [
SChainRule(10000, '2.2.2.2'),
Expand All @@ -63,6 +63,6 @@ def test_firewall_manager_flush():
fm.add_rules(rules)
fm.host_controller.add_rule(SChainRule(10072, '2.2.2.2'))

fm.flush()
fm.cleanup()
assert list(fm.rules) == []
assert fm.host_controller.has_rule(SChainRule(10072, '2.2.2.2'))
19 changes: 18 additions & 1 deletion tests/firewall/nftables_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

from core.schains.firewall.nftables import NFTablesController, NFT_CHAIN_BASE_PATH
from core.schains.firewall.types import SChainRule
from core.schains.firewall.utils import cleanup_firewall_for_schain
from tools.helper import run_cmd


Expand Down Expand Up @@ -87,6 +88,9 @@ def test_create_delete_chain(filter_table, nft_chain_folder):
manager.cleanup()
chains = run_cmd(['nft', 'list', 'chains']).stdout.decode('utf-8')
assert chains == 'table inet firewall {\n}\n'
assert os.path.isfile(nft_chain_path)

manager.remove_saved_rules()
assert not os.path.isfile(nft_chain_path)


Expand All @@ -106,8 +110,21 @@ def test_saved_rules(filter_table, nft_chain_folder):
assert not os.path.isfile(nft_chain_path)


def test_cleanup_firewall_for_schain(filter_table, nft_chain_folder):
chain_name = 'test-chain'
nft_chain_path = os.path.join(NFT_CHAIN_BASE_PATH, f'skale-{chain_name}.conf')

manager = NFTablesController(chain=chain_name)
manager.create_chain(first_port=10000, last_port=10063)

cleanup_firewall_for_schain(schain_name=chain_name)
chains = run_cmd(['nft', 'list', 'chains']).stdout.decode('utf-8')
assert chains == 'table inet firewall {\n}\n'
assert not os.path.isfile(nft_chain_path)


def add_remove_rule(srule, refresh):
manager = NFTablesController()
manager = NFTablesController(chain='test')
manager.add_rule(srule)
time.sleep(1)
if not manager.has_rule(srule):
Expand Down
5 changes: 4 additions & 1 deletion tests/schains/cleaner_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,8 @@ def test_get_schains_on_node(schain_dirs_for_monitor,
]).issubset(set(result))


def test_remove_schain(skale, schain_db, node_config, dutils):
@mock.patch('core.schains.cleaner.cleanup_firewall_for_schain')
def test_remove_schain(cleanup_firewall_for_schain, skale, schain_db, node_config, dutils):
schain_name = schain_db
remove_schain(skale, node_config.id, schain_name, msg='Test remove_schain', dutils=dutils)
container_name = SCHAIN_CONTAINER_NAME_TEMPLATE.format(schain_name)
Expand All @@ -250,7 +251,9 @@ def test_remove_schain(skale, schain_db, node_config, dutils):
assert record.is_deleted is True


@mock.patch('core.schains.cleaner.cleanup_firewall_for_schain')
def test_cleanup_schain(
cleanup_firewall_rules,
schain_db,
node_config,
schain_on_contracts,
Expand Down
6 changes: 6 additions & 0 deletions tests/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,9 @@ class SChainTestFirewallManager(SChainFirewallManager):
def create_host_controller(self):
return HostTestFirewallController()

def cleanup(self):
self.remove_rules(self.rules)


class SChainTestRuleController(SChainRuleController):
def create_firewall_manager(self):
Expand All @@ -248,6 +251,9 @@ def is_persistent(self) -> bool:
def is_inited(self) -> bool:
return True

def cleanup(self) -> None:
self.firewall_manager.cleanup()


def get_test_rule_controller(
name,
Expand Down

0 comments on commit 9e33f82

Please sign in to comment.