cfndsl 1.3.2 → 1.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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,31 @@ 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
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']
47
+ extract_list_type(resource_name.split('::').join, property_info)
48
+ elsif property_info['Type']
49
+ # Special types (defined below) are joined with their parent
50
+ # resource name for uniqueness and connection
51
+ resource_name.split('::').join + property_info['Type']
52
+ else
53
+ warn "could not extract resource type for property #{property_name} from #{resource_name}, assuming Json"
54
+ 'Json'
55
+ end
49
56
  extracted[property_name] = property_type
50
57
  extracted
51
58
  end
@@ -53,7 +60,6 @@ module CfnDsl
53
60
  resources
54
61
  end
55
62
  end
56
- # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
57
63
 
58
64
  # rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity, Metrics/MethodLength
59
65
  def self.extract_types(spec)
@@ -77,46 +83,43 @@ module CfnDsl
77
83
  root_resource_name = root_resource ? root_resource[1].gsub(/::/, '') : property_name
78
84
  property_name = property_name.gsub(/::|\./, '')
79
85
 
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
86
+ properties =
87
+ if property_info.key?('PrimitiveType')
88
+ property_info['PrimitiveType']
89
+ elsif property_info.key?('ItemType')
90
+ extract_list_type(root_resource_name, property_info)
91
+ elsif property_info.key?('Type')
92
+ property_info['Type']
93
+ elsif property_info.key?('Properties')
94
+ property_info['Properties'].each_with_object({}) do |(nested_prop_name, nested_prop_info), extracted|
100
95
  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']
96
+ if nested_prop_info['Type'] == 'Map' || nested_prop_info['Type'] == 'Json'
97
+ # The Map type and the incorrectly labelled Json type
98
+ 'Json'
99
+ elsif nested_prop_info['PrimitiveType']
100
+ nested_prop_info['PrimitiveType']
101
+ elsif nested_prop_info['PrimitiveItemType']
102
+ Array(nested_prop_info['PrimitiveItemType'])
103
+ elsif nested_prop_info['PrimitiveItemTypes']
104
+ Array(nested_prop_info['PrimitiveItemTypes'])
105
+ elsif nested_prop_info['Types']
106
+ Array(nested_prop_info['Types'])
107
+ elsif nested_prop_info['ItemType']
108
+ extract_list_type(root_resource_name, nested_prop_info)
109
+ elsif nested_prop_info['Type']
110
+ root_resource_name + nested_prop_info['Type']
105
111
  else
106
- Array(root_resource_name + nested_prop_info['ItemType'])
112
+ warn "could not extract property type for #{nested_prop_name} from #{property_name}, assuming Json"
113
+ p nested_prop_info
114
+ 'Json'
107
115
  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
116
+ extracted[nested_prop_name] = nested_prop_type
117
+ extracted
115
118
  end
116
- extracted[nested_prop_name] = nested_prop_type
117
- extracted
119
+ else
120
+ # No Type information typically just a plain JSON object
121
+ 'Json'
118
122
  end
119
- end
120
123
  types[property_name] = properties
121
124
  types
122
125
  end
@@ -156,27 +159,33 @@ module CfnDsl
156
159
  classes = {}
157
160
 
158
161
  # 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)
162
+ types_list['Types'].each_pair do |typename, type_val|
163
+ unless type_def.const_defined?(typename)
164
+ if type_val.is_a?(Array)
165
+ type_def.const_set(typename, type_val)
166
+ else
167
+ classes[typename] = type_def.const_set(typename, Class.new(type_def::Type))
168
+ end
165
169
  end
166
170
  end
167
171
 
168
172
  # Now go through them again and define attribute setter methods
169
- classes.each_pair do |typename, type|
173
+ classes.each_pair do |typename, klass|
170
174
  typeval = types_list['Types'][typename]
171
175
  next unless typeval.respond_to?(:each_pair)
172
176
 
173
177
  typeval.each_pair do |attr_name, attr_type|
174
178
  attr_method = attr_name
175
179
  variable = "@#{attr_name}".to_sym
176
- klass = nil
180
+
181
+ # handle bogus List defined as Type
182
+ unless attr_type.is_a?(Array)
183
+ attr_class = type_def.const_get(attr_type)
184
+ attr_type = attr_class if attr_class.is_a?(Array)
185
+ end
177
186
 
178
187
  if attr_type.is_a?(Array)
179
- klass = type_def.const_get(attr_type[0])
188
+ attr_class = type_def.const_get(attr_type[0])
180
189
  singular_method = CfnDsl::Plurals.singularize(attr_name)
181
190
 
182
191
  if singular_method == attr_name
@@ -184,16 +193,14 @@ module CfnDsl
184
193
  attr_method = CfnDsl::Plurals.pluralize(attr_name)
185
194
  end
186
195
 
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)
196
+ define_array_method(attr_class, singular_method, klass, variable) if singular_method != attr_method
191
197
  end
192
198
 
193
- type.class_eval do
199
+ klass.class_eval do
194
200
  CfnDsl.method_names(attr_method) do |inner_method|
195
201
  define_method(inner_method) do |value = nil, *_rest, &block|
196
- value ||= klass.new
202
+ # noinspection RubyScope
203
+ value ||= attr_class.new
197
204
  instance_variable_set(variable, value)
198
205
  value.instance_eval(&block) if block
199
206
  value
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module CfnDsl
4
- VERSION = '1.3.2'
4
+ VERSION = '1.3.3'
5
5
  end
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.2
4
+ version: 1.3.3
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-06-25 00:00:00.000000000 Z
14
+ date: 2021-07-14 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
@@ -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
- }