cfndsl 1.3.2 → 1.3.5

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,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.2'
4
+ VERSION = '1.3.5'
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.5
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: 2022-06-07 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: bundler
@@ -52,9 +52,9 @@ executables:
52
52
  extensions: []
53
53
  extra_rdoc_files: []
54
54
  files:
55
+ - ".github/workflows/spec.yml"
55
56
  - ".gitignore"
56
57
  - ".rubocop.yml"
57
- - ".travis.yml"
58
58
  - CHANGELOG.md
59
59
  - Gemfile
60
60
  - LICENSE
@@ -83,8 +83,8 @@ 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
87
+ - lib/cfndsl/aws/patches/901_SageMakerTags_patch.json
88
88
  - lib/cfndsl/aws/resource_specification.json
89
89
  - lib/cfndsl/aws/types.rb
90
90
  - lib/cfndsl/aws/types.yaml
@@ -193,7 +193,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
193
193
  - !ruby/object:Gem::Version
194
194
  version: '0'
195
195
  requirements: []
196
- rubygems_version: 3.0.8
196
+ rubygems_version: 3.3.7
197
197
  signing_key:
198
198
  specification_version: 4
199
199
  summary: AWS Cloudformation DSL
data/.travis.yml DELETED
@@ -1,23 +0,0 @@
1
- language: ruby
2
- rvm: # all MRI ruby versions that are not EOL
3
- - 2.7
4
- - 2.6
5
- - '3.0'
6
- sudo: false
7
- before_install:
8
- - gem update --system
9
- - gem install bundler
10
- deploy:
11
- provider: rubygems
12
- api_key:
13
- secure: cIDF27JCirxxg7SXw6R+xxABMwCrrirJiJzljVxb/MdlRyUVaSW8XdZjOVyNgJkCx+vQOX4U+hp+p0xVI/Loh4EXkgbDvu2oGIAn/g1lfWabwKtdkFEviQn4tWvqDcEkxm5Hm6Gs0pFCaurqynMPNbsLVAEIiSw+la8LxEeeQ6I=
14
- gem: cfndsl
15
- on:
16
- tags: true
17
- repo: cfndsl/cfndsl
18
- notifications:
19
- email:
20
- recipients:
21
- - gergnz@gmail.com
22
- on_failure: change
23
- on_success: never
@@ -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
- }