cfndsl 1.3.1 → 1.3.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -72,12 +72,19 @@ module CfnDsl
72
72
  resource_name = name.gsub(/::/, '_')
73
73
  type_module.const_set(resource_name, resource)
74
74
  info['Properties'].each_pair do |pname, ptype|
75
+ # handle bogus List defined as Type
76
+ unless ptype.is_a?(Array)
77
+ pclass = type_module.const_get ptype
78
+ if pclass.is_a?(Array)
79
+ ptype = pclass
80
+ else
81
+ create_property_def(resource, pname, pclass)
82
+ end
83
+ end
84
+
75
85
  if ptype.is_a? Array
76
86
  pclass = type_module.const_get ptype.first
77
87
  create_array_property_def(resource, pname, pclass, info)
78
- else
79
- pclass = type_module.const_get ptype
80
- create_property_def(resource, pname, pclass)
81
88
  end
82
89
  end
83
90
  resource_name
data/lib/cfndsl/types.rb CHANGED
@@ -9,6 +9,18 @@ module CfnDsl
9
9
  # Types helper
10
10
  # rubocop:disable Metrics/ModuleLength
11
11
  module Types
12
+ def self.extract_list_type(root_name, property_info)
13
+ # Tag is a reused type, but not quite primitive
14
+ # and not all resources use the general form
15
+ if property_info['ItemType'] == 'Tag'
16
+ ['Tag']
17
+ elsif (property_info['ItemType'] == 'Json') && (property_info['Type'] == 'List')
18
+ ['Json']
19
+ else
20
+ Array(root_name + property_info['ItemType'])
21
+ end
22
+ end
23
+
12
24
  def self.extract_from_resource_spec(fail_patches: false)
13
25
  spec = Specification.load_file(fail_patches: fail_patches)
14
26
  resources = extract_resources spec.resources
@@ -16,36 +28,33 @@ module CfnDsl
16
28
  { 'Resources' => resources, 'Types' => types, 'Version' => spec.version, 'File' => spec.file }
17
29
  end
18
30
 
19
- # rubocop:disable Metrics/AbcSize, Metrics/MethodLength, Metrics/CyclomaticComplexity
31
+ # rubocop:disable Metrics/CyclomaticComplexity, Metrics/MethodLength, Metrics/AbcSize
20
32
  def self.extract_resources(spec)
21
33
  spec.each_with_object({}) do |(resource_name, resource_info), resources|
22
34
  properties = resource_info['Properties'].each_with_object({}) do |(property_name, property_info), extracted|
23
35
  # some json incorrectly labelled as Type -> Json instead of PrimitiveType
24
36
  # also, AWS now has the concept of Map which cfndsl had never defined
25
- if property_info['Type'] == 'Map' || property_info['Type'] == 'Json'
26
- property_type = 'Json'
27
- elsif property_info['PrimitiveType']
28
- property_type = property_info['PrimitiveType']
29
- elsif property_info['PrimitiveItemType']
30
- property_type = Array(property_info['PrimitiveItemType'])
31
- elsif property_info['PrimitiveTypes']
32
- property_type = property_info['PrimitiveTypes'][0]
33
- elsif property_info['ItemType']
34
- # Tag is a reused type, but not quite primitive
35
- # and not all resources use the general form
36
- property_type = if property_info['ItemType'] == 'Tag'
37
- ['Tag']
38
- else
39
- Array(resource_name.split('::').join + property_info['ItemType'])
40
- end
41
- elsif property_info['Type']
42
- # Special types (defined below) are joined with their parent
43
- # resource name for uniqueness and connection
44
- property_type = resource_name.split('::').join + property_info['Type']
45
- else
46
- warn "could not extract resource type for property #{property_name} from #{resource_name}, assuming Json"
47
- property_type = 'Json'
48
- end
37
+ property_type =
38
+ if property_info['Type'] == 'Map' || property_info['Type'] == 'Json'
39
+ 'Json'
40
+ elsif property_info['PrimitiveType']
41
+ property_info['PrimitiveType']
42
+ elsif property_info['PrimitiveItemType']
43
+ Array(property_info['PrimitiveItemType'])
44
+ elsif property_info['PrimitiveTypes']
45
+ property_info['PrimitiveTypes'][0]
46
+ elsif property_info['ItemType'] == 'List'
47
+ 'List'
48
+ elsif property_info['ItemType']
49
+ extract_list_type(resource_name.split('::').join, property_info)
50
+ elsif property_info['Type']
51
+ # Special types (defined below) are joined with their parent
52
+ # resource name for uniqueness and connection
53
+ resource_name.split('::').join + property_info['Type']
54
+ else
55
+ warn "could not extract resource type for property #{property_name} from #{resource_name}, assuming Json"
56
+ 'Json'
57
+ end
49
58
  extracted[property_name] = property_type
50
59
  extracted
51
60
  end
@@ -53,9 +62,8 @@ module CfnDsl
53
62
  resources
54
63
  end
55
64
  end
56
- # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
57
65
 
58
- # rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity, Metrics/MethodLength
66
+ # rubocop:disable Metrics/PerceivedComplexity
59
67
  def self.extract_types(spec)
60
68
  primitive_types = {
61
69
  'String' => 'String',
@@ -67,7 +75,8 @@ module CfnDsl
67
75
  'Double' => 'Double',
68
76
  'Timestamp' => 'Timestamp',
69
77
  'Map' => 'Map',
70
- 'Long' => 'Long'
78
+ 'Long' => 'Long',
79
+ 'List' => 'List'
71
80
  }
72
81
  spec.each_with_object(primitive_types) do |(property_name, property_info), types|
73
82
  # In order to name things uniquely and allow for connections
@@ -77,46 +86,43 @@ module CfnDsl
77
86
  root_resource_name = root_resource ? root_resource[1].gsub(/::/, '') : property_name
78
87
  property_name = property_name.gsub(/::|\./, '')
79
88
 
80
- if property_info.key?('PrimitiveType')
81
- properties = property_info['PrimitiveType']
82
- elsif property_info.key?('Type')
83
- properties = property_info['Type']
84
- elsif property_info.key?('Properties')
85
- properties = property_info['Properties'].each_with_object({}) do |(nested_prop_name, nested_prop_info), extracted|
86
- if nested_prop_info['Type'] == 'Map' || nested_prop_info['Type'] == 'Json'
87
- # The Map type and the incorrectly labelled Json type
88
- nested_prop_type = 'Json'
89
- elsif nested_prop_info['PrimitiveType']
90
- nested_prop_type = nested_prop_info['PrimitiveType']
91
- elsif nested_prop_info['PrimitiveItemType']
92
- nested_prop_type = Array(nested_prop_info['PrimitiveItemType'])
93
- elsif nested_prop_info['PrimitiveItemTypes']
94
- nested_prop_type = Array(nested_prop_info['PrimitiveItemTypes'])
95
- elsif nested_prop_info['Types']
96
- nested_prop_type = Array(nested_prop_info['Types'])
97
- elsif nested_prop_info['ItemType']
98
- # Tag is a reused type, but not quite primitive
99
- # and not all resources use the general form
89
+ properties =
90
+ if property_info.key?('PrimitiveType')
91
+ property_info['PrimitiveType']
92
+ elsif property_info.key?('ItemType')
93
+ extract_list_type(root_resource_name, property_info)
94
+ elsif property_info.key?('Type')
95
+ property_info['Type']
96
+ elsif property_info.key?('Properties')
97
+ property_info['Properties'].each_with_object({}) do |(nested_prop_name, nested_prop_info), extracted|
100
98
  nested_prop_type =
101
- if nested_prop_info['ItemType'] == 'Tag'
102
- ['Tag']
103
- elsif (nested_prop_info['ItemType'] == 'Json') && (nested_prop_info['Type'] == 'List')
104
- ['Json']
99
+ if nested_prop_info['Type'] == 'Map' || nested_prop_info['Type'] == 'Json'
100
+ # The Map type and the incorrectly labelled Json type
101
+ 'Json'
102
+ elsif nested_prop_info['PrimitiveType']
103
+ nested_prop_info['PrimitiveType']
104
+ elsif nested_prop_info['PrimitiveItemType']
105
+ Array(nested_prop_info['PrimitiveItemType'])
106
+ elsif nested_prop_info['PrimitiveItemTypes']
107
+ Array(nested_prop_info['PrimitiveItemTypes'])
108
+ elsif nested_prop_info['Types']
109
+ Array(nested_prop_info['Types'])
110
+ elsif nested_prop_info['ItemType']
111
+ extract_list_type(root_resource_name, nested_prop_info)
112
+ elsif nested_prop_info['Type']
113
+ root_resource_name + nested_prop_info['Type']
105
114
  else
106
- Array(root_resource_name + nested_prop_info['ItemType'])
115
+ warn "could not extract property type for #{nested_prop_name} from #{property_name}, assuming Json"
116
+ p nested_prop_info
117
+ 'Json'
107
118
  end
108
-
109
- elsif nested_prop_info['Type']
110
- nested_prop_type = root_resource_name + nested_prop_info['Type']
111
- else
112
- warn "could not extract property type for #{nested_prop_name} from #{property_name}, assuming Json"
113
- nested_prop_type = 'Json'
114
- p nested_prop_info
119
+ extracted[nested_prop_name] = nested_prop_type
120
+ extracted
115
121
  end
116
- extracted[nested_prop_name] = nested_prop_type
117
- extracted
122
+ else
123
+ # No Type information typically just a plain JSON object
124
+ 'Json'
118
125
  end
119
- end
120
126
  types[property_name] = properties
121
127
  types
122
128
  end
@@ -156,27 +162,33 @@ module CfnDsl
156
162
  classes = {}
157
163
 
158
164
  # Go through and declare all of the types first
159
- types_list['Types'].each_key do |typename|
160
- if !type_def.const_defined?(typename)
161
- klass = type_def.const_set(typename, Class.new(type_def::Type))
162
- classes[typename] = klass
163
- else
164
- classes[typename] = type_def.const_get(typename)
165
+ types_list['Types'].each_pair do |typename, type_val|
166
+ unless type_def.const_defined?(typename)
167
+ if type_val.is_a?(Array)
168
+ type_def.const_set(typename, type_val)
169
+ else
170
+ classes[typename] = type_def.const_set(typename, Class.new(type_def::Type))
171
+ end
165
172
  end
166
173
  end
167
174
 
168
175
  # Now go through them again and define attribute setter methods
169
- classes.each_pair do |typename, type|
176
+ classes.each_pair do |typename, klass|
170
177
  typeval = types_list['Types'][typename]
171
178
  next unless typeval.respond_to?(:each_pair)
172
179
 
173
180
  typeval.each_pair do |attr_name, attr_type|
174
181
  attr_method = attr_name
175
182
  variable = "@#{attr_name}".to_sym
176
- klass = nil
183
+
184
+ # handle bogus List defined as Type
185
+ unless attr_type.is_a?(Array)
186
+ attr_class = type_def.const_get(attr_type)
187
+ attr_type = attr_class if attr_class.is_a?(Array)
188
+ end
177
189
 
178
190
  if attr_type.is_a?(Array)
179
- klass = type_def.const_get(attr_type[0])
191
+ attr_class = type_def.const_get(attr_type[0])
180
192
  singular_method = CfnDsl::Plurals.singularize(attr_name)
181
193
 
182
194
  if singular_method == attr_name
@@ -184,16 +196,14 @@ module CfnDsl
184
196
  attr_method = CfnDsl::Plurals.pluralize(attr_name)
185
197
  end
186
198
 
187
- define_array_method(klass, singular_method, type, variable) if singular_method != attr_method
188
-
189
- else
190
- klass = type_def.const_get(attr_type)
199
+ define_array_method(attr_class, singular_method, klass, variable) if singular_method != attr_method
191
200
  end
192
201
 
193
- type.class_eval do
202
+ klass.class_eval do
194
203
  CfnDsl.method_names(attr_method) do |inner_method|
195
204
  define_method(inner_method) do |value = nil, *_rest, &block|
196
- value ||= klass.new
205
+ # noinspection RubyScope
206
+ value ||= attr_class.new
197
207
  instance_variable_set(variable, value)
198
208
  value.instance_eval(&block) if block
199
209
  value
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CfnDsl
4
- VERSION = '1.3.1'
4
+ VERSION = '1.3.4'
5
5
  end
@@ -9,7 +9,7 @@ CloudFormation do
9
9
  QueueName 'ConfigServiceQueue'
10
10
  end
11
11
 
12
- Bucket('ConfigServiceBucket') do
12
+ S3_Bucket('ConfigServiceBucket') do
13
13
  end
14
14
 
15
15
  IAM_Policy('ConfigServiceS3BucketAccessPolicy') do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cfndsl
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.1
4
+ version: 1.3.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steven Jack
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: exe
13
13
  cert_chain: []
14
- date: 2021-01-23 00:00:00.000000000 Z
14
+ date: 2022-05-16 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: bundler
@@ -83,7 +83,6 @@ files:
83
83
  - lib/cfndsl/aws/patches/520_ServiceDiscovery_InstanceAttributes_patch.json
84
84
  - lib/cfndsl/aws/patches/600_RefKinds_patch.json
85
85
  - lib/cfndsl/aws/patches/700_SAM_Serverless_Function_InlineCode_patch.json
86
- - lib/cfndsl/aws/patches/800_List_types_patch.json
87
86
  - lib/cfndsl/aws/patches/900_SageMakerTags_patch.json
88
87
  - lib/cfndsl/aws/resource_specification.json
89
88
  - lib/cfndsl/aws/types.rb
@@ -186,7 +185,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
186
185
  requirements:
187
186
  - - ">="
188
187
  - !ruby/object:Gem::Version
189
- version: '2.7'
188
+ version: '2.6'
190
189
  required_rubygems_version: !ruby/object:Gem::Requirement
191
190
  requirements:
192
191
  - - ">="
@@ -1,115 +0,0 @@
1
- {
2
- "broken" : "6.3.0",
3
- "ResourceTypes": {
4
- "AWS::AppSync::GraphQLApi": {
5
- "patch": {
6
- "operations": [
7
- {
8
- "op": "replace",
9
- "path": "/Properties/Tags",
10
- "value": {
11
- "Type": "List",
12
- "ItemType": "Tag",
13
- "Required": false,
14
- "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-appsync-graphqlapi.html#cfn-appsync-graphqlapi-tags",
15
- "UpdateType": "Mutable"
16
- }
17
- },
18
- {
19
- "op": "replace",
20
- "path": "/Properties/AdditionalAuthenticationProviders",
21
- "value": {
22
- "Type": "List",
23
- "Required": false,
24
- "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-appsync-graphqlapi-additionalauthenticationproviders.html",
25
- "ItemType": "AdditionalAuthenticationProvider",
26
- "UpdateType": "Mutable"
27
- }
28
- }
29
- ],
30
- "description": "Fix GraphQLApi to be List of Tag"
31
- }
32
- },
33
- "AWS::LakeFormation::DataLakeSettings": {
34
- "patch": {
35
- "operations": [
36
- {
37
- "op": "replace",
38
- "path": "/Properties/Admins",
39
- "value": {
40
- "Type": "List",
41
- "Required": false,
42
- "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-lakeformation-datalakesettings-admins.html",
43
- "ItemType": "DataLakePrincipal",
44
- "UpdateType": "Mutable"
45
- }
46
- }
47
- ],
48
- "description": "Fix GraphQLApi to be List of Tag"
49
- }
50
- }
51
- },
52
- "PropertyTypes": {
53
- "AWS::CodeBuild::Project.ProjectTriggers": {
54
- "patch": {
55
- "operations": [
56
- {
57
- "op": "replace",
58
- "path": "/Properties/FilterGroups",
59
- "value": {
60
- "Type": "List",
61
- "Required": false,
62
- "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-codebuild-project-filtergroup.html",
63
- "ItemType": "WebhookFilter",
64
- "UpdateType": "Mutable"
65
- }
66
- }
67
- ],
68
- "description": "Fix FilterGroups to be List of WebhookFilter"
69
- }
70
- },
71
- "AWS::Glue::SecurityConfiguration.EncryptionConfiguration": {
72
- "patch": {
73
- "operations": [
74
- {
75
- "op": "replace",
76
- "path": "/Properties/S3Encryptions",
77
- "value": {
78
- "Type": "List",
79
- "Required": false,
80
- "Documentation": "http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-glue-securityconfiguration-s3encryptions.html",
81
- "ItemType": "S3Encryption",
82
- "UpdateType": "Mutable"
83
- }
84
- }
85
- ],
86
- "description": "Fix S3Encryptions to be List of S3Encryption"
87
- }
88
- },
89
- "patch": {
90
- "operations": [
91
- {
92
- "op": "remove",
93
- "path": "/AWS::AppSync::GraphQLApi.Tags"
94
- },
95
- {
96
- "op": "remove",
97
- "path": "/AWS::CodeBuild::Project.FilterGroup"
98
- },
99
- {
100
- "op": "remove",
101
- "path": "/AWS::LakeFormation::DataLakeSettings.Admins"
102
- },
103
- {
104
- "op": "remove",
105
- "path": "/AWS::AppSync::GraphQLApi.AdditionalAuthenticationProviders"
106
- },
107
- {
108
- "op": "remove",
109
- "path": "/AWS::Glue::SecurityConfiguration.S3Encryptions"
110
- }
111
- ],
112
- "description": "Remove bogus List Types"
113
- }
114
- }
115
- }