Skip to content

Commit b0782f8

Browse files
authored
Relax E3041 to support AWS::Route53::RecordSet resources that specify DNS root records (#3376) (#3377)
1 parent 7008855 commit b0782f8

File tree

3 files changed

+19
-14
lines changed

3 files changed

+19
-14
lines changed

docs/rules.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ The following **208** rules are applied by this linter:
137137
| [E3038<a name="E3038"></a>](../src/cfnlint/rules/resources/ServerlessTransform.py) | Check if Serverless Resources have Serverless Transform | Check that a template with Serverless Resources also includes the Serverless Transform | | [Source](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/transform-aws-serverless.html) | `resources`,`transform` |
138138
| [E3039<a name="E3039"></a>](../src/cfnlint/rules/resources/dynamodb/AttributeMismatch.py) | AttributeDefinitions / KeySchemas mismatch | Verify the set of Attributes in AttributeDefinitions and KeySchemas match | | [Source](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-dynamodb-table.html) | `resources`,`dynamodb` |
139139
| [E3040<a name="E3040"></a>](../src/cfnlint/rules/resources/properties/ReadOnly.py) | Validate we aren't configuring read only properties | Read only properties can be configured in a CloudFormation template but they aren't sent to the resource provider code and can cause drift. | | [Source](https://docs.aws.amazon.com/cloudformation-cli/latest/userguide/resource-type-schema.html#schema-properties-readonlyproperties) | `resources`,`properties` |
140-
| [E3041<a name="E3041"></a>](../src/cfnlint/rules/resources/route53/RecordSetName.py) | RecordSet HostedZoneName is a superdomain of Name | In a RecordSet, the HostedZoneName must be a superdomain of the Name being validated | | [Source](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53-recordset.html#cfn-route53-recordset-name) | `resource`,`properties`,`route53` |
140+
| [E3041<a name="E3041"></a>](../src/cfnlint/rules/resources/route53/RecordSetName.py) | RecordSet HostedZoneName is a superdomain of or equal to Name | In a RecordSet, the HostedZoneName must be a superdomain of or equal to the Name being validated | | [Source](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53-recordset.html#cfn-route53-recordset-name) | `resource`,`properties`,`route53` |
141141
| [E3042<a name="E3042"></a>](../src/cfnlint/rules/resources/ecs/TaskDefinitionEssentialContainer.py) | Validate at least one essential container is specified | Check that every TaskDefinition specifies at least one essential container | | [Source](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-taskdefinition-containerdefinitions.html#cfn-ecs-taskdefinition-containerdefinition-essential) | `properties`,`ecs`,`task`,`container`,`fargate` |
142142
| [E3043<a name="E3043"></a>](../src/cfnlint/rules/resources/cloudformation/NestedStackParameters.py) | Validate parameters for in a nested stack | Evalute if parameters for a nested stack are specified and if parameters are specified for a nested stack that aren't required. | | [Source](https://github.com/awslabs/cfn-python-lint) | `resources`,`cloudformation` |
143143
| [E3044<a name="E3044"></a>](../src/cfnlint/rules/resources/ecs/FargateDeploymentSchedulingStrategy.py) | ECS service using FARGATE or EXTERNAL can only use SchedulingStrategy of REPLICA | When using a TargetType of Fargate or External the SchedulingStrategy has to be Replica | | [Source](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-service.html#cfn-ecs-service-schedulingstrategy) | `properties`,`ecs`,`service`,`container`,`fargate` |

src/cfnlint/rules/resources/route53/RecordSetName.py

+9-11
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@ class RecordSetName(CfnLintKeyword):
1616
"""Check if a Route53 Resoruce Records Name is valid with a HostedZoneName"""
1717

1818
id = "E3041"
19-
shortdesc = "RecordSet HostedZoneName is a superdomain of Name"
19+
shortdesc = "RecordSet HostedZoneName is a superdomain of or equal to Name"
2020
description = (
21-
"In a RecordSet, the HostedZoneName must be a superdomain of the Name being"
22-
" validated"
21+
"In a RecordSet, the HostedZoneName must be a superdomain of or equal to"
22+
" the Name being validated"
2323
)
2424
source_url = "https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-route53-recordset.html#cfn-route53-recordset-name"
2525
tags = ["resource", "properties", "route53"]
@@ -39,24 +39,22 @@ def validate(
3939
name = props.get("Name", None)
4040
hz_name = props.get("HostedZoneName", None)
4141
if isinstance(name, str) and isinstance(hz_name, str):
42-
if hz_name[-1] != ".":
42+
if not hz_name.endswith("."):
4343
yield ValidationError(
4444
f"{hz_name!r} must end in a dot",
4545
path=deque(["HostedZoneName"]),
4646
instance=props.get("HostedZoneName"),
4747
)
48+
hz_name = f"{hz_name}."
4849

49-
if hz_name[-1] == ".":
50-
hz_name = hz_name[:-1]
51-
hz_name = f".{hz_name}"
52-
if name[-1] == ".":
53-
name = name[:-1]
50+
if not name.endswith("."):
51+
name = f"{name}."
5452

55-
if hz_name not in [name, name[-len(hz_name) :]]:
53+
if name != hz_name and not name.endswith(f".{hz_name}"):
5654
yield ValidationError(
5755
(
5856
f"{props.get('Name')!r} must be a subdomain "
59-
f"of {props.get('HostedZoneName')!r}"
57+
f"of or equal to {props.get('HostedZoneName')!r}"
6058
),
6159
path=deque(["Name"]),
6260
instance=props.get("Name"),

test/unit/rules/resources/route53/test_recordset_name.py

+9-2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@ def rule():
2727
},
2828
[],
2929
),
30+
(
31+
{
32+
"HostedZoneName": "bar.",
33+
"Name": "bar",
34+
},
35+
[],
36+
),
3037
(
3138
{
3239
"HostedZoneName": "bar.",
@@ -60,7 +67,7 @@ def rule():
6067
},
6168
[
6269
ValidationError(
63-
"'bar.foo.' must be a subdomain of 'bar.'",
70+
"'bar.foo.' must be a subdomain of or equal to 'bar.'",
6471
path=deque(["Name"]),
6572
)
6673
],
@@ -72,7 +79,7 @@ def rule():
7279
},
7380
[
7481
ValidationError(
75-
"'foobar.' must be a subdomain of 'bar.'",
82+
"'foobar.' must be a subdomain of or equal to 'bar.'",
7683
path=deque(["Name"]),
7784
)
7885
],

0 commit comments

Comments
 (0)