aws-carb 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: a8091f519cc7a1feb9f06b8e7970b160e9fa18d8
4
+ data.tar.gz: 3ec84346a2226990efd24aa108e5a8f346c42977
5
+ SHA512:
6
+ metadata.gz: 4042bb7bdb921791fa89ff6c6c76da063b95a95dbf89c91df3c66ce4b3bb7f95cdcd58c69c6f475dfdc560d30f5439d42bc14a41873d84127998d51fcac10ab5
7
+ data.tar.gz: 189636adab38df5f0412792e82e2173fbf861e8a76b49b2634719b7faad8c252c52887400c720b21efead5976afc2b5d220613df363d30368c752e8bd01a203e
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ .*.sw?
2
+ *.lock
3
+ *.gem
4
+ .bundle
5
+ config.yaml
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
data/README.md ADDED
@@ -0,0 +1,31 @@
1
+ # aws-carb: amazon web services - cloudinit and route53 bootstrap
2
+
3
+ ## Install
4
+
5
+ via rubygems:
6
+
7
+ ```
8
+ gem install aws-carb
9
+ ```
10
+
11
+ using bundler:
12
+
13
+ ```
14
+ bundler install
15
+ ```
16
+
17
+ ## Configuration
18
+
19
+ At minimum, Carb needs to know your aws-ec2 credentials. The simplest way to allow this is to edit ~/.carb/config/config.yaml. See config/config.yaml.example for an example config.
20
+
21
+
22
+ ## Example usage
23
+
24
+ carb can be used to create ec2 instances
25
+
26
+ ```
27
+ aws create
28
+ ```
29
+
30
+
31
+
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/aws-carb.gemspec ADDED
@@ -0,0 +1,32 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'aws-carb/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "aws-carb"
8
+ spec.version = AWSCarb::VERSION
9
+ spec.authors = ["Rob Wilson"]
10
+ spec.email = ["roobert@gmail.com"]
11
+ spec.summary = "aws - cloudinit and route53 bootstrap"
12
+ spec.description = "a tool for provisioning ec2 instances with a templated cloudinit configuration, with the optional ability to update route53 with dns records to point at your new instance"
13
+ spec.homepage = "http://github.com/roobert/aws-carb"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.5"
22
+ spec.add_development_dependency "rake", "~> 10.0.0"
23
+
24
+ spec.add_dependency "activesupport", ">= 4.0.0"
25
+ spec.add_dependency "andand", ">= 1.3.0"
26
+ spec.add_dependency "awesome_print", ">= 1.2.0"
27
+ spec.add_dependency "aws-sdk", ">= 1.33.0"
28
+ spec.add_dependency "colorize", ">= 0.6.0"
29
+ spec.add_dependency "erubis", ">= 2.7.0"
30
+ spec.add_dependency "shell-spinner", ">= 1.0.0"
31
+ spec.add_dependency "subcommand", ">= 1.0.0"
32
+ end
data/bin/carb ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '../lib'))
4
+
5
+ require 'aws-carb'
6
+ require 'aws-carb/helpers'
7
+ require 'aws-carb/cli_argument_parser'
8
+ require 'aws-carb/config'
9
+ require 'aws-carb/user_data'
10
+ require 'aws-carb/services/route53'
11
+ require 'aws-carb/services/ec2'
12
+ require 'aws-carb/monkey_patches'
13
+
14
+ AWSCarb.run
@@ -0,0 +1,24 @@
1
+ common:
2
+ domain: <domain>
3
+
4
+ ec2:
5
+ access_key_id: <key_id>
6
+ secret_access_key: <secret_key>
7
+
8
+ template_options:
9
+ repository_server: <repo_server>
10
+ debian_distro: <distro>
11
+ puppet_master: <puppetmaster>
12
+ s3_access_key_id: <key_id>
13
+ s3_secret_access_key: <secret_key>
14
+ s3_region: us-east-1
15
+ ssh_keys:
16
+ - <key>
17
+ - <key>
18
+ - <key>
19
+
20
+ route53:
21
+ access_key_id: <key_id>
22
+ secret_access_key: <secret_key>
23
+ zone: <zone_id>
24
+ ttl: 600
@@ -0,0 +1,359 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ include Subcommands
4
+
5
+ module AWSCarb
6
+ module CliArgumentParser
7
+ def self.parse
8
+ cli_arguments = OpenStruct.new
9
+ cli_arguments.global = OpenStruct.new
10
+ cli_arguments.subcommand = OpenStruct.new
11
+ cli_arguments.subcommand.user_data_template = OpenStruct.new
12
+ cli_arguments.subcommand.config_overrides = OpenStruct.new
13
+ cli_arguments.subcommand.ec2 = OpenStruct.new
14
+ cli_arguments.subcommand.route53 = OpenStruct.new
15
+
16
+ indent = ' ' * 10
17
+
18
+ banner = <<-HEREDOC.strip_heredoc
19
+ #{File.basename($0)}(1)
20
+
21
+ #{'NAME'.colorize({:color => :white, :mode => :bold})}
22
+
23
+ carb
24
+
25
+ #{'DESCRIPTION'.colorize({:color => :white, :mode => :bold})}
26
+
27
+ amazon web services - cloudinit and route53 bootstrap
28
+
29
+ HEREDOC
30
+
31
+
32
+ # these are the only defaults we need to bother setting since they get used before we load the config file..
33
+ cli_arguments.global.verbose = false
34
+ cli_arguments.global.config_file = File.join(Dir.home, ".carb/config", "config.yaml")
35
+
36
+ global_options do |option|
37
+
38
+ option.summary_width = 50
39
+ option.summary_indent = ' '
40
+
41
+ synopsis = <<-HEREDOC.strip_heredoc
42
+ #{"SYNOPSIS".colorize({:color => :white, :mode => :bold})}
43
+
44
+ #{File.basename($0)} [global options] [subcommand [options]]
45
+
46
+ HEREDOC
47
+
48
+ option.banner = banner + synopsis
49
+ option.separator "#{'GLOBAL OPTIONS'.colorize({:color => :white, :mode => :bold})}"
50
+ option.separator ""
51
+
52
+ option.on("-c", "--config=FILE", "") do |file|
53
+ cli_arguments.global.config_file = file
54
+ end
55
+
56
+ option.separator ""
57
+
58
+ option.on("-v", "--verbose", "") do |boolean|
59
+ cli_arguments.global.verbose = boolean
60
+
61
+ # FIXME: use a stupidly named global(!!!!!) variable to avoid clashing with rubys $VERBOSE
62
+ $GLOBAL_VERBOSE = boolean
63
+ end
64
+
65
+ option.separator ""
66
+ option.separator " -h, --help"
67
+ end
68
+
69
+ command :create do |option|
70
+
71
+ option.summary_width = 50
72
+ option.summary_indent = ' '
73
+
74
+ synopsis = <<-HEREDOC.strip_heredoc
75
+ #{'SYNOPSIS'.colorize({:color => :white, :mode => :bold})}
76
+
77
+ #{File.basename($0)} create [options]
78
+
79
+ HEREDOC
80
+
81
+ option.banner = banner + synopsis
82
+ option.description = "create an ec2 instance"
83
+
84
+ option.separator ""
85
+ option.separator " user_data tempate options:"
86
+ option.separator ""
87
+
88
+ option.on "--user-data-template=FILE", "\n\n#{indent}user data template" do |user_data_template|
89
+ cli_arguments.subcommand.user_data_template.file = user_data_template
90
+ end
91
+
92
+ option.separator ""
93
+
94
+ option.on "--show-parsed-template=BOOLEAN", "\n\n#{indent}display parsed template file" do |show_parsed_template|
95
+ cli_arguments.subcommand.user_data_template.show_parsed_template = show_parsed_template
96
+ end
97
+
98
+ option.separator ""
99
+
100
+ option.separator ""
101
+ option.separator " config file overrides:"
102
+ option.separator ""
103
+
104
+ option.on "--common-variables=HASH", String, "\n\n#{indent}common variables" do |common_variables|
105
+ begin
106
+ data = eval(common_variables)
107
+ raise unless data.class == Hash
108
+ cli_arguments.subcommand.config_overrides.common_variables = data.deep_symbolize_keys
109
+ rescue => e
110
+ puts "# could not parse argument for --common-variables, is it a valid hash?"
111
+ die e
112
+ end
113
+ end
114
+
115
+ option.separator ""
116
+
117
+ option.on "--general-variables=HASH", String, "\n\n#{indent}general variables" do |general_variables|
118
+ begin
119
+ data = eval(general_variables)
120
+ raise unless data.class == Hash
121
+ cli_arguments.subcommand.config_overrides.general_variables = data.deep_symbolize_keys
122
+ rescue => e
123
+ puts "# could not parse argument for --general-variables, is it a valid hash?"
124
+ die e
125
+ end
126
+ end
127
+
128
+ option.separator ""
129
+
130
+ option.on "--ec2-variables=HASH", String, "\n\n#{indent}ec2 variables" do |ec2_variables|
131
+ begin
132
+ data = eval(ec2_variables)
133
+ raise unless data.class == Hash
134
+ cli_arguments.subcommand.config_overrides.ec2_variables = data.deep_symbolize_keys
135
+ rescue => e
136
+ puts "# could not parse argument for --ec2-variables, is it a valid hash?"
137
+ die e
138
+ end
139
+ end
140
+
141
+ option.separator ""
142
+
143
+ option.on "--route53-variables=HASH", String, "\n\n#{indent}route53 variables" do |route53_variables|
144
+ begin
145
+ data = eval(route53_variables)
146
+ raise unless data.class == Hash
147
+ cli_arguments.subcommand.config_overrides.route53_variables = data.deep_symbolize_keys
148
+ rescue => e
149
+ puts "# could not parse argument for --route53-variables, is it a valid hash?"
150
+ die e
151
+ end
152
+ end
153
+
154
+ option.separator ""
155
+
156
+ option.on "--user-data-template-variables=HASH", String, "\n\n#{indent}user data template variables" do |user_data_template_variables|
157
+ begin
158
+ data = eval(user_data_template_variables)
159
+ raise unless data.class == Hash
160
+ cli_arguments.subcommand.config_overrides.user_data_template_variables = data.deep_symbolize_keys
161
+ rescue => e
162
+ puts "# could not parse argument for --user-data-template-variables, is it a valid hash?"
163
+ die e
164
+ end
165
+ end
166
+
167
+ option.separator ""
168
+ option.separator " long descriptions for these parameters can be found here:\n http://<TODO>"
169
+ option.separator ""
170
+
171
+ option.separator ""
172
+ option.separator " ec2 config convenience arguments:"
173
+ option.separator ""
174
+
175
+ option.on "--ec2-access-key-id=STRING", "\n\n#{indent}access key id".downcase do |access_key_id|
176
+ cli_arguments.subcommand.ec2.access_key_id = access_key_id
177
+ end
178
+
179
+ option.separator ""
180
+
181
+ option.on "--ec2-secret-access-key=STRING", "\n\n#{indent}secret access key".downcase do |secret_access_key|
182
+ cli_arguments.subcommand.ec2.secret_access_key = secret_access_key
183
+ end
184
+
185
+ option.separator ""
186
+
187
+ option.on "--image-id=STRING", "\n\n#{indent}ID of the AMI you want to launch.".downcase do |image_id|
188
+ cli_arguments.subcommand.ec2.image_id = image_id
189
+ end
190
+
191
+ option.separator ""
192
+
193
+ option.on "--instance-type=STRING", "\n\n#{indent}The type of instance to launch, for example \"m1.small\".".downcase do |instance_type|
194
+ cli_arguments.subcommand.ec2.instance_type = instance_type
195
+ end
196
+
197
+ option.separator ""
198
+
199
+ option.on "--key-name=STRING", "\n\n#{indent}The name of the key pair to use.".downcase do |key_name|
200
+ cli_arguments.subcommand.ec2.key_name = key_name
201
+ end
202
+
203
+ option.separator ""
204
+
205
+
206
+ block_device_help = <<-HEREDOC.strip_heredoc
207
+
208
+ :virtual_name - (String) Specifies the virtual device name.
209
+ :device_name - (String) Specifies the device name (e.g., /dev/sdh).
210
+ :ebs - (Hash) Specifies parameters used to automatically setup Amazon\n#{indent} EBS volumes when the instance is launched.
211
+ :snapshot_id - (String) The ID of the snapshot from which the volume will be created.
212
+ :volume_size - (Integer) The size of the volume, in gigabytes.
213
+ :delete_on_termination - (Boolean) Specifies whether the Amazon EBS volume is\n#{indent} deleted on instance termination.
214
+ :volume_type - (String) Valid values include:
215
+ standard
216
+ io1
217
+ :iops - (Integer)
218
+ :no_device - (String) Specifies the device name to suppress during instance launch.
219
+ HEREDOC
220
+
221
+ block_device_help = block_device_help.lines.map { |line| indent + " #{line}" }
222
+
223
+ block_device_help = "\n\n#{indent}Specifies how block devices are exposed to the instance. Each mapping\n#{indent}is made up of a virtualName and a deviceName.\n" + block_device_help.join.downcase
224
+
225
+ option.on "--block-device-mappings=HASH", block_device_help do |key_name|
226
+ cli_arguments.subcommand.ec2.key_name = key_name
227
+ end
228
+
229
+ option.separator ""
230
+
231
+ option.on "--user-data=STRING", "\n\n#{indent}Arbitrary user data. note: this is merged with user_data_template if also specified.".downcase do |user_data|
232
+ cli_arguments.subcommand.ec2.user_data = user_data
233
+ end
234
+
235
+ option.separator ""
236
+
237
+ option.on "--iam-instance-profile=STRING", "\n\n#{indent}the name or ARN of an IAM instance profile.".downcase do |profile|
238
+ cli_arguments.subcommand.ec2.iam_instance_profile = profile
239
+ end
240
+
241
+ option.separator ""
242
+
243
+ option.on "--monitoring-enabled=BOOLEAN", "\n\n#{indent}enable CloudWatch monitoring.".downcase do |boolean|
244
+ cli_arguments.subcommand.ec2.monitoring_enabled = boolean
245
+ end
246
+
247
+ option.separator ""
248
+
249
+ option.on "--availability-zone=STRING", "\n\n#{indent}availability zone.".downcase do |zone|
250
+ cli_arguments.subcommand.ec2.availability_zone = zone
251
+ end
252
+
253
+ option.separator ""
254
+
255
+ option.on "--security-groups=ARRAY", Array, "\n\n#{indent}Security groups. can be a single value or an array of values.\n#{indent}Values should be space deliminated group name strings.".downcase do |groups|
256
+ cli_arguments.subcommand.ec2.security_groups = groups
257
+ end
258
+
259
+ option.separator ""
260
+
261
+ option.on "--security-group-ids=ARRAY", Array, "\n\n#{indent}security_group_ids accepts a single ID or an array of\n#{indent}security group IDs.".downcase do |group_ids|
262
+ cli_arguments.subcommand.ec2.security_group_ids = group_ids
263
+ end
264
+
265
+ option.separator ""
266
+
267
+ option.on "--disable-api-termination=BOOLEAN", "\n\n#{indent}instance termination via the instance API.".downcase do |api_termination|
268
+ cli_arguments.subcommand.ec2.disable_api_termination = api_termination
269
+ end
270
+
271
+ option.separator ""
272
+
273
+ option.on "--instance-initiated-shutdown-behavior=STRING", "\n\n#{indent}instance termination on instance-initiated shutdown".downcase do |shutdown_behavior|
274
+ cli_arguments.subcommand.ec2.instance_initiated_shutdown_behavior = shutdown_behavior
275
+ end
276
+
277
+ option.separator ""
278
+
279
+ option.on "--subnet=STRING", "\n\n#{indent}The VPC Subnet (or subnet id string) to launch the instance in.".downcase do |subnet|
280
+ cli_arguments.subcommand.ec2.subnet = subnet
281
+ end
282
+
283
+ option.separator ""
284
+
285
+ option.on "--private_ip_address=STRING", "\n\n#{indent}If you're using VPC, you can optionally use this option to assign the\n#{indent}instance a specific available IP address from the subnet (e.g., '10.0.0.25').\n#{indent}This option is not valid for instances launched outside a VPC (i.e.\n#{indent}those launched without the :subnet option).".downcase do |ip|
286
+ cli_arguments.subcommand.ec2.private_ip_address = ip
287
+ end
288
+
289
+ option.separator ""
290
+
291
+ option.on "--dedicated-tenancy=BOOLEAN", "\n\n#{indent}Instances with dedicated tenancy will not share physical hardware with\n#{indent}instances outside their VPC. NOTE: Dedicated tenancy incurs an \n#{indent}additional service charge. This option is not valid for\n#{indent}instances launched outside a VPC (e.g.those launched without the :subnet option).".downcase do |tenancy|
292
+ cli_arguments.subcommand.ec2.dedicated_tenancy = tenancy
293
+ end
294
+
295
+ option.separator ""
296
+
297
+ option.on "--ebs-optimized=BOOLEAN", "\n\n#{indent}EBS-Optimized instances enable Amazon EC2 instances to fully utilize the\n#{indent}IOPS provisioned on an EBS volume. EBS-optimized instances deliver dedicated\n#{indent}throughput between Amazon EC2 and Amazon EBS, with options between\n#{indent}500 Mbps and 1000 Mbps depending on the instance type used. When attached\n#{indent}to EBS-Optimized instances, Provisioned IOPS volumes are designed to\n#{indent}deliver within 10% of their provisioned performance 99.9% of the time.\n#{indent}NOTE: EBS Optimized instances incur an additional service charge.\n#{indent}This option is only valid for certain instance types.".downcase do |ebs_optimized|
298
+ cli_arguments.subcommand.ec2.ebs_optimized = ebs_optimized
299
+ end
300
+
301
+ option.separator ""
302
+ option.separator " long descriptions for these parameters can be found here:\n http://docs.aws.amazon.com/AWSRubySDK/latest/AWS/EC2/InstanceCollection.html"
303
+ option.separator ""
304
+
305
+ option.separator ""
306
+ option.separator " route53 convenience arguments:"
307
+ option.separator ""
308
+
309
+ option.on "--route53-access-key-id=STRING", "\n\n#{indent}access key id".downcase do |access_key_id|
310
+ cli_arguments.subcommand.route53.access_key_id = access_key_id
311
+ end
312
+
313
+ option.separator ""
314
+
315
+ option.on "--route53-secret-access-key=STRING", "\n\n#{indent}secret access key".downcase do |secret_access_key|
316
+ cli_arguments.subcommand.route53.secret_access_key = secret_access_key
317
+ end
318
+
319
+ option.separator ""
320
+
321
+
322
+ option.on "--zone=STRING", "\n\n#{indent}route53 zone".downcase do |zone|
323
+ cli_arguments.subcommand.route53.route = route
324
+ end
325
+
326
+ option.separator ""
327
+
328
+ option.on "--ttl=STRING", "\n\n#{indent}ttl".downcase do |ttl|
329
+ cli_arguments.subcommand.route53.ttl = ttl
330
+ end
331
+
332
+ option.separator ""
333
+
334
+ end
335
+
336
+ begin
337
+ #cli_arguments.chosen_subcommand = opt_parse
338
+ subcommand = opt_parse
339
+
340
+ # show help if no arguments passed in
341
+ if subcommand.nil?
342
+ add_subcommand_help
343
+ puts @global
344
+
345
+ exit 1
346
+ end
347
+
348
+ if ARGV.length > 0
349
+ raise ArgumentError, "unknown command line argument(s): #{ARGV.inspect.to_s}"
350
+ end
351
+ rescue => e
352
+ puts e
353
+ exit 1
354
+ end
355
+
356
+ return cli_arguments
357
+ end
358
+ end
359
+ end
@@ -0,0 +1,166 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ module AWSCarb
4
+ class Config
5
+ include Singleton
6
+
7
+ attr_reader :config
8
+
9
+ def create(cli_arguments)
10
+
11
+ @config = load_file(cli_arguments.global.config_file)
12
+
13
+ merge_cli_arguments_with_config(cli_arguments)
14
+
15
+ establish_hostname_and_domain
16
+
17
+ check_route53_settings
18
+ end
19
+
20
+ def check_route53_settings
21
+ die 'route53: no zone id specified!' if @config[:route53][:zone].nil?
22
+ die 'route53: no ttl specified!' if @config[:route53][:zone].nil?
23
+ end
24
+
25
+ def merge_cli_arguments_with_config(cli_arguments)
26
+ begin
27
+
28
+ config_sections = [:common, :general, :ec2, :route53, :user_data_template_variables, :user_data_template]
29
+
30
+ # special condition: common command line arguments are shared between all instances first..
31
+ if cli_arguments.subcommand.config_overrides.common_variables
32
+ @config[:common] ||= {}
33
+ @config[:common].merge! cli_arguments.subcommand.config_overrides.common_variables
34
+ end
35
+
36
+ # all sections share 'common' variables..
37
+ config_sections.each do |section|
38
+ @config[section] ||= {}
39
+ @config[section].merge! @config[:common]
40
+ end
41
+
42
+ # merge the config overrides hashes into config
43
+ if cli_arguments.subcommand.config_overrides
44
+ cli_arguments.subcommand.config_overrides.marshal_dump.each do |key, value|
45
+
46
+ next if key == :common
47
+
48
+ # key differs from command line argument - we lose the _variables suffix
49
+ config_key = key.to_s.gsub('_variables', '').to_sym
50
+
51
+ @config[config_key] ||= {}
52
+ @config[config_key].merge! cli_arguments.subcommand.config_overrides.send(key)
53
+ end
54
+ end
55
+
56
+ # merge the convenience arguments..
57
+ config_sections.each do |section|
58
+ if cli_arguments.subcommand.send(section.to_s)
59
+ @config[section].merge! cli_arguments.subcommand.send(section.to_s).marshal_dump
60
+ end
61
+ end
62
+
63
+ # merge the convenience argument parameters with config
64
+ @config.deep_symbolize_keys!
65
+
66
+ rescue => e
67
+ puts "# failed to merge cli arguments with config"
68
+ die e
69
+ end
70
+ end
71
+
72
+ def load_file(cli_argument_config_file)
73
+
74
+ # allow forcing of no config file..
75
+ return if cli_argument_config_file.empty?
76
+
77
+ config_file = cli_argument_config_file
78
+
79
+ begin
80
+ # make keys symbols so we can more easily merge with cli arg structs..
81
+ @config = YAML.load_file(config_file).deep_symbolize_keys
82
+ rescue => e
83
+ puts "# failed to load config file: '#{config_file}'"
84
+ die e
85
+ end
86
+ end
87
+
88
+ # when looking for a key, check 'common' section first, then override if a value
89
+ # in the supplied context is found..
90
+ def find_with_context(key, context)
91
+ return @config[context][key] if @config[context][key]
92
+ return @config[:common][key] if @config[:common][key]
93
+ return nil
94
+ end
95
+
96
+ def [](key)
97
+ @config[key]
98
+ end
99
+
100
+ # try and work out the hostname, presidence is:
101
+ #
102
+ # * config file
103
+ # * user_data_template_variables cli args
104
+ #
105
+ # note: raw user_data is not checked (not to be confused with user_data_template or user_data_template_variables..)
106
+ #
107
+ def establish_hostname_and_domain
108
+ ShellSpinner "# checking whether hostname and domain have been set", false do
109
+
110
+ hostname, domain = nil
111
+
112
+ @config[:route53][:hostname] = find_with_context(:hostname, :user_data_template_variables) if find_with_context(:hostname, :user_data_template_variables)
113
+ @config[:route53][:domain] = find_with_context(:domain, :user_data_template_variables) if find_with_context(:domain, :user_data_template_variables)
114
+ @config[:route53][:hostname] = find_with_context(:hostname, :route53) if find_with_context(:hostname, :route53)
115
+ @config[:route53][:domain] = find_with_context(:domain, :route53) if find_with_context(:domain, :route53)
116
+
117
+ help = <<-HEREDOC.strip_heredoc
118
+ #
119
+ # checked:
120
+ # 'common', 'user_data_template_variables',
121
+ # and 'route53' sections of config
122
+ # --common-variables, --route53-variables,
123
+ # and --user-data-template-variables
124
+ #
125
+ # route53 dynamic DNS will not be updated!
126
+ HEREDOC
127
+
128
+ domain = @config[:route53][:domain]
129
+ hostname = @config[:route53][:hostname]
130
+
131
+ if domain.nil? and hostname.nil?
132
+ debug "# WARNING: hostname and domain not found"
133
+ debug help
134
+ debug
135
+ elsif domain and hostname.nil?
136
+ debug "# WARNING: hostname not found"
137
+ debug help
138
+ debug
139
+ elsif domain.nil? and hostname
140
+ debug "# WARNING: domain not found"
141
+ debug help
142
+ debug
143
+ else
144
+ debug "# found hostname and domain:"
145
+ debug "hostname: #{hostname}"
146
+ debug "domain: #{domain}"
147
+ debug
148
+
149
+ @config[:route53][:new_dns_records] = {
150
+ :public => { :alias => "#{hostname}.#{domain}.", :target => nil },
151
+ :private => { :alias => "#{hostname}-private.#{domain}.", :target => nil }
152
+ }
153
+ end
154
+ end
155
+
156
+ puts
157
+ end
158
+
159
+
160
+ def display
161
+ puts "# config:"
162
+ ap @config
163
+ puts
164
+ end
165
+ end
166
+ end
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ def die(error)
4
+ if $GLOBAL_VERBOSE and error.respond_to?('backtrace')
5
+ puts "# stack trace:"
6
+ puts error.backtrace
7
+ puts
8
+ end
9
+
10
+ puts "error: #{error}"
11
+
12
+ exit 1
13
+ end
14
+
15
+ def debug(message = nil)
16
+ puts message if @GLOBAL_VERBOSE
17
+ end