-
Notifications
You must be signed in to change notification settings - Fork 6
feat: add sub function #171
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Luis-Henrique
wants to merge
60
commits into
main
Choose a base branch
from
feat/add-sub-function
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 57 commits
Commits
Show all changes
60 commits
Select commit
Hold shift + click to select a range
a68acba
feat: add get att intrinsic function
Luis-Henrique 7dddd14
Merge branch 'main' into feat/getatt-intrinsic-function
Luis-Henrique 96b1b45
feat: add join intrinsic function
Luis-Henrique 021100a
feat: add join intrinsic function
Luis-Henrique e4468e7
docs: update docstrings
Luis-Henrique 8b802b0
feat: add get att intrinsic function
Luis-Henrique 6fd85c2
feat: add select intrinsic function
Luis-Henrique dcf019a
fix: resolve intrinsic functions in select
Luis-Henrique cecc57f
feat: add split intrinsic function
Luis-Henrique c97fb1c
feat: add split intrinsic function
Luis-Henrique ac26009
Merge branch 'feat/getatt-intrinsic-function' into feat/join-intrinsi…
Luis-Henrique f74aad5
Merge branch 'feat/join-intrinsic-function' into feat/select-intrinsi…
Luis-Henrique 42a44c6
Merge branch 'feat/select-intrinsic-function' into feat/add-split-fun…
Luis-Henrique bb44bbf
feat: update intrinsic function to handle the short form of get att
Luis-Henrique 4fae8ca
Merge branch 'main' into feat/getatt-intrinsic-function
Luis-Henrique 027258f
Merge branch 'feat/getatt-intrinsic-function' into feat/join-intrinsi…
Luis-Henrique d257d56
Merge branch 'feat/join-intrinsic-function' into feat/select-intrinsi…
Luis-Henrique 2a1b04b
Merge branch 'feat/select-intrinsic-function' into feat/add-split-fun…
Luis-Henrique aa2b1db
feat: update select function
Luis-Henrique 8a955b0
Merge branch 'main' into feat/getatt-intrinsic-function
Luis-Henrique 26ad31f
Merge branch 'feat/getatt-intrinsic-function' into feat/join-intrinsi…
Luis-Henrique 8fbb012
Merge branch 'feat/join-intrinsic-function' into feat/select-intrinsi…
Luis-Henrique b9c9903
Merge branch 'feat/select-intrinsic-function' into feat/add-split-fun…
Luis-Henrique 9c2d633
wip: add sub function
Luis-Henrique 9988540
wip: add sub function
Luis-Henrique c8d33da
refactor: update param type and variable name
Luis-Henrique f4ca1bf
Merge branch 'feat/getatt-intrinsic-function' of github.com:noverde/f…
Luis-Henrique 02e7cd9
feat: update join function
Luis-Henrique 20099c1
Merge branch 'feat/join-intrinsic-function' of github.com:noverde/fas…
Luis-Henrique 312b9fa
feat: update join function
Luis-Henrique fcc3a63
Merge branch 'feat/getatt-intrinsic-function' into feat/join-intrinsi…
Luis-Henrique f244a86
feat: update select function test
Luis-Henrique 7e1a3ce
Merge branch 'feat/select-intrinsic-function' of github.com:noverde/f…
Luis-Henrique 83cdf16
Merge branch 'feat/join-intrinsic-function' into feat/select-intrinsi…
Luis-Henrique 1b47c20
Merge branch 'feat/select-intrinsic-function' into feat/add-split-fun…
Luis-Henrique b3d14ce
feat: update select function
Luis-Henrique 2258fd1
feat: update select function
Luis-Henrique 8dd68d5
Merge branch 'feat/select-intrinsic-function' into feat/add-split-fun…
Luis-Henrique 078ab66
feat: update split function
Luis-Henrique e810204
feat: update split function
Luis-Henrique 3a25222
test: add getatt function tests
Luis-Henrique 4acd284
Merge branch 'feat/getatt-intrinsic-function' into feat/join-intrinsi…
Luis-Henrique 0621aa3
test: add join function tests
Luis-Henrique 8a07fd5
Merge branch 'feat/join-intrinsic-function' into feat/select-intrinsi…
Luis-Henrique 901ac5f
test: add select function tests
Luis-Henrique 3ee4c2a
Merge branch 'feat/select-intrinsic-function' into feat/add-split-fun…
Luis-Henrique 350ab84
test: add split function tests
Luis-Henrique 6b1f717
feat: make format
Luis-Henrique fc2eee9
Merge branch 'feat/add-split-function' into feat/add-sub-function
Luis-Henrique 9521938
feat: add sub intrinsic function
Luis-Henrique 050e3cc
feat: add sub intrinsic function
Luis-Henrique a7777b2
feat: update cloudformation templates
Luis-Henrique f868bf4
Merge branch 'feat/getatt-intrinsic-function' into feat/join-intrinsi…
Luis-Henrique fc33617
Merge branch 'feat/join-intrinsic-function' into feat/select-intrinsi…
Luis-Henrique 194fcf2
feat: remove file
Luis-Henrique e0f2397
Merge branch 'feat/select-intrinsic-function' into feat/add-split-fun…
Luis-Henrique 35fb0f7
Merge branch 'feat/add-split-function' into feat/add-sub-function
Luis-Henrique a65a566
fix: update replace function
Luis-Henrique 16cd406
Merge branch 'feat/add-sub-function' of github.com:noverde/faster-sam…
Luis-Henrique 0cf27a0
feat: uodate replace function
Luis-Henrique File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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 |
|---|---|---|
| @@ -1,7 +1,9 @@ | ||
| import base64 | ||
| import logging | ||
| from enum import Enum | ||
| import os | ||
| from pathlib import Path | ||
| import re | ||
| from typing import Any, Dict, List, Optional, Union | ||
|
|
||
| import yaml | ||
|
|
@@ -584,7 +586,16 @@ def eval(function: Dict[str, Any], template: Dict[str, Any]) -> Any: | |
| NotImplementedError | ||
| If the intrinsic function is not implemented. | ||
| """ | ||
| implemented = ("Fn::Base64", "Fn::FindInMap", "Ref") | ||
| implemented = ( | ||
| "Fn::Base64", | ||
| "Fn::FindInMap", | ||
| "Fn::GetAtt", | ||
| "Fn::Join", | ||
| "Fn::Select", | ||
| "Fn::Split", | ||
| "Fn::Sub", | ||
| "Ref", | ||
| ) | ||
|
|
||
| fun, val = list(function.items())[0] | ||
|
|
||
|
|
@@ -597,6 +608,21 @@ def eval(function: Dict[str, Any], template: Dict[str, Any]) -> Any: | |
| if "Fn::FindInMap" == fun: | ||
| return IntrinsicFunctions.find_in_map(val, template) | ||
|
|
||
| if "Fn::GetAtt" == fun: | ||
| return IntrinsicFunctions.get_att(val, template) | ||
|
|
||
| if "Fn::Join" == fun: | ||
| return IntrinsicFunctions.join(val, template) | ||
|
|
||
| if "Fn::Select" == fun: | ||
| return IntrinsicFunctions.select(val, template) | ||
|
|
||
| if "Fn::Split" == fun: | ||
| return IntrinsicFunctions.split(val, template) | ||
|
|
||
| if "Fn::Sub" == fun: | ||
| return IntrinsicFunctions.sub(val, template) | ||
|
|
||
| if "Ref" == fun: | ||
| return IntrinsicFunctions.ref(val, template) | ||
|
|
||
|
|
@@ -676,3 +702,228 @@ def ref(value: str, template: Dict[str, Any]) -> Optional[str]: | |
| # NOTE: this is a partial implementation | ||
|
|
||
| return None | ||
|
|
||
| @staticmethod | ||
| def get_att(value: Union[List[str], str], template: Dict[str, Any]) -> Optional[str]: | ||
| """ | ||
| Gets the value of an attribute from a CloudFormation template based on a list | ||
| of logical name and attribute name. | ||
|
|
||
| Parameters | ||
| ---------- | ||
| value : List[Any] | ||
| List containing the logical name and attribute name | ||
| template : Dict[str, Any] | ||
| A dictionary representing the CloudFormation template. | ||
|
|
||
| Returns | ||
| ------- | ||
| Optional[str] | ||
| The value of atribute name, or None if the keys are not found. | ||
| """ | ||
| if isinstance(value, str): | ||
| value = value.split(".") | ||
|
|
||
| logical_name, attribute_name = value | ||
|
|
||
| if logical_name not in template["Resources"]: | ||
| return None | ||
|
|
||
| if isinstance(attribute_name, dict): | ||
| attribute_name = IntrinsicFunctions.eval(attribute_name, template) | ||
|
|
||
| if attribute_name is None: | ||
| return None | ||
|
|
||
| if attribute_name not in template["Resources"][logical_name]["Properties"]: | ||
| return None | ||
|
|
||
| attribute_value = template["Resources"][logical_name]["Properties"][attribute_name] | ||
|
|
||
| if isinstance(attribute_value, dict): | ||
| attribute_value = IntrinsicFunctions.eval(attribute_value, template) | ||
|
|
||
| if attribute_value is None: | ||
| return None | ||
|
|
||
| return attribute_value | ||
|
|
||
| @staticmethod | ||
| def join(value: List[Any], template: Dict[str, Any]) -> Optional[str]: | ||
| """ | ||
| Joins elements in a list with a specified delimiter. | ||
|
|
||
| Parameters | ||
| ---------- | ||
| value : List[Any] | ||
| A list containing two elements: the delimiter as the first element, | ||
| and the values to join as the second element. | ||
| template : Dict[str, Any] | ||
| A dictionary representing the CloudFormation template. | ||
|
|
||
| Returns | ||
| ------- | ||
| Optional[str] | ||
| The joined string if successful; otherwise, None. | ||
| """ | ||
| delimiter, values = value | ||
|
|
||
| for index, element in enumerate(values): | ||
| if isinstance(element, dict): | ||
| element = IntrinsicFunctions.eval(element, template) | ||
|
|
||
| if element is None: | ||
| return None | ||
|
|
||
| values[index] = element | ||
|
|
||
| return delimiter.join(values) | ||
|
|
||
| @staticmethod | ||
| def select(value: List[Any], template: Dict[str, Any]) -> Optional[str]: | ||
| """ | ||
| Selects a value from a list based on the given index. If the value at the index | ||
| is a dictionary, it evaluates it using CloudFormation template data. | ||
| Parameters | ||
| ---------- | ||
| value : List[Any] | ||
| A list containing values from which to select. | ||
| template : Dict[str, Any] | ||
| A dictionary representing the CloudFormation template. | ||
| Returns | ||
| ------- | ||
| Optional[str] | ||
| The selected value from the list, or None if any of the evaluated | ||
| values are None. | ||
| """ | ||
| index, objects = value | ||
|
|
||
| if isinstance(index, dict): | ||
| index = IntrinsicFunctions.eval(index, template) | ||
|
|
||
| if index is None: | ||
| return None | ||
|
|
||
| if isinstance(objects, dict): | ||
| objects = IntrinsicFunctions.eval(objects, template) | ||
|
|
||
| if objects is None: | ||
| return None | ||
| else: | ||
| for i, obj in enumerate(objects): | ||
| if isinstance(obj, dict): | ||
| objects[i] = IntrinsicFunctions.eval(obj, template) | ||
|
|
||
| if objects[i] is None: | ||
| return None | ||
|
|
||
| return objects[int(index)] | ||
|
|
||
| @staticmethod | ||
| def split(value: List[Any], template: Dict[str, Any]) -> Optional[str]: | ||
| """ | ||
| Splits a list of values using a specified delimiter. | ||
|
|
||
| Parameters | ||
| ---------- | ||
| value : List[Any] | ||
| A tuple containing the delimiter as its first element, followed | ||
| by a list of values to split. | ||
| template : Dict[str, Any] | ||
| A dictionary representing the CloudFormation template. | ||
|
|
||
| Returns | ||
| ------- | ||
| Optional[str] | ||
| A list of strings resulting from splitting using the delimiter. | ||
| or None if any of the evaluated values are None. | ||
| """ | ||
| delimiter, source = value | ||
|
|
||
| if isinstance(source, dict): | ||
| source = IntrinsicFunctions.eval(source, template) | ||
|
|
||
| if source is None: | ||
| return None | ||
|
|
||
| return source.split(delimiter) | ||
|
|
||
| @staticmethod | ||
| def sub(value: List[Any], template: Dict[str, Any]) -> Optional[str]: | ||
| """ | ||
| Substitutes intrinsic functions and environment variables in the given value. | ||
|
|
||
| Parameters | ||
| ---------- | ||
| value : List[Any] | ||
| A list containing the string to perform substitutions on and a dictionary | ||
| containing variable names and their corresponding values. | ||
| template : Dict[str, Any] | ||
| A dictionary representing the CloudFormation template. | ||
|
|
||
| Returns | ||
| ------- | ||
| Optional[str] | ||
| The resulting string after performing substitutions, or None if any of the | ||
| variables or intrinsic functions could not be resolved. | ||
| """ | ||
|
|
||
| pseudo_parameters = [ | ||
| "AWS::AccountId", | ||
| "AWS::NotificationARNs", | ||
| "AWS::NoValue", | ||
| "AWS::Partition", | ||
| "AWS::Region", | ||
| "AWS::StackId", | ||
| "AWS::StackName", | ||
| "AWS::URLSuffix", | ||
| ] | ||
|
|
||
| pattern = r"\${(.*?)}" | ||
|
|
||
| def replace(string: str, matches: List[Any]): | ||
| matches = [ | ||
| param if param not in pseudo_parameters else param.replace("::", "_") | ||
| for param in matches | ||
| ] | ||
|
|
||
| for match in matches: | ||
| if match in os.environ: | ||
| env_var = os.environ[match] | ||
| return string.replace(f"${{{match}}}", env_var) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Dessa maneira o código não vai sempre retornar após encontrar o primeiro match no ambiente?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Corrigido! |
||
| else: | ||
| return None | ||
|
|
||
| if isinstance(value, list): | ||
| string, var_list = value | ||
|
|
||
| for var_dict in var_list: | ||
| var_name, var_value = list(var_dict.items())[0] | ||
|
|
||
| if isinstance(var_name, dict): | ||
| var_name = IntrinsicFunctions.eval(var_name, template) | ||
|
|
||
| if var_name is None: | ||
| return None | ||
|
|
||
| if isinstance(var_value, dict): | ||
| var_value = IntrinsicFunctions.eval(var_value, template) | ||
|
|
||
| if var_value is None: | ||
| return None | ||
|
|
||
| if var_name in string: | ||
| result = string.replace(f"${{{var_name}}}", str(var_value)) | ||
| else: | ||
| return None | ||
|
|
||
| matches = re.findall(pattern, result) | ||
|
|
||
| if not matches: | ||
| return result | ||
|
|
||
| return replace(result, matches) | ||
| else: | ||
| matches = re.findall(pattern, value) | ||
|
|
||
| return replace(value, matches) | ||
This file contains hidden or 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 hidden or 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 hidden or 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
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Acho que vale a pena tirar essa função daqui e adicionar um teste unitário, se alguém alterar ela e adicionar um bug pode passar despercebido já que ela é testado só pela função acima dela.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Corrigido!