cfndsl 0.4.4 → 0.5.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -13
- data/.rubocop.yml +23 -0
- data/Gemfile +4 -0
- data/Rakefile +19 -17
- data/bin/cfndsl +20 -20
- data/cfndsl.gemspec +16 -15
- data/lib/cfndsl.rb +62 -68
- data/lib/cfndsl/aws/cloud_formation_template.rb +16 -0
- data/lib/cfndsl/aws/types.rb +12 -0
- data/lib/cfndsl/{aws_types.yaml → aws/types.yaml} +0 -0
- data/lib/cfndsl/{Conditions.rb → conditions.rb} +5 -7
- data/lib/cfndsl/creation_policy.rb +21 -0
- data/lib/cfndsl/errors.rb +29 -0
- data/lib/cfndsl/generate_types.rb +154 -0
- data/lib/cfndsl/jsonable.rb +214 -0
- data/lib/cfndsl/mappings.rb +23 -0
- data/lib/cfndsl/metadata.rb +16 -0
- data/lib/cfndsl/module.rb +52 -51
- data/lib/cfndsl/names.rb +5 -5
- data/lib/cfndsl/orchestration_template.rb +173 -0
- data/lib/cfndsl/os/heat_template.rb +16 -0
- data/lib/cfndsl/os/types.rb +12 -0
- data/lib/cfndsl/{os_types.yaml → os/types.yaml} +11 -11
- data/lib/cfndsl/{Outputs.rb → outputs.rb} +3 -4
- data/lib/cfndsl/{Parameters.rb → parameters.rb} +12 -13
- data/lib/cfndsl/plurals.rb +34 -0
- data/lib/cfndsl/properties.rb +21 -0
- data/lib/cfndsl/rake_task.rb +9 -7
- data/lib/cfndsl/ref_check.rb +44 -0
- data/lib/cfndsl/{Resources.rb → resources.rb} +13 -15
- data/lib/cfndsl/types.rb +151 -0
- data/lib/cfndsl/update_policy.rb +25 -0
- data/lib/cfndsl/version.rb +1 -1
- data/sample/autoscale.rb +152 -158
- data/sample/autoscale2.rb +151 -155
- data/sample/circular.rb +30 -33
- data/sample/codedeploy.rb +35 -36
- data/sample/config_service.rb +120 -0
- data/sample/ecs.rb +39 -39
- data/sample/iam_policies.rb +82 -0
- data/sample/lambda.rb +20 -24
- data/sample/s3.rb +11 -11
- data/sample/t1.rb +7 -9
- data/sample/vpc_example.rb +50 -0
- data/sample/vpc_with_vpn_example.rb +97 -0
- data/spec/cfndsl_spec.rb +22 -11
- data/spec/fixtures/heattest.rb +13 -14
- data/spec/fixtures/test.rb +56 -53
- metadata +36 -30
- data/lib/cfndsl/CloudFormationTemplate.rb +0 -267
- data/lib/cfndsl/CreationPolicy.rb +0 -25
- data/lib/cfndsl/Errors.rb +0 -31
- data/lib/cfndsl/JSONable.rb +0 -235
- data/lib/cfndsl/Mappings.rb +0 -25
- data/lib/cfndsl/Metadata.rb +0 -22
- data/lib/cfndsl/Plurals.rb +0 -35
- data/lib/cfndsl/Properties.rb +0 -25
- data/lib/cfndsl/RefCheck.rb +0 -48
- data/lib/cfndsl/Types.rb +0 -309
- data/lib/cfndsl/UpdatePolicy.rb +0 -29
- data/sample/config-service.rb +0 -119
- data/sample/iam-policies.rb +0 -82
- data/sample/vpc-example.rb +0 -51
- data/sample/vpc-with-vpn-example.rb +0 -97
@@ -1,12 +1,11 @@
|
|
1
|
-
require 'cfndsl/
|
1
|
+
require 'cfndsl/jsonable'
|
2
2
|
|
3
3
|
module CfnDsl
|
4
|
+
# Handles Output objects
|
4
5
|
class OutputDefinition < JSONable
|
5
|
-
##
|
6
|
-
# Handles Output objects
|
7
6
|
dsl_attr_setter :Value, :Description, :Condition
|
8
7
|
|
9
|
-
def initialize(
|
8
|
+
def initialize(value = nil)
|
10
9
|
@Value = value if value
|
11
10
|
end
|
12
11
|
end
|
@@ -1,32 +1,31 @@
|
|
1
|
-
require 'cfndsl/
|
1
|
+
require 'cfndsl/jsonable'
|
2
2
|
|
3
|
-
module CfnDsl
|
4
|
-
|
3
|
+
module CfnDsl
|
4
|
+
# Handles input parameter objects
|
5
5
|
class ParameterDefinition < JSONable
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
dsl_attr_setter :Type, :Default, :NoEcho, :AllowedValues, :AllowedPattern, :MaxLength,
|
7
|
+
:MinLength, :MaxValue, :MinValue, :Description, :ConstraintDescription
|
8
|
+
|
9
9
|
def initialize
|
10
10
|
@Type = :String
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
def String
|
14
14
|
@Type = :String
|
15
15
|
end
|
16
|
-
|
16
|
+
|
17
17
|
def Number
|
18
18
|
@Type = :Number
|
19
19
|
end
|
20
|
-
|
20
|
+
|
21
21
|
def CommaDelimitedList
|
22
22
|
@Type = :CommaDelimitedList
|
23
23
|
end
|
24
|
-
|
25
|
-
def to_hash
|
24
|
+
|
25
|
+
def to_hash
|
26
26
|
h = {}
|
27
|
-
h[:Type] = @Type
|
27
|
+
h[:Type] = @Type
|
28
28
|
h[:Default] = @Default if @Default
|
29
29
|
end
|
30
30
|
end
|
31
|
-
|
32
31
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module CfnDsl
|
2
|
+
# Plural names for lists of content objects
|
3
|
+
module Plurals
|
4
|
+
@plurals = {
|
5
|
+
'Metadata' => 'Metadata',
|
6
|
+
'Property' => 'Properties',
|
7
|
+
'Policy' => 'Policies',
|
8
|
+
'PolicyDocument' => 'PolicyDocument',
|
9
|
+
'AssumeRolePolicyDocument' => 'AssumeRolePolicyDocument',
|
10
|
+
'SecurityGroupIngress' => 'SecurityGroupIngress',
|
11
|
+
'SecurityGroupEgress' => 'SecurityGroupEgress',
|
12
|
+
'DBSecurityGroupIngress' => 'DBSecurityGroupIngress',
|
13
|
+
'UpdatePolicy' => 'UpdatePolicy',
|
14
|
+
'CreationPolicy' => 'CreationPolicy'
|
15
|
+
}
|
16
|
+
|
17
|
+
@singles = {}
|
18
|
+
@plurals.each_pair { |key, val| @singles[val] = key }
|
19
|
+
|
20
|
+
def self.pluralize(name)
|
21
|
+
name = name.to_s
|
22
|
+
return @plurals[name] if @plurals.key?(name)
|
23
|
+
|
24
|
+
"#{name}s"
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.singularize(name)
|
28
|
+
name = name.to_s
|
29
|
+
return @singles[name] if @singles.key?(name)
|
30
|
+
|
31
|
+
name[0..-2]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'cfndsl/jsonable'
|
2
|
+
|
3
|
+
module CfnDsl
|
4
|
+
# Handles property objects for Resources
|
5
|
+
#
|
6
|
+
# Usage
|
7
|
+
# Resource("aaa") {
|
8
|
+
# Property("propName", "propValue" )
|
9
|
+
# }
|
10
|
+
#
|
11
|
+
class PropertyDefinition < JSONable
|
12
|
+
attr_reader :value
|
13
|
+
def initialize(value)
|
14
|
+
@value = value
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_json(*a)
|
18
|
+
@value.to_json(*a)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/cfndsl/rake_task.rb
CHANGED
@@ -1,15 +1,17 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/tasklib'
|
3
|
+
|
4
|
+
require 'cfndsl'
|
4
5
|
|
5
6
|
module CfnDsl
|
7
|
+
# Rake Task
|
6
8
|
class RakeTask < Rake::TaskLib
|
7
9
|
attr_accessor :cfndsl_opts
|
8
10
|
|
9
11
|
def initialize(name = nil)
|
10
12
|
yield self if block_given?
|
11
13
|
|
12
|
-
desc
|
14
|
+
desc 'Generate Cloudformation' unless ::Rake.application.last_comment
|
13
15
|
task(name || :generate) do |_t, _args|
|
14
16
|
cfndsl_opts[:files].each do |opts|
|
15
17
|
generate(opts)
|
@@ -27,7 +29,7 @@ module CfnDsl
|
|
27
29
|
end
|
28
30
|
|
29
31
|
def log(opts)
|
30
|
-
type = opts[:output].nil? ?
|
32
|
+
type = opts[:output].nil? ? 'STDOUT' : opts[:output]
|
31
33
|
verbose.puts("Writing to #{type}") if verbose
|
32
34
|
end
|
33
35
|
|
@@ -36,7 +38,7 @@ module CfnDsl
|
|
36
38
|
end
|
37
39
|
|
38
40
|
def model(filename)
|
39
|
-
|
41
|
+
raise "#{filename} doesn't exist" unless File.exist?(filename)
|
40
42
|
verbose.puts("using extras #{extra}") if verbose
|
41
43
|
CfnDsl.eval_file_with_extras(filename, extra, verbose).to_json
|
42
44
|
end
|
@@ -50,7 +52,7 @@ module CfnDsl
|
|
50
52
|
end
|
51
53
|
|
52
54
|
def file_output(path)
|
53
|
-
File.open(File.expand_path(path),
|
55
|
+
File.open(File.expand_path(path), 'w') { |f| yield f }
|
54
56
|
end
|
55
57
|
end
|
56
58
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# This module defines some methods for walking the reference tree
|
2
|
+
# of various objects.
|
3
|
+
module RefCheck
|
4
|
+
# Build up a set of references.
|
5
|
+
def build_references(refs)
|
6
|
+
raise 'Circular reference' if @_visited
|
7
|
+
|
8
|
+
@_visited = true
|
9
|
+
|
10
|
+
if respond_to?(:all_refs)
|
11
|
+
all_refs.each do |ref|
|
12
|
+
refs[ref.to_s] = 1
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
ref_children.each do |elem|
|
17
|
+
elem.build_references(refs) if elem.respond_to?(:build_references)
|
18
|
+
end
|
19
|
+
|
20
|
+
@_visited = nil
|
21
|
+
|
22
|
+
refs
|
23
|
+
end
|
24
|
+
|
25
|
+
def ref_children
|
26
|
+
[]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# Mixin to Array
|
31
|
+
class Array
|
32
|
+
include RefCheck
|
33
|
+
def ref_children
|
34
|
+
self
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Mixin to Array
|
39
|
+
class Hash
|
40
|
+
include RefCheck
|
41
|
+
def ref_children
|
42
|
+
values
|
43
|
+
end
|
44
|
+
end
|
@@ -1,36 +1,34 @@
|
|
1
|
-
require 'cfndsl/
|
2
|
-
require 'cfndsl/
|
3
|
-
require 'cfndsl/
|
4
|
-
require 'cfndsl/
|
1
|
+
require 'cfndsl/jsonable'
|
2
|
+
require 'cfndsl/metadata'
|
3
|
+
require 'cfndsl/properties'
|
4
|
+
require 'cfndsl/update_policy'
|
5
5
|
|
6
6
|
module CfnDsl
|
7
|
+
# Handles Resource objects
|
7
8
|
class ResourceDefinition < JSONable
|
8
|
-
##
|
9
|
-
# Handles Resource objects
|
10
9
|
dsl_attr_setter :Type, :DependsOn, :DeletionPolicy, :Condition
|
11
10
|
dsl_content_object :Property, :Metadata, :UpdatePolicy, :CreationPolicy
|
12
11
|
|
13
|
-
def
|
14
|
-
|
12
|
+
def add_tag(name, value, propagate = nil)
|
13
|
+
send(:Tag) do
|
15
14
|
Key name
|
16
15
|
Value value
|
17
16
|
PropagateAtLaunch propagate unless propagate.nil?
|
18
|
-
|
17
|
+
end
|
19
18
|
end
|
20
19
|
|
21
|
-
def
|
20
|
+
def all_refs
|
22
21
|
refs = []
|
23
|
-
if @DependsOn
|
24
|
-
if
|
22
|
+
if @DependsOn
|
23
|
+
if @DependsOn.respond_to?(:each)
|
25
24
|
@DependsOn.each do |dep|
|
26
25
|
refs.push dep
|
27
26
|
end
|
28
27
|
end
|
29
28
|
|
30
|
-
if
|
31
|
-
refs.push @DependsOn
|
32
|
-
end
|
29
|
+
refs.push @DependsOn if @DependsOn.instance_of?(String)
|
33
30
|
end
|
31
|
+
|
34
32
|
refs
|
35
33
|
end
|
36
34
|
end
|
data/lib/cfndsl/types.rb
ADDED
@@ -0,0 +1,151 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'cfndsl/jsonable'
|
3
|
+
require 'cfndsl/plurals'
|
4
|
+
require 'cfndsl/names'
|
5
|
+
require 'cfndsl/types'
|
6
|
+
|
7
|
+
module CfnDsl
|
8
|
+
# rubocop:disable Metrics/ModuleLength
|
9
|
+
module Types
|
10
|
+
# rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
|
11
|
+
def self.included(type_def)
|
12
|
+
types_list = YAML.load(File.open("#{File.dirname(__FILE__)}/#{type_def::TYPE_PREFIX}/types.yaml"))
|
13
|
+
type_def.const_set('Types_Internal', types_list)
|
14
|
+
|
15
|
+
# Do a little sanity checking - all of the types referenced in Resources
|
16
|
+
# should be represented in Types
|
17
|
+
types_list['Resources'].keys.each do |resource_name|
|
18
|
+
resource = types_list['Resources'][resource_name]
|
19
|
+
resource.values.each do |thing|
|
20
|
+
thing.values.each do |type|
|
21
|
+
if type.is_a?(Array)
|
22
|
+
type.each do |inner_type|
|
23
|
+
puts "unknown type #{inner_type}" unless types_list['Types'].key?(inner_type)
|
24
|
+
end
|
25
|
+
else
|
26
|
+
puts "unknown type #{type}" unless types_list['Types'].key?(type)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# All of the type values should also be references
|
33
|
+
types_list['Types'].values do |type|
|
34
|
+
if type.respond_to?(:values)
|
35
|
+
type.values.each do |tv|
|
36
|
+
puts "unknown type #{tv}" unless types_list['Types'].key?(tv)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
classes = {}
|
42
|
+
|
43
|
+
# Go through and declare all of the types first
|
44
|
+
types_list['Types'].each_key do |typename|
|
45
|
+
if !type_def.const_defined?(typename)
|
46
|
+
klass = type_def.const_set(typename, Class.new(type_def::Type))
|
47
|
+
classes[typename] = klass
|
48
|
+
else
|
49
|
+
classes[typename] = type_def.const_get(typename)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# Now go through them again and define attribute setter methods
|
54
|
+
classes.each_pair do |typename, type|
|
55
|
+
typeval = types_list['Types'][typename]
|
56
|
+
next unless typeval.respond_to?(:each_pair)
|
57
|
+
typeval.each_pair do |attr_name, attr_type|
|
58
|
+
if attr_type.is_a?(Array)
|
59
|
+
klass = type_def.const_get(attr_type[0])
|
60
|
+
variable = "@#{attr_name}".to_sym
|
61
|
+
|
62
|
+
method = CfnDsl::Plurals.singularize(attr_name)
|
63
|
+
methods = attr_name
|
64
|
+
all_methods = CfnDsl.method_names(method) + CfnDsl.method_names(methods)
|
65
|
+
type.class_eval do
|
66
|
+
all_methods.each do |method_name|
|
67
|
+
define_method(method_name) do |value = nil, *rest, &block|
|
68
|
+
existing = instance_variable_get(variable)
|
69
|
+
# For no-op invocations, get out now
|
70
|
+
return existing if value.nil? && rest.empty? && !block
|
71
|
+
|
72
|
+
# We are going to modify the value in some
|
73
|
+
# way, make sure that we have an array to mess
|
74
|
+
# with if we start with nothing
|
75
|
+
existing = instance_variable_set(variable, []) unless existing
|
76
|
+
|
77
|
+
# special case for just a block, no args
|
78
|
+
if value.nil? && rest.empty? && block
|
79
|
+
val = klass.new
|
80
|
+
existing.push val
|
81
|
+
value.instance_eval(&block(val))
|
82
|
+
return existing
|
83
|
+
end
|
84
|
+
|
85
|
+
# Glue all of our parameters together into
|
86
|
+
# a giant array - flattening one level deep, if needed
|
87
|
+
array_params = []
|
88
|
+
if value.is_a?(Array)
|
89
|
+
value.each { |x| array_params.push x }
|
90
|
+
else
|
91
|
+
array_params.push value
|
92
|
+
end
|
93
|
+
unless rest.empty?
|
94
|
+
rest.each do |v|
|
95
|
+
if v.is_a?(Array)
|
96
|
+
array_params += rest
|
97
|
+
else
|
98
|
+
array_params.push v
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# Here, if we were given multiple arguments either
|
104
|
+
# as method [a,b,c], method(a,b,c), or even
|
105
|
+
# method( a, [b], c) we end up with
|
106
|
+
# array_params = [a,b,c]
|
107
|
+
#
|
108
|
+
# array_params will have at least one item
|
109
|
+
# unless the user did something like pass in
|
110
|
+
# a bunch of empty arrays.
|
111
|
+
if block
|
112
|
+
array_params.each do |array_params_value|
|
113
|
+
value = klass.new
|
114
|
+
existing.push value
|
115
|
+
value.instance_eval(&block(array_params_value)) if block
|
116
|
+
end
|
117
|
+
else
|
118
|
+
# List of parameters with no block -
|
119
|
+
# hope that the user knows what he is
|
120
|
+
# doing and stuff them into our existing
|
121
|
+
# array
|
122
|
+
array_params.each do |_|
|
123
|
+
existing.push value
|
124
|
+
end
|
125
|
+
end
|
126
|
+
return existing
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
else
|
131
|
+
klass = type_def.const_get(attr_type)
|
132
|
+
variable = "@#{attr_name}".to_sym
|
133
|
+
|
134
|
+
type.class_eval do
|
135
|
+
CfnDsl.method_names(attr_name) do |inner_method|
|
136
|
+
define_method(inner_method) do |value = nil, *_rest, &block|
|
137
|
+
value ||= klass.new
|
138
|
+
instance_variable_set(variable, value)
|
139
|
+
value.instance_eval(&block) if block
|
140
|
+
value
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
# rubocop:enable Metrics/MethodLength, Metrics/AbcSize, Metrics/PerceivedComplexity, Metrics/CyclomaticComplexity
|
149
|
+
end
|
150
|
+
# rubocop:enable Metrics/ModuleLength
|
151
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'cfndsl/jsonable'
|
2
|
+
|
3
|
+
module CfnDsl
|
4
|
+
# Handles autoscaling group update policy objects for Resources
|
5
|
+
#
|
6
|
+
# Usage
|
7
|
+
# Resource("aaa") {
|
8
|
+
# UpdatePolicy("AutoScalingRollingUpdate", {
|
9
|
+
# "MinInstancesInService" => "1",
|
10
|
+
# "MaxBatchSize" => "1",
|
11
|
+
# "PauseTime" => "PT12M5S"
|
12
|
+
# })
|
13
|
+
# }
|
14
|
+
#
|
15
|
+
class UpdatePolicyDefinition < JSONable
|
16
|
+
attr_reader :value
|
17
|
+
def initialize(value)
|
18
|
+
@value = value
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_json(*a)
|
22
|
+
@value.to_json(*a)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/cfndsl/version.rb
CHANGED