Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
81 commits
Select commit Hold shift + click to select a range
b08ece2
feat: added standard layer
ErikPre Mar 25, 2026
64da640
feat: stuff
ErikPre Mar 25, 2026
af68600
chore: Add TODO
Laennart Mar 25, 2026
5ffdaff
fix: Policy registration
Laennart Mar 25, 2026
10ecb5b
wip: Nat
Laennart Mar 25, 2026
a3d79be
fix: duplicate rulebase
Laennart Mar 25, 2026
032920c
wip: Broken with two policies
Laennart Mar 25, 2026
d46c0a4
Revert "chore: Add TODO"
Laennart Mar 27, 2026
a8fab50
Merge remote-tracking branch 'upstream/develop' into feature/checkpoi…
Laennart Mar 27, 2026
32029e6
fix: Checkpoint Policy Import
Laennart Mar 27, 2026
08188e4
Merge remote-tracking branch 'upstream/develop' into feature/checkpoi…
Laennart Mar 27, 2026
eb60980
feat: Get NAT rulebases
Laennart Mar 27, 2026
a4dedce
wip: NAT import
Laennart Mar 27, 2026
0f818a7
Merge remote-tracking branch 'upstream/develop' into feature/checkpoi…
Laennart Mar 27, 2026
dd5a7d3
fix: Database duplication errors
Laennart Mar 29, 2026
b2485c8
Merge remote-tracking branch 'upstream/develop' into feature/checkpoi…
Laennart Mar 29, 2026
2f1e37b
fix: malformed object warning
ErikPre Mar 29, 2026
0514aef
Merge remote-tracking branch 'upstream/develop' into feature/checkpoi…
Laennart Mar 30, 2026
78bcf2f
feat: Add stm_link_type
Laennart Mar 30, 2026
b0fdcd1
wip: Proper policy mapping & nat import
Laennart Mar 30, 2026
13f6ffc
Merge remote-tracking branch 'upstream/develop' into feature/checkpoi…
Laennart Mar 30, 2026
3e359bd
fix: multiple NAT objects
ErikPre Apr 1, 2026
b1c1d0d
wip: NAT rules working as rules
ErikPre Apr 1, 2026
d1f7bcb
Merge remote-tracking branch 'upstream/develop' into feature/checkpoi…
Laennart Apr 8, 2026
37ba8d2
chore: Revert sql upgrade script change
Laennart Apr 8, 2026
a47b191
fix: NAT query
Laennart Apr 8, 2026
5ac8a55
wip: NAT frontend
Laennart Apr 9, 2026
1c836b3
Merge remote-tracking branch 'upstream/develop' into feature/checkpoi…
Laennart Apr 9, 2026
bce860f
wip: NAT report
Laennart Apr 12, 2026
6d373ab
wip: NAT import
Laennart Apr 13, 2026
2f4f3ee
fix: NAT report
Laennart Apr 13, 2026
3de8cdd
Merge remote-tracking branch 'upstream/develop' into feature/checkpoi…
Laennart Apr 13, 2026
f694343
fix: Revert change
Laennart Apr 13, 2026
8d15525
fix: NAT report
Laennart Apr 13, 2026
57db4cf
fix: Nat rules set as access rule
Laennart Apr 13, 2026
ed5e471
refactor: Revert changes and remove unused attributes
Laennart Apr 13, 2026
d813b4d
wip: Fix NAT Rulebases missing
Laennart Apr 13, 2026
efecb08
fix: Rulebase order
Laennart Apr 14, 2026
b202e53
fix: Format
Laennart Apr 14, 2026
67add83
Merge remote-tracking branch 'upstream/develop' into feature/checkpoi…
Laennart Apr 14, 2026
6429a85
refactor: Satisfy Sonarqube
Laennart Apr 14, 2026
acf5cd8
feat: copilot comment, initial check
ErikPre Apr 15, 2026
9bc72fa
feat: set simpler standard
ErikPre Apr 15, 2026
e58a152
fix: pagination of gateways and servers
ErikPre Apr 15, 2026
56d7116
Merge remote-tracking branch 'upstream/develop' into feature/checkpoi…
Laennart Apr 15, 2026
f396510
wip: Review comments & new link type
Laennart Apr 16, 2026
ae594cc
Merge remote-tracking branch 'upstream/develop' into feature/checkpoi…
Laennart Apr 20, 2026
97103f9
feat: redo rule_type to type
ErikPre Apr 20, 2026
268a02b
fix: Query
Laennart Apr 21, 2026
4f36413
wip: Rule tree builder
Laennart Apr 21, 2026
074856c
fix: Format
Laennart Apr 21, 2026
deab96d
Merge remote-tracking branch 'upstream/develop' into feature/checkpoi…
Laennart Apr 27, 2026
4f10be6
fix: Review comments
Laennart Apr 27, 2026
8e8e7f7
fix: Review comments
Laennart Apr 27, 2026
0a86461
Merge branch 'develop' into feature/checkpoint-nat-support
Laennart May 18, 2026
cde5db7
feat: Forti NAT Support
Laennart May 22, 2026
53f72a3
feat: simplify function
ErikPre May 26, 2026
9ec613b
fix: Copilot issues
ErikPre May 26, 2026
6e5386f
Merge remote-tracking branch 'upstream/develop' into feature/checkpoi…
ErikPre May 26, 2026
899baa2
fix: made function easier
ErikPre May 26, 2026
7ce4132
Merge branch 'develop' into feature/checkpoint-nat-support
Y4nnikH May 27, 2026
6075cd9
Merge remote-tracking branch 'upstream/develop' into feature/checkpoi…
ErikPre Jun 1, 2026
258e190
refactor: linting
ErikPre Jun 2, 2026
cf3ed5d
fix: use long for bigint from database
ErikPre Jun 2, 2026
aa7e16c
fix: overwrite default egde-case
ErikPre Jun 2, 2026
f58da15
fix: long string
ErikPre Jun 3, 2026
46a6c1e
Merge remote-tracking branch 'upstream/develop' into feature/checkpoi…
ErikPre Jun 9, 2026
4767bbc
fix: making sure that fcntl is not throwing an exception
ErikPre Jun 10, 2026
40028f9
fix: tests for Original
ErikPre Jun 10, 2026
4bf27cb
feat: ipv6 support
ErikPre Jun 10, 2026
5416d30
feat: implemented all nat types
ErikPre Jun 14, 2026
cf3e19b
fix: made function easier
ErikPre Jun 16, 2026
ad37dec
fix: more sonarqube issues
ErikPre Jun 16, 2026
9c04889
Merge remote-tracking branch 'upstream/develop' into feature/checkpoi…
ErikPre Jun 16, 2026
9cf926a
fix: make import safer
ErikPre Jun 16, 2026
7083c2c
Merge branch 'develop' into feature/checkpoint-nat-support
ErikPre Jun 23, 2026
3ffda47
feat: bumped up version
ErikPre Jun 23, 2026
38ff70a
refactor: set standard time object to time
ErikPre Jun 23, 2026
970f884
refactor: time object
ErikPre Jun 23, 2026
3277863
feat: added NAT tests
ErikPre Jun 23, 2026
36e2c40
fix: cs tests
ErikPre Jun 23, 2026
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
2 changes: 1 addition & 1 deletion .agents
1 change: 1 addition & 0 deletions agents
Submodule agents added at a5ed17
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ fragment ruleFragment on rule {
rule_custom_fields
rule_implied
nat_rule
access_rule
xlate_rule
uiuser {
uiuser_username
}
Expand All @@ -133,6 +135,9 @@ fragment ruleFragment on rule {
rule_last_hit
}
rule_comment
ruleByXlateRule {
rule_uid
}
section_header: rule_head_text
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,8 @@ fragment ruleFragment on rule {
rule_custom_fields
rule_implied
nat_rule
access_rule
xlate_rule
uiuser {
uiuser_username
}
Expand All @@ -188,6 +190,9 @@ fragment ruleFragment on rule {
rule_last_hit
}
rule_comment
ruleByXlateRule {
rule_uid
}
section_header: rule_head_text
}

Expand Down
1 change: 1 addition & 0 deletions roles/database/files/sql/creation/fworch-fill-stm.sql
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,7 @@ insert into stm_link_type (id, name) VALUES (2, 'ordered');
insert into stm_link_type (id, name) VALUES (3, 'inline');
insert into stm_link_type (id, name) VALUES (4, 'concatenated');
insert into stm_link_type (id, name) VALUES (5, 'domain');
insert into stm_link_type (id, name) VALUES (6, 'nat');

-- insert into compliance.assessability_issue_type (type_id, type_name) VALUES (1, 'empty group');
-- insert into compliance.assessability_issue_type (type_id, type_name) VALUES (2, 'broadcast address');
Expand Down
1 change: 1 addition & 0 deletions roles/database/files/upgrade/9.1.11.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
insert into stm_link_type (id, name) VALUES (6, 'nat') ON CONFLICT DO NOTHING;
Comment thread
Laennart marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,7 @@ def get_rulebases(
native_config_domain: dict[str, Any] | None,
device_config: dict[str, Any] | None,
policy_rulebases_uid_list: list[str],
policy_structure: dict[str, Any],
is_global: bool = False,
access_type: str = "access",
rulebase_uid: str | None = None,
Expand Down Expand Up @@ -407,6 +408,7 @@ def get_rulebases(
show_params_rules,
is_global,
policy_rulebases_uid_list,
policy_structure=policy_structure,
)


Expand Down Expand Up @@ -530,6 +532,7 @@ def get_inline_layers_recursively(
show_params_rules: dict[str, Any],
is_global: bool,
policy_rulebases_uid_list: list[str],
policy_structure: dict[str, Any],
) -> list[str]:
"""
Takes current_rulebase, splits sections into sub-rulebases and searches for layerguards to fetch
Expand Down Expand Up @@ -569,6 +572,7 @@ def get_inline_layers_recursively(
is_global=is_global,
access_type="access",
rulebase_uid=rule["inline-layer"],
policy_structure=policy_structure,
)

return policy_rulebases_uid_list
Expand Down Expand Up @@ -978,3 +982,30 @@ def get_object_details_from_api(uid_missing_obj: str, sid: str = "", apiurl: str
return obj
FWOLogger.warning(f"missing nw obj of unexpected type '{obj_type}': {uid_missing_obj}")
return {}


def get_gateways_and_servers(sid: str = "", apiurl: str = "") -> list[dict[str, Any]]:
"""Fetch gateways and servers from the API."""
current = 0
total = 1

gateways_and_servers: list[dict[str, Any]] = []

while current < total:
try:
result = cp_api_call(apiurl, "show-gateways-and-servers", {"details-level": "full", "offset": current}, sid)
except Exception as e:
raise FwoImporterError(f"error while trying to get gateways and servers: {e}")

if result is None or "objects" not in result:
raise FwoImporterError("no objects received while trying to get gateways and servers")

gateways_and_servers.extend(result["objects"])

if "total" not in result or "to" not in result:
raise FwoImporterError("result does not contain total or to field while trying to get gateways and servers")

total = result["total"]
current = result["to"]
Comment thread
ErikPre marked this conversation as resolved.

return gateways_and_servers
264 changes: 264 additions & 0 deletions roles/importer/files/importer/fw_modules/checkpointR8x/cp_nat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,264 @@
from typing import Any

from fw_modules.checkpointR8x.cp_rule import parse_single_rule
from fwo_log import FWOLogger
from models.import_state import ImportState
from models.rulebase import Rulebase


def normalize_nat_rules(
native_config: dict[str, Any],
import_state: ImportState,
normalized_config: dict[str, Any],
):
native_nat_rulebases = native_config.get("nat_rulebases", [])
if not native_nat_rulebases:
return

for gateway in native_config["gateways"]:
parse_native_nat_rulebases(gateway, native_nat_rulebases, import_state, normalized_config, native_config)

Comment thread
ErikPre marked this conversation as resolved.
Comment thread
Laennart marked this conversation as resolved.

def get_initial_nat_rulebase_link(gateway: dict[str, Any], normalized_config: dict[str, Any]) -> dict[str, Any] | None:
normalized_gateway = next((gw for gw in normalized_config["gateways"] if gw["Uid"] == gateway["uid"]), None)

if normalized_gateway is None:
FWOLogger.warning("Could not find normalized gateway for initial NAT rulebase link: " + str(gateway["uid"]))
return None

initial_gateway_link = next(
(
link
for link in normalized_gateway["RulebaseLinks"]
if link.get("is_initial") and link.get("link_type") == "ordered"
),
None,
)

if initial_gateway_link is None:
FWOLogger.warning("Could not find initial gateway rulebase link for NAT rulebase: " + str(gateway["uid"]))
return None

return initial_gateway_link


def parse_native_nat_rulebases(
gateway: dict[str, Any],
native_nat_rulebases: list[dict[str, Any]],
import_state: ImportState,
normalized_config: dict[str, Any],
native_config: dict[str, Any],
):
for nat_rulebase in native_nat_rulebases:
if "nat_rule_chunks" not in nat_rulebase:
continue

normalized_nat_rulebase = insert_parent_nat_rulebase(gateway, import_state, normalized_config)
normalized_gateway = next((gw for gw in normalized_config["gateways"] if gw["Uid"] == gateway["uid"]), None)

if normalized_gateway is None:
FWOLogger.warning("Could not find normalized gateway for NAT rulebase, skipping: " + str(gateway["uid"]))
continue

initial_gateway_link = get_initial_nat_rulebase_link(gateway, normalized_config)

if initial_gateway_link is None:
continue

initial_to_rulebase_uid = initial_gateway_link.get("to_rulebase_uid")
if not initial_to_rulebase_uid:
FWOLogger.warning(
"Initial gateway rulebase link is missing to_rulebase_uid for NAT rulebase, skipping: "
+ str(gateway["uid"])
)
continue

insert_rulebase_link(
from_rulebase_uid=initial_to_rulebase_uid,
to_rulebase_uid=normalized_nat_rulebase.uid,
link_type="nat",
normalized_gateway=normalized_gateway,
)
Comment thread
ErikPre marked this conversation as resolved.

for chunk in nat_rulebase["nat_rule_chunks"]:
parse_nat_rule_chunk(
chunk,
normalized_nat_rulebase,
gateway,
native_config,
import_state,
normalized_config,
normalized_gateway,
)


def insert_parent_nat_rulebase(
gateway: dict[str, Any],
import_state: ImportState,
normalized_config: dict[str, Any],
) -> Rulebase:
nat_rulebase_uid = "nat-rulebase-" + gateway["uid"]
existing_nat_rulebase = next((rb for rb in normalized_config["policies"] if rb.uid == nat_rulebase_uid), None)

if existing_nat_rulebase is not None:
return existing_nat_rulebase

normalized_nat_rulebase = Rulebase(
uid=nat_rulebase_uid,
mgm_uid=import_state.mgm_details.uid,
name="NAT",
rules={},
)

normalized_config["policies"].append(normalized_nat_rulebase)

return normalized_nat_rulebase


def insert_rulebase_link(
from_rulebase_uid: str,
to_rulebase_uid: str,
link_type: str,
normalized_gateway: dict[str, Any],
) -> None:
if not any(
link
for link in normalized_gateway["RulebaseLinks"]
if link["to_rulebase_uid"] == to_rulebase_uid
and link["link_type"] == link_type
and link["from_rulebase_uid"] == from_rulebase_uid
):
normalized_gateway["RulebaseLinks"].append(
{
"from_rulebase_uid": from_rulebase_uid,
"to_rulebase_uid": to_rulebase_uid,
"link_type": link_type,
"is_initial": False,
"is_global": False,
"is_section": False,
}
)


def parse_nat_rulebase(
src_rulebase: dict[str, Any],
normalized_nat_rulebase: Rulebase,
gateway: dict[str, Any],
native_config: dict[str, Any],
import_state: ImportState,
normalized_config: dict[str, Any],
normalized_gateway: dict[str, Any],
):
section_rulebase = Rulebase(
uid=src_rulebase["uid"],
mgm_uid=import_state.mgm_details.uid,
name=src_rulebase["name"],
rules={},
)

if not any(rb for rb in normalized_config["policies"] if rb.uid == section_rulebase.uid):
normalized_config["policies"].append(section_rulebase)

insert_rulebase_link(
from_rulebase_uid=normalized_nat_rulebase.uid,
to_rulebase_uid=section_rulebase.uid,
link_type="nat",
normalized_gateway=normalized_gateway,
)

for rule in src_rulebase["rulebase"]:
parse_nat_rule(rule, section_rulebase, gateway, native_config)


def parse_nat_rule(
src_rulebase: dict[str, Any],
rulebase: Rulebase,
gateway: dict[str, Any],
native_config: dict[str, Any],
):
(rule_match, rule_xlate) = parse_nat_rule_transform(src_rulebase)
parse_single_rule(
rule_match,
rulebase,
rulebase.name,
rulebase.uid,
gateway,
native_config["policies"],
)
parse_single_rule( # do not increase rule_num here (xlate rules do not count)
rule_xlate,
rulebase,
rulebase.name,
rulebase.uid,
gateway,
native_config["policies"],
)


def parse_nat_rule_chunk(
chunk: dict[str, Any],
normalized_nat_rulebase: Rulebase,
gateway: dict[str, Any],
native_config: dict[str, Any],
import_state: ImportState,
normalized_config: dict[str, Any],
normalized_gateway: dict[str, Any],
):
if "rulebase" not in chunk:
return

for src_rulebase in chunk["rulebase"]:
if "rulebase" in src_rulebase:
parse_nat_rulebase(
src_rulebase,
normalized_nat_rulebase,
gateway,
native_config,
import_state,
normalized_config,
normalized_gateway,
)
if "rule-number" in src_rulebase: # rulebase is just a single rule (xlate rules do not count)
parse_nat_rule(src_rulebase, normalized_nat_rulebase, gateway, native_config)


def parse_nat_rule_transform(nat_rule: dict[str, Any]) -> tuple[dict[str, Any], dict[str, Any]]:
nat_in_rule = {
"uid": nat_rule["uid"],
"source": [nat_rule["original-source"]],
"destination": [nat_rule["original-destination"]],
"service": [nat_rule["original-service"]],
"action": [{"name": "accept", "type": "nat-action", "uid": nat_rule["uid"] + "_original-action"}],
"track": [{"type": "nat", "name": "None", "uid": nat_rule["uid"]}],
"type": "nat",
"rule-number": 0,
"source-negate": False,
"destination-negate": False,
"service-negate": False,
"install-on": nat_rule["install-on"],
"time": nat_rule.get("time", "time"),
"enabled": nat_rule["enabled"],
"comments": nat_rule["comments"],
Comment thread
ErikPre marked this conversation as resolved.
"nat_rule": True,
"xlate_rule_uid": nat_rule["uid"] + "_translated",
"access_rule": False,
}
Comment thread
Laennart marked this conversation as resolved.
Comment thread
ErikPre marked this conversation as resolved.
nat_out_rule = {
"uid": nat_rule["uid"] + "_translated",
"source": [nat_rule["translated-source"]],
"destination": [nat_rule["translated-destination"]],
"service": [nat_rule["translated-service"]],
"action": [{"name": "accept", "type": "nat-action", "uid": nat_rule["uid"] + "_translated-action"}],
"track": [{"type": "nat", "name": "None", "uid": nat_rule["uid"] + "_translated"}],
"type": "nat",
"rule-number": 0,
"enabled": True,
"source-negate": False,
"destination-negate": False,
"service-negate": False,
"install-on": nat_rule["install-on"],
"time": "time",
"nat_rule": True,
"access_rule": False,
}
return (nat_in_rule, nat_out_rule)
Loading
Loading