Skip to content

Commit 3033a36

Browse files
committed
Add update_if_exist option to add_output
With !89+ assets export an output for the S3 URI. It doesn't work for PyFunctionAssets if reused multiple times as `add_output` doesn't check if the output already exists. With this change, the function can override the already existing output to avoid the error
1 parent d2c8f2d commit 3033a36

File tree

2 files changed

+40
-4
lines changed

2 files changed

+40
-4
lines changed

src/e3/aws/troposphere/__init__.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,8 @@ def resources(self, stack: Stack) -> list[AWSObject | Construct]:
128128
Description=f"S3 URI for the Asset {self.name}",
129129
Export=Export(name=self.s3_uri_output_name),
130130
Value=f"s3://{stack.s3_bucket}/{stack.s3_assets_key}{self.s3_key}",
131-
)
131+
),
132+
update_if_exist=True,
132133
)
133134
return []
134135

@@ -309,12 +310,23 @@ def add_parameter(self, parameter: Parameter | list[Parameter]) -> None:
309310
else:
310311
self.template.add_parameter(param)
311312

312-
def add_output(self, output: Output | list[Output]) -> None:
313+
def add_output(
314+
self, output: Output | list[Output], update_if_exist: bool = False
315+
) -> None:
313316
"""Add outputs to stack template.
314317
315318
:param output: output to add to the template
319+
:param update_if_exist: update the output if already exists, avoiding
320+
the duplicate key exception
316321
"""
317-
self.template.add_output(output)
322+
if not isinstance(output, list):
323+
output = [output]
324+
325+
for out in output:
326+
if update_if_exist and out.title in self.template.outputs:
327+
self.template.outputs[out.title] = out
328+
else:
329+
self.template.add_output(out)
318330

319331
def add_condition(self, condition_name: str, condition: ConditionFunction) -> None:
320332
"""Add condition to stack template.

tests/tests_e3_aws/troposphere/stack/stack_test.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import json
44
from pathlib import Path
5-
5+
import pytest
66
from troposphere import Parameter, Output, Export
77

88
from e3.aws.troposphere.s3.bucket import Bucket
@@ -85,6 +85,30 @@ def test_add_outputs() -> None:
8585
assert stack.export()["Resources"] == expected_template
8686

8787

88+
def test_update_output() -> None:
89+
"""Test updating an already existing output."""
90+
o = Output("Output", Description="My output", Value=Export(name="Output"))
91+
stack = Stack("test-stack", "this is a test stack")
92+
stack.add_output(o)
93+
94+
# This one should fail because of the duplicate key
95+
with pytest.raises(match='duplicate key "Output" detected'):
96+
stack.add_output(o)
97+
98+
# This one should update the output
99+
o.Description = "Updated output"
100+
stack.add_output(o, update_if_exist=True)
101+
102+
assert stack.export()["Outputs"] == {
103+
"Output": {
104+
"Description": "Updated output",
105+
"Value": {
106+
"Name": "Output",
107+
},
108+
},
109+
}
110+
111+
88112
def test_extend() -> None:
89113
"""Test adding multiple construct and retrieving an AWSObject from a stack."""
90114
stack = Stack("test-stack", "this is a test stack")

0 commit comments

Comments
 (0)