Skip to content

Commit cab5a5e

Browse files
Merge pull request #449 from iriusrisk/hotfix/BLAZ-1929
[hotfix/BLAZ-1929] to main
2 parents 89d86a0 + 6caaa75 commit cab5a5e

3 files changed

Lines changed: 118 additions & 27 deletions

File tree

slp_tfplan/slp_tfplan/objects/tfplan_objects.py

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from enum import Enum
2-
from typing import List, Dict, Union, Optional
2+
from typing import Union, Optional
33

44
from otm.otm.entity.component import Component
55
from otm.otm.entity.dataflow import Dataflow
@@ -19,8 +19,8 @@ def __init__(self,
1919
component_type: str,
2020
parent: str,
2121
parent_type: ParentType,
22-
tags: [str],
23-
clones_ids: [str] = None,
22+
tags: list[str],
23+
clones_ids: list[str] = None,
2424
tf_resource_id: str = None,
2525
tf_type: str = None,
2626
configuration: {} = None):
@@ -68,7 +68,7 @@ class SecurityGroupCIDRType(Enum):
6868

6969
@auto_repr
7070
class SecurityGroupCIDR:
71-
def __init__(self, cidr_blocks: List[str], description: str, type: SecurityGroupCIDRType,
71+
def __init__(self, cidr_blocks: list[str], description: str, type: SecurityGroupCIDRType,
7272
from_port: int = None, to_port: int = None,
7373
protocol: str = None):
7474
self.cidr_blocks = cidr_blocks
@@ -81,19 +81,19 @@ def __init__(self, cidr_blocks: List[str], description: str, type: SecurityGroup
8181

8282
@auto_repr
8383
class SecurityGroup:
84-
def __init__(self, security_group_id: str, name: str, ingress_sgs: List[str] = None, egress_sgs: List[str] = None,
85-
ingress_cidr: List[SecurityGroupCIDR] = None, egress_cidr: List[SecurityGroupCIDR] = None):
84+
def __init__(self, security_group_id: str, name: str, ingress_sgs: list[str] = None, egress_sgs: list[str] = None,
85+
ingress_cidr: list[SecurityGroupCIDR] = None, egress_cidr: list[SecurityGroupCIDR] = None):
8686
self.id: str = security_group_id
8787
self.name: str = name
88-
self.ingress_sgs: List[str] = ingress_sgs
89-
self.egress_sgs: List[str] = egress_sgs
90-
self.ingress_cidr: List[SecurityGroupCIDR] = ingress_cidr
91-
self.egress_cidr: List[SecurityGroupCIDR] = egress_cidr
88+
self.ingress_sgs: list[str] = ingress_sgs
89+
self.egress_sgs: list[str] = egress_sgs
90+
self.ingress_cidr: list[SecurityGroupCIDR] = ingress_cidr
91+
self.egress_cidr: list[SecurityGroupCIDR] = egress_cidr
9292

9393

9494
@auto_repr
9595
class LaunchTemplate:
96-
def __init__(self, launch_template_id: str, security_groups_ids: List[str]):
96+
def __init__(self, launch_template_id: str, security_groups_ids: list[str]):
9797
self.id = launch_template_id
9898
self.security_groups_ids = security_groups_ids
9999

@@ -104,11 +104,11 @@ class TFPlanOTM(OTM):
104104
def __init__(self,
105105
project_id: str,
106106
project_name: str,
107-
components: List[TFPlanComponent],
108-
security_groups: List[SecurityGroup],
109-
launch_templates: List[LaunchTemplate],
110-
variables: Dict[str, Union[list, str]],
111-
dataflows: List[Dataflow],
107+
components: list[TFPlanComponent],
108+
security_groups: list[SecurityGroup],
109+
launch_templates: list[LaunchTemplate],
110+
variables: dict[str, Union[list, str]],
111+
dataflows: list[Dataflow],
112112
default_trustzone: Trustzone = None):
113113
super().__init__(project_name, project_id, IacType.TERRAFORM)
114114
self.default_trustzone = default_trustzone

slp_tfplan/slp_tfplan/transformers/singleton_transformer.py

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import itertools
2-
from typing import List, Dict
32

43
from otm.otm.entity.dataflow import Dataflow
54
from sl_util.sl_util.iterations_utils import remove_from_list
@@ -8,7 +7,7 @@
87
from slp_tfplan.slp_tfplan.transformers.transformer import Transformer
98

109

11-
def _merge_component_configurations(otm_components: List[TFPlanComponent]) -> Dict:
10+
def _merge_component_configurations(otm_components: list[TFPlanComponent]) -> dict:
1211
merge_configuration = {}
1312
for component in otm_components:
1413
merge_configuration = {
@@ -17,7 +16,7 @@ def _merge_component_configurations(otm_components: List[TFPlanComponent]) -> Di
1716
return merge_configuration
1817

1918

20-
def _find_equivalent_dataflows(dataflow: Dataflow, dataflows: List[Dataflow]) -> List[Dataflow]:
19+
def _find_equivalent_dataflows(dataflow: Dataflow, dataflows: list[Dataflow]) -> list[Dataflow]:
2120
equivalent_dataflows = []
2221
for df in dataflows:
2322
if _are_equivalent_dataflows(dataflow, df):
@@ -27,11 +26,7 @@ def _find_equivalent_dataflows(dataflow: Dataflow, dataflows: List[Dataflow]) ->
2726

2827

2928
def _are_sibling(component, sibling):
30-
if component.category and sibling.category:
31-
return component.category == sibling.category
32-
if not component.category and not sibling.category:
33-
return component.type == sibling.type
34-
return False
29+
return component.type == sibling.type and component.category == sibling.category
3530

3631

3732
def _are_equivalent_dataflows(dataflow_1: Dataflow, dataflow_2: Dataflow) -> bool:
@@ -45,7 +40,7 @@ def _are_equivalent_dataflows(dataflow_1: Dataflow, dataflow_2: Dataflow) -> boo
4540
return is_same_dataflow or is_reverse_bidirectional_dataflow
4641

4742

48-
def _merge_dataflows(origin_dataflow: Dataflow, dataflows: List[Dataflow]) -> Dataflow:
43+
def _merge_dataflows(origin_dataflow: Dataflow, dataflows: list[Dataflow]) -> Dataflow:
4944
for df in dataflows:
5045
if origin_dataflow.tags is None:
5146
origin_dataflow.tags = df.tags
@@ -69,7 +64,7 @@ def _merge_dataflows(origin_dataflow: Dataflow, dataflows: List[Dataflow]) -> Da
6964
def __build_singleton_name(component: TFPlanComponent):
7065
return component.category or f"{component.type} (grouped)"
7166

72-
def _build_singleton_component(otm_components: List[TFPlanComponent]) -> TFPlanComponent:
67+
def _build_singleton_component(otm_components: list[TFPlanComponent]) -> TFPlanComponent:
7368
tags = list(set(itertools.chain.from_iterable([c.tags or [] for c in otm_components])))
7469
configuration = _merge_component_configurations(otm_components)
7570
component_id = otm_components[0].id
@@ -91,7 +86,7 @@ def __init__(self, otm: TFPlanOTM):
9186
self.otm_components = self.otm.components
9287
self.otm_dataflows = self.otm.dataflows
9388

94-
self.singleton_component_relations: Dict[str, TFPlanComponent] = {}
89+
self.singleton_component_relations: dict[str, TFPlanComponent] = {}
9590

9691
def transform(self):
9792
self.__populate_singleton_component_relations()

slp_tfplan/tests/unit/transformers/test_singleton_transformer.py

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from random import randrange
2+
from pytest import mark, param
23

34
from otm.otm.entity.parent_type import ParentType
45
from slp_tfplan.slp_tfplan.transformers.singleton_transformer import SingletonTransformer
@@ -495,3 +496,98 @@ def test_singleton_by_group_and_type_works_mixed(self):
495496
assert len(otm.components) == 2
496497
assert otm.components[0].id == component_a.id
497498
assert otm.components[1].id == component_c.id
499+
500+
@mark.parametrize("components, expected_count", [
501+
param(
502+
[
503+
build_mocked_component({
504+
'component_name': 'component_a',
505+
'tf_type': 'type_a',
506+
'configuration': {SINGLETON_CONFIG: True, CATEGORY_CONFIG: 'Category'},
507+
}),
508+
build_mocked_component({
509+
'component_name': 'component_b',
510+
'tf_type': 'type_b',
511+
'configuration': {SINGLETON_CONFIG: True, CATEGORY_CONFIG: 'Category'},
512+
})
513+
],
514+
2,
515+
id="same category but different types should not singleton"
516+
),
517+
param(
518+
[
519+
build_mocked_component({
520+
'component_name': 'component_a',
521+
'tf_type': 'same_type',
522+
'configuration': {SINGLETON_CONFIG: True, CATEGORY_CONFIG: 'Category_A'},
523+
}),
524+
build_mocked_component({
525+
'component_name': 'component_b',
526+
'tf_type': 'same_type',
527+
'configuration': {SINGLETON_CONFIG: True, CATEGORY_CONFIG: 'Category_B'},
528+
})
529+
],
530+
2,
531+
id="same type but different categories should not singleton"
532+
),
533+
param(
534+
[
535+
build_mocked_component({
536+
'component_name': 'component_a',
537+
'tf_type': 'same_type',
538+
'configuration': {SINGLETON_CONFIG: True, CATEGORY_CONFIG: None},
539+
}),
540+
build_mocked_component({
541+
'component_name': 'component_b',
542+
'tf_type': 'same_type',
543+
'configuration': {SINGLETON_CONFIG: True, CATEGORY_CONFIG: 'Category'},
544+
})
545+
],
546+
2,
547+
id="same type but one category is none should not singleton"
548+
),
549+
param(
550+
[
551+
build_mocked_component({
552+
'component_name': 'component_a',
553+
'tf_type': 'same_type',
554+
'configuration': {SINGLETON_CONFIG: True, CATEGORY_CONFIG: 'Category'},
555+
}),
556+
build_mocked_component({
557+
'component_name': 'component_b',
558+
'tf_type': 'same_type',
559+
'configuration': {SINGLETON_CONFIG: True, CATEGORY_CONFIG: 'Category'},
560+
})
561+
],
562+
1,
563+
id="same type and same category should singleton"
564+
),
565+
param(
566+
[
567+
build_mocked_component({
568+
'component_name': 'component_a',
569+
'tf_type': 'same_type',
570+
'configuration': {SINGLETON_CONFIG: True, CATEGORY_CONFIG: None},
571+
}),
572+
build_mocked_component({
573+
'component_name': 'component_b',
574+
'tf_type': 'same_type',
575+
'configuration': {SINGLETON_CONFIG: True, CATEGORY_CONFIG: None},
576+
})
577+
],
578+
1,
579+
id="same type and both categories none should singleton"
580+
),
581+
])
582+
def test_singleton_category_and_type(self, components, expected_count):
583+
"""
584+
Test if singleton is correctly applied based on type and category combinations.
585+
"""
586+
# GIVEN an OTM with the provided components
587+
otm = build_mocked_otm(components)
588+
589+
# WHEN SingletonTransformer::transform is invoked
590+
SingletonTransformer(otm).transform()
591+
592+
# THEN verify the expected number of components remain after the transformation
593+
assert len(otm.components) == expected_count

0 commit comments

Comments
 (0)