Created IAC reverse generator

This commit is contained in:
p2913020
2026-05-22 00:19:30 -04:00
parent d04c2c6e4b
commit 1a11244fff
161 changed files with 26806 additions and 51 deletions

View File

@@ -0,0 +1,59 @@
"""Multi-provider resource merging with conflict resolution.
Merges resources from multiple scan profiles into a unified inventory,
resolving naming conflicts by prefixing with the provider identifier.
"""
from dataclasses import replace
from collections import defaultdict
from iac_reverse.models import DiscoveredResource, ScanResult
class ResourceMerger:
"""Merges resources from multiple ScanResult objects into a unified list.
When resources from different providers share the same name, the merger
resolves the conflict by prefixing each conflicting resource's name with
its provider identifier (e.g., "kubernetes_nginx", "docker_swarm_nginx").
Provider-specific attributes are preserved unchanged.
"""
def merge(self, scan_results: list[ScanResult]) -> list[DiscoveredResource]:
"""Merge resources from multiple scan results into a unified list.
Args:
scan_results: List of ScanResult objects, one per provider/scan profile.
Returns:
A unified list of DiscoveredResource with naming conflicts resolved
by prefixing conflicting names with the provider identifier.
"""
# Collect all resources from all scan results
all_resources: list[DiscoveredResource] = []
for result in scan_results:
all_resources.extend(result.resources)
# Group resources by name to detect conflicts
resources_by_name: dict[str, list[DiscoveredResource]] = defaultdict(list)
for resource in all_resources:
resources_by_name[resource.name].append(resource)
# Identify conflicting names: same name from different providers
conflicting_names: set[str] = set()
for name, resources in resources_by_name.items():
providers = {r.provider for r in resources}
if len(providers) > 1:
conflicting_names.add(name)
# Build the merged list, resolving conflicts
merged: list[DiscoveredResource] = []
for resource in all_resources:
if resource.name in conflicting_names:
prefixed_name = f"{resource.provider.value}_{resource.name}"
merged.append(replace(resource, name=prefixed_name))
else:
merged.append(resource)
return merged