-
Notifications
You must be signed in to change notification settings - Fork 311
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Resolve #1114] Resolvable Template Handler configs and the !stack_at…
…tr resolver (#1189) This pull request adds two related things: 1. Template handler configurations are now fully resolvable. 2. You can now use the `!stack_attr` resolver to reference other configurations on the stack and StackGroup The need for these two things came about in my testing on the recent changes to Sceptre's resolvers. ## Why is this necessary? Previously, I had this on one of my stacks: ```yaml template: type: sam path: beatbox/template.yaml artifact_bucket_name: {{ template_bucket_name }} artifact_prefix: {{ template_key_prefix }} ``` ^^ This has been working just fine until I set `template_bucket_name` in my project to a `!stack_output` resolver. Once I did that, however, the template handler blew up because Jinja was attempting to cast the StackOutput resolver to string. With the changes in this PR, I can now do this: ```yaml template: type: sam path: beatbox/template.yaml # This will access and resolve the value of template_bucket_name from the StackGroup # and then access that value as the resolved value for handler. artifact_bucket_name: !stack_attr template_bucket_name artifact_prefix: {{ template_key_prefix }} ```
- Loading branch information
1 parent
b44797a
commit d6ecbd2
Showing
10 changed files
with
268 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
from typing import Any, List | ||
|
||
from sceptre.resolvers import Resolver | ||
|
||
|
||
class StackAttr(Resolver): | ||
"""Resolves to the value of another field on the Stack Config, including other resolvers. | ||
The argument for this resolver should be the "key path" from the stack object, which can access | ||
nested keys/indexes using a "." to separate segments. | ||
For example, given this Stack Config structure... | ||
sceptre_user_data: | ||
nested_list: | ||
- first | ||
- second | ||
Using "!stack_attr sceptre_user_data.nested_list.1" on your stack would resolve to "second". | ||
""" | ||
|
||
# These are all the attributes on Stack Configs whose names are changed when they are assigned | ||
# to the Stack instance. | ||
STACK_ATTR_MAP = { | ||
'template': 'template_handler_config', | ||
'protect': 'protected', | ||
'stack_name': 'external_name', | ||
'stack_tags': 'tags' | ||
} | ||
|
||
def resolve(self) -> Any: | ||
"""Returns the resolved value of the field referenced by the resolver's argument.""" | ||
segments = self.argument.split('.') | ||
|
||
# Remap top-level attributes to match stack config | ||
first_segment = segments[0] | ||
segments[0] = self.STACK_ATTR_MAP.get(first_segment, first_segment) | ||
|
||
if self._key_is_from_stack_group_config(first_segment): | ||
obj = self.stack.stack_group_config | ||
else: | ||
obj = self.stack | ||
|
||
result = self._recursively_resolve_segments(obj, segments) | ||
return result | ||
|
||
def _key_is_from_stack_group_config(self, key: str): | ||
return key in self.stack.stack_group_config and not hasattr(self.stack, key) | ||
|
||
def _recursively_resolve_segments(self, obj: Any, segments: List[str]): | ||
if not segments: | ||
return obj | ||
|
||
attr_name, *rest = segments | ||
if isinstance(obj, dict): | ||
value = obj[attr_name] | ||
elif isinstance(obj, list): | ||
value = obj[int(attr_name)] | ||
else: | ||
value = getattr(obj, attr_name) | ||
|
||
return self._recursively_resolve_segments(value, rest) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.