Skip to content
Merged
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
28 changes: 28 additions & 0 deletions transformers/vendors/fortinet_transformer.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
to convert between Fortinet-specific and universal data models.
"""

import jmespath

from transformers.action_mapper import ActionMapper
from transformers.base_transformer import BaseTransformer
from transformers.category_mapper import CategoryMapper
Expand Down Expand Up @@ -52,3 +54,29 @@
CategoryMapper({value: key for key, value in FORTINET_CATEGORY_MAP.items()}),
MetadataEnricher("fortinet"),
]

JMESPATH_FLATTEN_URLS = """
*[?modify_type!='Deleted'].*.data_urls.*.{
pattern: url,
action: `allow`,
category_id: 'Uncategorized',
list_name: @.name,
list_id: @.object_id,
type: @.data_type
}
"""

def flatten_fortinet_jmespath(url_lists: dict) -> list[dict]:
"""
Flatten Fortinet JSON using JMESPath.

Args:
url_lists: Nested Fortinet JSON URL list.

Returns:
Flat list of URL entries suitable for transformer input.
"""
result = jmespath.search(JMESPATH_FLATTEN_URLS, url_lists)
# jmespath returns a nested list, flatten if needed
flat_result = [item for sublist in result for item in sublist] if result else []
return flat_result
33 changes: 31 additions & 2 deletions transformers/vendors/netskope_transformer.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,53 @@
This module defines transformers and mappings required to convert
Netskope URL list configurations to and from the universal data model.
"""

import re
from typing import Any
from typing import Dict
from typing import List
from typing import Optional

import jmespath

from transformers.action_mapper import ActionMapper
from transformers.base_transformer import BaseTransformer
from transformers.category_mapper import CategoryMapper
from transformers.metadata_enricher import MetadataEnricher
from transformers.pattern_normalizer import PatternNormalizer
from transformers.type_mapper import TypeMapper

JMESPATH_NETSKOPE = """
values(@)[?modify_type!='Deleted'].{
list_name: name,
list_id: object_id,
type: data_type,
urls: values(data_urls)
}
"""

def flatten_netskope_jmespath(url_lists: dict) -> list[dict]:
"""Flatten the structure using jmespath."""
extracted = jmespath.search(JMESPATH_NETSKOPE, url_lists) or []
flat = []

for lst in extracted:
for entry in lst.get("urls", []):
url = entry.get("url")
if not url:
continue
flat.append({
"pattern": url,
"action": "allow",
"category_id": "Uncategorized",
"list_name": lst["list_name"],
"list_id": str(lst["list_id"]),
"type": lst["type"]
})
return flat

class NetskopePatternNormalizer(BaseTransformer):
"""Normalize Netskope URL patterns for vendor compatibility.

This transformer converts universal URL patterns into Netskope-
compatible formats:

Expand Down