convection 2.2.1 → 2.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/bin/convection +27 -2
- data/convection.gemspec +1 -0
- data/lib/convection/dsl/terraform_intrinsic_functions.rb +93 -0
- metadata +18 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ea262d5b5afd735ba927d096ad928f509ba36ebf
|
4
|
+
data.tar.gz: 3c44b95e767817b022dcb7ed20dfbfa413882366
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3ac71c23b2062b707a5caafceb973de58ccc4ba32436373f6a26ee14ea49350d19078f6de1bc959d0280477412a63db8e03a7de9b53ddfa175cdc0c8d4dc52ab
|
7
|
+
data.tar.gz: c2a5cae44fda5935f59c4dea52486ddfc4371b4fe1ad1e294bd3d39f2cdaaab7ff833007e1a492fc8cb0891acc358d9feefffabf5a431b75bbbfcc7c2d30789a
|
data/README.md
CHANGED
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
docs/index.md
|
data/bin/convection
CHANGED
@@ -118,36 +118,59 @@ module Convection
|
|
118
118
|
describe_stack_resources(options[:stack], options[:format], options[:properties], options[:type])
|
119
119
|
end
|
120
120
|
|
121
|
+
# rubocop:disable Style/AsciiComments
|
122
|
+
|
121
123
|
desc 'terraform-export STACK', 'Create terraform configuration for a given stack (including `terraform import` commands)'
|
122
124
|
option :module_path, desc: 'The module path prefix for terraform', default: DEFAULT_MODULE_PATH
|
123
125
|
option :output_directory, desc: 'The directory to create configuration files under', aliases: %w(-d --dir), default: '.'.freeze
|
124
126
|
option :cloudfile, desc: 'The cloudfile to load', default: 'Cloudfile'
|
127
|
+
option :confirm_root, desc: 'Prompt to confirm module path when --module-path="root"', default: true, type: :boolean
|
128
|
+
option :overwrite, desc: 'Overwrite any conflicting tf.json files in --output-directory', default: false, type: :boolean
|
129
|
+
option :skip_existing, desc: 'Skip any conflicting tf.json files in --output-directory', default: false, type: :boolean
|
125
130
|
def terraform_export(stack_name)
|
126
131
|
if options[:output_directory].empty?
|
127
132
|
say_status :error, '--output-directory must not be empty.', :red
|
128
133
|
exit 1
|
129
134
|
end
|
130
135
|
|
131
|
-
if options[:module_path] == DEFAULT_MODULE_PATH
|
136
|
+
if options[:confirm_root] && options[:module_path] == DEFAULT_MODULE_PATH
|
132
137
|
say_status :warning, '--module-path was set to "root".', :yellow
|
133
138
|
exit 0 unless yes?('Are you sure you want to generate terraform import commands in the root namespace?')
|
134
139
|
end
|
135
140
|
|
136
141
|
init_cloud
|
137
142
|
template = @cloud.stacks.fetch(stack_name).template
|
143
|
+
# Beware of 🐲. This patches this Template to include terraform compatible intrinsic functions where possible.
|
144
|
+
#
|
145
|
+
# This should only be done in single threaded environment in the terraform-export command as it breaks usage of cloudformation psuedo-functions.
|
146
|
+
#
|
147
|
+
# e.g. #get_att("Bucket", "Arn") returns "aws_s3_bucket.bucket.arn" instead of { "Fn::GetAtt" => ["Bucket", "Arn"] }.
|
148
|
+
require 'convection/dsl/terraform_intrinsic_functions'
|
149
|
+
template.extend(Convection::DSL::TerraformIntrinsicFunctions)
|
138
150
|
template.resource_collections.each(&method(:import_resources))
|
139
151
|
template.resources.each(&method(:import_resources))
|
140
152
|
end
|
141
153
|
|
154
|
+
# rubocop:enable Style/AsciiComments
|
155
|
+
|
142
156
|
no_commands do
|
143
157
|
attr_accessor :last_event
|
144
158
|
|
145
159
|
private
|
146
160
|
|
161
|
+
# rubocop:disable Style/AsciiComments
|
162
|
+
|
147
163
|
def import_resources(_resource_name, resource)
|
164
|
+
# Beware of 🐲. This patches this instance to include terraform compatible intrinsic functions where possible.
|
165
|
+
#
|
166
|
+
# This should only be done in single threaded environment in the terraform-export command as it breaks usage of cloudformation psuedo-functions.
|
167
|
+
require 'convection/dsl/terraform_intrinsic_functions'
|
168
|
+
resource.extend(Convection::DSL::TerraformIntrinsicFunctions)
|
169
|
+
|
148
170
|
if resource.respond_to?(:to_hcl_json)
|
149
171
|
empty_directory options[:output_directory]
|
150
|
-
|
172
|
+
destination = File.join(options[:output_directory], "#{resource.name.downcase}.tf.json")
|
173
|
+
create_file destination, resource.to_hcl_json, force: options[:overwrite], skip: options[:skip_existing]
|
151
174
|
else
|
152
175
|
say "# Unable to generate terraform configuration for #{resource.class}. Define #{resource.class}#to_hcl_json to do so.", :yellow
|
153
176
|
end
|
@@ -169,6 +192,8 @@ module Convection
|
|
169
192
|
puts # Print an additional new line
|
170
193
|
end
|
171
194
|
|
195
|
+
# rubocop:enable Style/AsciiComments
|
196
|
+
|
172
197
|
def operation(task_name, stack)
|
173
198
|
work_q = Queue.new
|
174
199
|
semaphore = Mutex.new
|
data/convection.gemspec
CHANGED
@@ -18,6 +18,7 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(/^(test|spec|features)\//)
|
19
19
|
spec.require_paths = ['lib']
|
20
20
|
|
21
|
+
spec.add_runtime_dependency 'activesupport'
|
21
22
|
spec.add_runtime_dependency 'aws-sdk', '>= 2'
|
22
23
|
spec.add_runtime_dependency 'httparty', '~> 0.13'
|
23
24
|
spec.add_runtime_dependency 'netaddr', '~> 1.5'
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require 'active_support/core_ext/string/inflections'
|
2
|
+
|
3
|
+
module Convection
|
4
|
+
module DSL
|
5
|
+
module TerraformIntrinsicFunctions
|
6
|
+
def base64(_content)
|
7
|
+
%q(base64(#{content.to_json}))
|
8
|
+
end
|
9
|
+
|
10
|
+
def fn_and(*)
|
11
|
+
warn "WARNING: Condition functions cannot be inferred when migrating to terraform. Please set count on migrated resources manually. #{self.class}(#{name})"
|
12
|
+
'${todo.fn_and.ATTRIBUTE.set_in_count}'
|
13
|
+
end
|
14
|
+
|
15
|
+
def fn_equals(*)
|
16
|
+
warn "WARNING: Condition functions cannot be inferred when migrating to terraform. Please set count on migrated resources manually. #{self.class}(#{name})"
|
17
|
+
'${todo.fn_equals.ATTRIBUTE.set_in_count}'
|
18
|
+
end
|
19
|
+
|
20
|
+
def fn_if(*)
|
21
|
+
warn "WARNING: Condition functions cannot be inferred when migrating to terraform. Please set count on migrated resources manually. #{self.class}(#{name})"
|
22
|
+
'${todo.fn_if.ATTRIBUTE.set_in_count}'
|
23
|
+
end
|
24
|
+
|
25
|
+
def fn_import_value(*)
|
26
|
+
warn "WARNING: Fn::ImportValue cannot be inferred when migrated to terraform. Please pull in this input through a variable or local value in your configuration. #{self.class}(#{name})"
|
27
|
+
'${todo.fn_import_value.ATTRIBUTE}'
|
28
|
+
end
|
29
|
+
|
30
|
+
def fn_not(*)
|
31
|
+
warn "WARNING: Condition functions cannot be inferred when migrating to terraform. Please set count on migrated resources manually. #{self.class}(#{name})"
|
32
|
+
'${todo.fn_not.ATTRIBUTE.set_in_count}'
|
33
|
+
end
|
34
|
+
|
35
|
+
def fn_or(*)
|
36
|
+
warn "WARNING: Condition functions cannot be inferred when migrating to terraform. Please set count on migrated resources manually. #{self.class}(#{name})"
|
37
|
+
'${todo.fn_or.ATTRIBUTE.set_in_count}'
|
38
|
+
end
|
39
|
+
|
40
|
+
def fn_sub(*)
|
41
|
+
warn "WARNING: Fn::Sub cannot be inferred when migrating to terraform. Please use ${replace(str, search, replace)} instead. #{self.class}(#{name})"
|
42
|
+
'${replace(todo.fn_sub.STRING, todo.fn_sub.SEARCH, todo.fn_sub.REPLACE)}'
|
43
|
+
end
|
44
|
+
|
45
|
+
def find_in_map(*)
|
46
|
+
warn "WARNING: Fn::FindInMap cannot be inferred when migrating to terraform. Please consult with the interpolation syntax terraform docs #{self.class}(#{name})"
|
47
|
+
'${lookup(lookup(YOUR_MAP, YOUR_TOP_LEVEL_KEY), YOUR_NESTED_KEY)}'
|
48
|
+
end
|
49
|
+
|
50
|
+
def get_att(resource_name, attr_name)
|
51
|
+
interpolation_string = "${#{terraform_resource_type(resource_name)}.#{terraform_resource_name(resource_name)}.#{attr_name.underscore}}"
|
52
|
+
warn "WARNING: Inferring you want to use #{interpolation_string} in place of Fn::GetAtt. Please consult with the interpolation syntax terraform docs and docs for this resource type in terraform to verify compatablity. #{self.class}(#{name})"
|
53
|
+
interpolation_string
|
54
|
+
end
|
55
|
+
|
56
|
+
def get_azs(*)
|
57
|
+
warn "WARNING: Inferring you want to use ${var.availability_zones} instead of Fn::GetAZs. Please consult with the interpolation syntax terraform docs to verify compatablity. Additionally you should attempt to use variables in place of a literal list. #{self.class}(#{name})"
|
58
|
+
'${var.availability_zones}'
|
59
|
+
end
|
60
|
+
|
61
|
+
def join(delimiter, *values)
|
62
|
+
interpolation_string = "${join(\"#{delimiter}\", list(#{values.map { |o| "\"#{o}\"" }.join(', ')}))"
|
63
|
+
warn "WARNING: Inferring you want to use #{interpolation_string} in place of Fn::Join. Please consult with the interpolation syntax terraform docs to verify compatablity. Additionally you should attempt to use variables in place of a literal list. #{self.class}(#{name})"
|
64
|
+
interpolation_string
|
65
|
+
end
|
66
|
+
|
67
|
+
def select(index, *objects)
|
68
|
+
interpolation_string = "${element(list(#{objects.map { |o| "\"#{o}\"" }.join(', ')}), #{index})"
|
69
|
+
warn "WARNING: Inferring you want to use #{interpolation_string} in place of Fn::Select. Please consult with the interpolation syntax terraform docs to verify compatablity. Additionally you should attempt to use variables in place of a literal list. #{self.class}(#{name})"
|
70
|
+
interpolation_string
|
71
|
+
end
|
72
|
+
|
73
|
+
def fn_ref(resource_name)
|
74
|
+
interpolation_string = "${#{terraform_resource_type(resource_name)}.#{terraform_resource_name(resource_name)}.id}"
|
75
|
+
warn "WARNING: Inferring you want to use #{interpolation_string} in place of Fn::Ref. Please consult with the interpolation syntax terraform docs and docs for this resource type in terraform to verify compatablity. #{self.class}(#{name})"
|
76
|
+
interpolation_string
|
77
|
+
end
|
78
|
+
|
79
|
+
def terraform_resource_name(resource_name)
|
80
|
+
resource_name.underscore
|
81
|
+
end
|
82
|
+
|
83
|
+
def terraform_resource_type(resource_name)
|
84
|
+
return type.sub(/^AWS::/, 'aws_').underscore if respond_to?(:type)
|
85
|
+
return resources[resource_name].type.underscore if respond_to?(:resources) && resources[resource_name]
|
86
|
+
return all_resources[resource_name].type.underscore if respond_to?(:all_resources) && all_resources[resource_name]
|
87
|
+
return parent.resources[resource_name].type.underscore if respond_to?(:parent) && parent.resources[resource_name]
|
88
|
+
|
89
|
+
'todo_fixme_see_resource_type'
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: convection
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.2.
|
4
|
+
version: 2.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- John Manero
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-12-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: aws-sdk
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -118,6 +132,7 @@ files:
|
|
118
132
|
- lib/convection/control/stack.rb
|
119
133
|
- lib/convection/dsl/helpers.rb
|
120
134
|
- lib/convection/dsl/intrinsic_functions.rb
|
135
|
+
- lib/convection/dsl/terraform_intrinsic_functions.rb
|
121
136
|
- lib/convection/model/attributes.rb
|
122
137
|
- lib/convection/model/cloudfile.rb
|
123
138
|
- lib/convection/model/diff.rb
|
@@ -363,7 +378,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
363
378
|
version: '0'
|
364
379
|
requirements: []
|
365
380
|
rubyforge_project:
|
366
|
-
rubygems_version: 2.
|
381
|
+
rubygems_version: 2.5.1
|
367
382
|
signing_key:
|
368
383
|
specification_version: 4
|
369
384
|
summary: A fully generic, modular DSL for AWS CloudFormation
|