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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8931d15c79795527491f73c4440eb25decfbf0c1
4
- data.tar.gz: '0318b27b08e66eca49fe8c459a1036ef9d421a3f'
3
+ metadata.gz: ea262d5b5afd735ba927d096ad928f509ba36ebf
4
+ data.tar.gz: 3c44b95e767817b022dcb7ed20dfbfa413882366
5
5
  SHA512:
6
- metadata.gz: c233b5c721e0d9701529748010627cb237d368b247902ef3a3b616fd1060d0e2319bb2d20eec338793604e55a2deb2d7bc16554651c92d6a9ea63df7f4a8d9eb
7
- data.tar.gz: 2bcf5644dd5d20986c96635276fbac598cef484ee4e5d3e670c214272624c95e0dc62e4ec974e0ccf048092c862f306d3ad42ee7dce396dcd0690911fcc4c5cc
6
+ metadata.gz: 3ac71c23b2062b707a5caafceb973de58ccc4ba32436373f6a26ee14ea49350d19078f6de1bc959d0280477412a63db8e03a7de9b53ddfa175cdc0c8d4dc52ab
7
+ data.tar.gz: c2a5cae44fda5935f59c4dea52486ddfc4371b4fe1ad1e294bd3d39f2cdaaab7ff833007e1a492fc8cb0891acc358d9feefffabf5a431b75bbbfcc7c2d30789a
data/README.md CHANGED
@@ -1 +1 @@
1
- ./docs/index.md
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
- create_file File.join(options[:output_directory], "#{resource.name.downcase}.tf.json"), resource.to_hcl_json
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.1
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-23 00:00:00.000000000 Z
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.6.13
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