Skip to content
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

Allow the characters _:./+-@= to be used in tag keys during deploy #1798

Merged
merged 6 commits into from
Feb 18, 2020

Conversation

sriram-mv
Copy link
Contributor

Copied from #1727

Why is this change necessary?

Using the aws cloudformation deploy --tags command, you are allowed to use these characters in the tag keys. Documentation also lists these characters as supported and allowed. With sam deploy --tags, it did not work properly due to a regex limiting supported characters to A-Za-z0-9.

How does it address the issue?
By adding a regex specifically for tag keys. By using this new regex, sam deploy --tags 'owner:name=son of anton' no longer converts the tag key to name instead of owner:name.
Before:

{"name": "son of anton"}

After:

{"owner:name": "son of anton"}

What side effects does this change have?
None. More characters allowed in keys and fully backwards compatible.

Checklist:

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@msambol
Copy link

msambol commented Feb 18, 2020

Thanks! Just discovered this when deploying.

def _value_regex(delim):
return f'(\\"(?:\\\\.|[^\\"\\\\]+)*\\"|(?:\\\\.|[^{delim}\\"\\\\]+)+)'
def _match_regex(match, delim):
return f'(\\"(?:\\\\{match}|[^\\"\\\\]+)*\\"|(?:\\\\{match}|[^{delim}\\"\\\\]+)+)'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is one crazy to read regex... :(

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will add a docstring.

@@ -9,15 +9,47 @@
import click


def _value_regex(delim):
return f'(\\"(?:\\\\.|[^\\"\\\\]+)*\\"|(?:\\\\.|[^{delim}\\"\\\\]+)+)'
def _match_regex(match, delim):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you throw a quick doc string on this? Finding it slightly hard to understand what/why you would need the match here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do


def _unquote(value):
r"""
Removes wrapping double quotes and any '\ ' characters. They are usually added to preserve spaces when passing
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You say "They are usually added". So does that mean there is a case that we wouldn't want to replace the double or '\ ' characters from the input?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I dont think so, we will want to replace it. "Usually added" maybe a misnomer, preserving spaces inside quotes or even escaping quotes within quotes requires a \ (escape) character.

"""
if value and (value[0] == value[-1] == '"'):
# Remove quotes only if the string is wrapped in quotes
value = value.strip('"')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The intention here is to only remove the first and last quotes right? Do we need to worry about the case where there are two " in the beginning or end of the string input?

Below was run in Python3.8

>>> value = '"a\""'
>>> value.strip('"')
'a'
>>> value = '""a""'
>>> value.strip('"')
'a'

Doing a slice might be better here:

>>> value = '"a\""'
>>> value[1:-1]
'a"'
>>> value = '""a""'
>>> value[1:-1]
'"a"'

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This only cares about wrapping quotes and not the entire nesting, can change the function name to reflect that.

# Use this regex when you have space as delimiter Ex: "KeyName1=string KeyName2=string"
VALUE_REGEX_SPACE_DELIM = _value_regex(" ")
VALUE_REGEX_SPACE_DELIM = _generate_match_regex(match_pattern=".", delim=" ")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are two different values here: one for tags and one for parameter overrides. Can we update these names to make them read better.

Also, should this and VALUE_REGEX_COMMA_DELIM be moved to CfnParameterOverridesType instead of the global scope?

RobReus and others added 6 commits February 18, 2020 15:21
Why is this change necessary?

* Tag keys and values need to allow characters as shown on https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Using_Tags.html

How does it address the issue?

* Adds appropriate regex with unit tests.

What side effects does this change have?

* None, tag keys and values are escaped which is good, cloudformation
rejects them anyways.
@sriram-mv sriram-mv merged commit 1c4bf97 into aws:develop Feb 18, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants