Module: CfnDsl::Specification
- Defined in:
- lib/cfndsl/specification.rb
Overview
Helper module for bridging the gap between a static types file included in the repo and dynamically generating the types directly from the AWS specification
Class Method Summary collapse
-
.determine_spec_file ⇒ Object
rubocop:enable Metrics/MethodLength, Metrics/AbcSize, Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity.
- .extract_from_resource_spec! ⇒ Object
-
.extract_resources(spec) ⇒ Object
rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity.
-
.extract_types(spec) ⇒ Object
rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity.
Class Method Details
.determine_spec_file ⇒ Object
rubocop:enable Metrics/MethodLength, Metrics/AbcSize, Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
94 95 96 97 98 |
# File 'lib/cfndsl/specification.rb', line 94 def self.determine_spec_file return CfnDsl.specification_file if File.exist? CfnDsl.specification_file File.('aws/resource_specification.json', __dir__) end |
.extract_from_resource_spec! ⇒ Object
100 101 102 103 104 105 |
# File 'lib/cfndsl/specification.rb', line 100 def self.extract_from_resource_spec! spec_file = JSON.parse File.read(determine_spec_file) resources = extract_resources spec_file['ResourceTypes'].merge(Patches.resources) types = extract_types spec_file['PropertyTypes'].merge(Patches.types) { 'Resources' => resources, 'Types' => types } end |
.extract_resources(spec) ⇒ Object
rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/cfndsl/specification.rb', line 8 def self.extract_resources(spec) spec.each_with_object({}) do |(resource_name, resource_info), resources| properties = resource_info['Properties'].each_with_object({}) do |(property_name, property_info), extracted| # some json incorrectly labelled as Type -> Json instead of PrimitiveType # also, AWS now has the concept of Map which cfndsl had never defined if property_info['Type'] == 'Map' || property_info['Type'] == 'Json' property_type = 'Json' elsif property_info['PrimitiveType'] property_type = property_info['PrimitiveType'] elsif property_info['PrimitiveItemType'] property_type = Array(property_info['PrimitiveItemType']) elsif property_info['ItemType'] # Tag is a reused type, but not quite primitive # and not all resources use the general form property_type = if property_info['ItemType'] == 'Tag' ['Tag'] else Array(resource_name.split('::').join + property_info['ItemType']) end elsif property_info['Type'] # Special types (defined below) are joined with their parent # resource name for uniqueness and connection property_type = resource_name.split('::').join + property_info['Type'] else warn "could not extract type from #{resource_name}" end extracted[property_name] = property_type extracted end resources[resource_name] = { 'Properties' => properties } resources end end |
.extract_types(spec) ⇒ Object
rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/cfndsl/specification.rb', line 44 def self.extract_types(spec) primitive_types = { 'String' => 'String', 'Boolean' => 'Boolean', 'Json' => 'Json', 'Integer' => 'Integer', 'Number' => 'Number', 'Double' => 'Double', 'Timestamp' => 'Timestamp', 'Map' => 'Map', 'Long' => 'Long' } spec.each_with_object(primitive_types) do |(property_name, property_info), types| # In order to name things uniquely and allow for connections # we extract the resource name from the property # AWS::IAM::User.Policy becomes AWSIAMUserPolicy root_resource = property_name.match(/(.*)\./) root_resource_name = root_resource ? root_resource[1].gsub(/::/, '') : property_name property_name = property_name.gsub(/::|\./, '') if property_info.key?('PrimitiveType') properties = property_info['PrimitiveType'] elsif property_info.key?('Type') properties = property_info['Type'] elsif property_info.key?('Properties') properties = property_info['Properties'].each_with_object({}) do |(nested_prop_name, nested_prop_info), extracted| if nested_prop_info['Type'] == 'Map' || nested_prop_info['Type'] == 'Json' # The Map type and the incorrectly labelled Json type nested_prop_type = 'Json' elsif nested_prop_info['PrimitiveType'] nested_prop_type = nested_prop_info['PrimitiveType'] elsif nested_prop_info['PrimitiveItemType'] nested_prop_type = Array(nested_prop_info['PrimitiveItemType']) elsif nested_prop_info['ItemType'] nested_prop_type = Array(root_resource_name + nested_prop_info['ItemType']) elsif nested_prop_info['Type'] nested_prop_type = root_resource_name + nested_prop_info['Type'] else warn "could not extract type from #{property_name}" end extracted[nested_prop_name] = nested_prop_type extracted end end types[property_name] = properties types end end |