Skip to content

Commit

Permalink
Handle CFN template values being represented as symbols (#100)
Browse files Browse the repository at this point in the history
Psych will interpret unquoted YAML values starting with a ':' character
as a Ruby symbol.

Avoid raising an error in this scenario, add Symbol to the list of
permitted classes when loading CloudFormation YAML templates.
  • Loading branch information
orien committed Jun 23, 2022
1 parent 674e223 commit 0232e66
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 3 deletions.
2 changes: 1 addition & 1 deletion lib/cfn-model/parser/cfn_parser.rb
Expand Up @@ -65,7 +65,7 @@ def parse_without_parameters(cloudformation_yml, with_line_numbers=false, condit
if with_line_numbers
parse_with_line_numbers(cloudformation_yml)
else
YAML.safe_load cloudformation_yml, permitted_classes: [Date]
YAML.safe_load cloudformation_yml, permitted_classes: [Date, Symbol]
end

# Transform raw resources in template as performed by
Expand Down
2 changes: 1 addition & 1 deletion lib/cfn-model/validator/cloudformation_validator.rb
Expand Up @@ -12,7 +12,7 @@ def validate(cloudformation_string)

schema = SchemaGenerator.new.generate cloudformation_string
validator = Kwalify::Validator.new(schema)
validator.validate(YAML.safe_load(cloudformation_string, permitted_classes: [Date]))
validator.validate(YAML.safe_load(cloudformation_string, permitted_classes: [Date, Symbol]))
rescue ArgumentError, IOError, NameError => e
raise ParserError, e.inspect
end
Expand Down
2 changes: 1 addition & 1 deletion lib/cfn-model/validator/resource_type_validator.rb
Expand Up @@ -5,7 +5,7 @@
class ResourceTypeValidator

def self.validate(cloudformation_yml)
hash = YAML.safe_load cloudformation_yml, permitted_classes: [Date]
hash = YAML.safe_load cloudformation_yml, permitted_classes: [Date, Symbol]
if hash == false || hash.nil?
raise ParserError.new 'yml empty'
end
Expand Down
3 changes: 3 additions & 0 deletions spec/parser/cfn_parser_spec.rb
Expand Up @@ -271,6 +271,9 @@
Type: String
NoEcho: true
Default: none
TestIPV6:
Type: String
Default: ::/0
Conditions:
IsNone: !Or
- !Equals
Expand Down
18 changes: 18 additions & 0 deletions spec/validator/cloudformation_validator_spec.rb
Expand Up @@ -176,5 +176,23 @@

expect(CloudFormationValidator.new.validate(valid_yaml)).to eq []
end

it 'does not raise an error when template is YAML with date and symbol values' do
valid_yaml = <<~TEMPLATE
---
AWSTemplateFormatVersion: 2010-09-09
Resources:
SecurityGroupIngress:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: sg-12341234
CidrIpv6: ::/0
FromPort: 22
ToPort: 22
IpProtocol: tcp
TEMPLATE

expect(CloudFormationValidator.new.validate(valid_yaml)).to eq []
end
end
end
38 changes: 38 additions & 0 deletions spec/validator/resource_type_validator_spec.rb
Expand Up @@ -123,4 +123,42 @@
expect(actual_hash).to eq expected_hash
end
end

context 'given a template with date and symbol values' do
let(:template) { <<~TEMPLATE }
---
AWSTemplateFormatVersion: 2010-09-09
Resources:
SecurityGroupIngress:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: sg-12341234
CidrIpv6: ::/0
FromPort: 22
ToPort: 22
IpProtocol: tcp
TEMPLATE

it 'successfully returns the Hash of the parsed document' do
parsed_template = ResourceTypeValidator.validate(template)

expect(parsed_template).to eq(
{
'AWSTemplateFormatVersion' => Date.new(2010, 9, 9),
'Resources' => {
'SecurityGroupIngress' => {
'Type' => 'AWS::EC2::SecurityGroupIngress',
'Properties' => {
'GroupId' => 'sg-12341234',
'CidrIpv6' => :':/0',
'FromPort' => 22,
'ToPort' => 22,
'IpProtocol' => 'tcp'
}
}
}
}
)
end
end
end

0 comments on commit 0232e66

Please sign in to comment.