From d42e57512354dc4628a0c3631841a25c9a4e8b92 Mon Sep 17 00:00:00 2001 From: Daniel Goldman Date: Sun, 15 Sep 2024 16:53:35 -0400 Subject: [PATCH 1/3] render security rules as `None` to prevent TF from deleting existing TF can specify security rules as independent resources or as subresources of the NSG. If security_rule is not None, it assumes all of the detected security rules are subresources. --- llamazure/tf/network.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llamazure/tf/network.py b/llamazure/tf/network.py index d2ee8cc..1caa594 100644 --- a/llamazure/tf/network.py +++ b/llamazure/tf/network.py @@ -44,7 +44,7 @@ def render(self) -> dict: "name": self.name, "resource_group_name": self.rg, "location": self.location, - "security_rule": [], + "security_rule": None, "tags": self.tags, } From 3ff572d5d32e43566d291d9192d8ce89addfc434 Mon Sep 17 00:00:00 2001 From: Daniel Goldman Date: Sun, 15 Sep 2024 18:47:50 -0400 Subject: [PATCH 2/3] feature: add RefList type for correct pluralisation when referencing lists in variables --- llamazure/tf/changelog.md | 9 ++++++++- llamazure/tf/models.py | 22 ++++++++++++++++++---- llamazure/tf/models_test.py | 7 ++++++- llamazure/tf/network.py | 14 +++++++------- 4 files changed, 39 insertions(+), 13 deletions(-) diff --git a/llamazure/tf/changelog.md b/llamazure/tf/changelog.md index ad2a98b..c21dd3a 100644 --- a/llamazure/tf/changelog.md +++ b/llamazure/tf/changelog.md @@ -1,7 +1,14 @@ # 0 +## 0.1 + +### 0.1.0 + +- fix : fix for TF considering NSG rules as subresources +- feature : add RefList type for correct pluralisation when referencing variables that are lists + ## 0.0 ### 0.0.1 -- feature: easily generate nsg rules +- feature : easily generate nsg rules diff --git a/llamazure/tf/models.py b/llamazure/tf/models.py index 3cb2e39..504a85c 100644 --- a/llamazure/tf/models.py +++ b/llamazure/tf/models.py @@ -3,6 +3,7 @@ from abc import ABC, abstractmethod from collections import defaultdict from dataclasses import dataclass +from typing import Union class TFResource(ABC): @@ -51,9 +52,22 @@ def register(resource: TFResource): } -def _pluralise(k: str, v: list[str], pluralise: str = "s") -> dict[str, str | list[str]]: +@dataclass(frozen=True) +class RefList: + """A reference to a var containing a list""" + + var: str + + +TFList = Union[list[str], RefList] + + +def _pluralise(k: str, v: TFList, pluralise: str = "s") -> dict[str, str | list[str]]: """Format the k-v pair, pluralising the k if necessary""" - if len(v) == 1: - return {k: v[0]} + if isinstance(v, RefList): + return {k + pluralise: [v.var]} else: - return {k + pluralise: v} + if len(v) == 1: + return {k: v[0]} + else: + return {k + pluralise: v} diff --git a/llamazure/tf/models_test.py b/llamazure/tf/models_test.py index e299069..e4322db 100644 --- a/llamazure/tf/models_test.py +++ b/llamazure/tf/models_test.py @@ -1,4 +1,4 @@ -from llamazure.tf.models import _pluralise +from llamazure.tf.models import RefList, _pluralise class TestPluralise: @@ -31,3 +31,8 @@ def test_multiple_elements_with_es_suffix(self): result = _pluralise("box", ["box", "fox"], pluralise="es") expected = {"boxes": ["box", "fox"]} assert result == expected + + def test_reflist(self): + result = _pluralise("apple", RefList("ref")) + expected = {"apples": ["ref"]} + assert result == expected diff --git a/llamazure/tf/network.py b/llamazure/tf/network.py index 1caa594..d42c588 100644 --- a/llamazure/tf/network.py +++ b/llamazure/tf/network.py @@ -5,7 +5,7 @@ from enum import Enum from typing import Generic, TypeVar -from llamazure.tf.models import AnyTFResource, TFResource, _pluralise +from llamazure.tf.models import AnyTFResource, TFList, TFResource, _pluralise T = TypeVar("T") @@ -70,12 +70,12 @@ class NSGRule: direction: Direction protocol: str = "Tcp" - src_ports: list[str] = field(default_factory=lambda: ["*"]) - src_addrs: list[str] = field(default_factory=lambda: ["*"]) - src_sgids: list[str] = field(default_factory=lambda: []) - dst_ports: list[str] = field(default_factory=lambda: ["*"]) - dst_addrs: list[str] = field(default_factory=lambda: ["*"]) - dst_sgids: list[str] = field(default_factory=lambda: []) + src_ports: TFList = field(default_factory=lambda: ["*"]) + src_addrs: TFList = field(default_factory=lambda: ["*"]) + src_sgids: TFList = field(default_factory=lambda: []) + dst_ports: TFList = field(default_factory=lambda: ["*"]) + dst_addrs: TFList = field(default_factory=lambda: ["*"]) + dst_sgids: TFList = field(default_factory=lambda: []) description: str = "" From 1abe0bc7ebaa9542663ce3b93490b80c214cd069 Mon Sep 17 00:00:00 2001 From: Daniel Goldman Date: Sun, 15 Sep 2024 21:34:34 -0400 Subject: [PATCH 3/3] fix test --- llamazure/tf/network_test.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llamazure/tf/network_test.py b/llamazure/tf/network_test.py index 438e996..b72f6d9 100644 --- a/llamazure/tf/network_test.py +++ b/llamazure/tf/network_test.py @@ -56,7 +56,7 @@ def test_terraform_example(self): "name": "acceptanceTestSecurityGroup1", "location": "West Europe", "resource_group_name": "example-resources", - "security_rule": [], + "security_rule": None, "tags": { "environment": "Production", }, @@ -91,5 +91,5 @@ def test_example(self): assert ( json.dumps(tf.render()) - == '{"resource": {"azurerm_network_security_group": {"n": {"name": "n", "resource_group_name": "rg", "location": "l", "security_rule": [], "tags": {}}}}}' + == '{"resource": {"azurerm_network_security_group": {"n": {"name": "n", "resource_group_name": "rg", "location": "l", "security_rule": null, "tags": {}}}}}' )