cfndsl 1.3.2 → 1.3.3

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,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
- }