awx 0.4.2 → 0.5.0

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: e8a94c9502e74dbf2341f840580ecef942de5f4b
4
- data.tar.gz: 1282d29984bc74544f9690e8165be5cc1d5e8937
3
+ metadata.gz: 54e617e3d455c0aa8d4f5d3dce0573cbb8ed86c3
4
+ data.tar.gz: 2039dffe2e3f9cc5e391fca408d726313280fcc7
5
5
  SHA512:
6
- metadata.gz: 80cb2a19a8ed00b096cfab3053ae90cfb32162f767f38cce76d86d985d364faaab670abf7629e7ae487aab3c7655cd557fc615f9179a330646a0eddb997b02c9
7
- data.tar.gz: fc84a4875cf90448c977a14f1e9849fb5685e1f0ef32b31d3a9676c04b37a479dc032ec24b9e0feb6c108b1237f09a60a3f7553f4fc9fb3549492123d1f2d591
6
+ metadata.gz: d050dcd91c40b5fb9fc39f38bba5854fe6790cc9cf77f262ab656bb0d8e666d63d0bafcd567a84a75c7142501e0e730bb559dfb5e48d73687d3528ebb02af699
7
+ data.tar.gz: 0cb3de40b28af605e5bbf33124a8c348c38441a95faa9a8fa90b81eafb8619fdf91d2ff6d8b74c0adadc71ae55739e6c50f70ba9d6ea35710f47406cecb3c1dc
@@ -5,7 +5,8 @@ module App
5
5
  # Gets the path to the root of the cloudformation templates in blufin-secrets repo.
6
6
  # @return string
7
7
  def self.get_cloudformation_path
8
- path = App::AWSProfile::get_profile['CloudFormation']['TemplatePath']
8
+ # TODO AWX PROFILE - Must support S3.
9
+ path = App::AWSProfile::get_profile['CloudFormation']['Templates']['Local']['Path']
9
10
  Blufin::Terminal::error("CloudFormation path not found: #{Blufin::Terminal::format_directory(path)}", 'This probably means directories got renamed or code got changed.', true) unless Blufin::Files::path_exists(path)
10
11
  path
11
12
  end
@@ -26,7 +27,7 @@ module App
26
27
  parsing_parameters = true
27
28
  Blufin::Files::read_file(tmp_file).each do |line|
28
29
  line = line.gsub("\n", '')
29
- if line.strip =~ /^description:/i
30
+ if line.strip =~ /^description:/i && !description_found
30
31
  new_lines << line unless description_found
31
32
  description_found = true
32
33
  else
@@ -44,7 +45,7 @@ module App
44
45
  template_filename = "#{template_category}-#{template_name}-#{DateTime.now.strftime('%Y%m%d-%H%M%S')}.yml"
45
46
  bucket_path = get_s3_bucket_path
46
47
  bucket_path = bucket_path == '' ? '' : "#{bucket_path}/"
47
- App::AWSCli::s3_upload(tmp_file, App::AWSProfile::get_profile['CloudFormation']['S3Bucket'], "#{bucket_path}#{template_filename}")
48
+ App::AWSCli::s3_upload(tmp_file, App::AWSProfile::get_profile['CloudFormation']['Uploads']['S3Bucket']['Name'], "#{bucket_path}#{template_filename}")
48
49
  # Return the S3 bucket URL.
49
50
  "#{get_s3_bucket_url}/#{template_filename}"
50
51
  end
@@ -54,13 +55,13 @@ module App
54
55
  def self.get_s3_bucket_url
55
56
  bucket_path = get_s3_bucket_path
56
57
  bucket_path = bucket_path == '' ? '' : "/#{bucket_path}"
57
- "https://#{App::AWSProfile::get_profile['CloudFormation']['S3Bucket']}.s3-#{App::AWSProfile::get_profile['CloudFormation']['S3BucketRegion']}.amazonaws.com#{bucket_path}"
58
+ "https://#{App::AWSProfile::get_profile['CloudFormation']['Uploads']['S3Bucket']['Name']}.s3-#{App::AWSProfile::get_profile['CloudFormation']['Uploads']['S3Bucket']['Region']}.amazonaws.com#{bucket_path}"
58
59
  end
59
60
 
60
61
  # Returns the S3 bucket path based on config parameters.
61
62
  # @return string
62
63
  def self.get_s3_bucket_path
63
- bucket_path = App::AWSProfile::get_profile['CloudFormation']['S3BucketPath']
64
+ bucket_path = App::AWSProfile::get_profile['CloudFormation']['Uploads']['S3Bucket']['Path']
64
65
  bucket_path.nil? || bucket_path.to_s.strip == '' ? '' : bucket_path
65
66
  end
66
67
 
@@ -48,8 +48,9 @@ module App
48
48
 
49
49
  # Validate CloudFormation data (if exists)
50
50
  if @@profile.has_key?(CLOUDFORMATION)
51
- cloudformation_template_path = @@profile[CLOUDFORMATION]['TemplatePath']
52
- s3_region = @@profile[CLOUDFORMATION]['S3BucketRegion']
51
+ # TODO AWX PROFILE - Must support S3.
52
+ cloudformation_template_path = @@profile[CLOUDFORMATION]['Templates']['Local']['Path']
53
+ s3_region = @@profile[CLOUDFORMATION]['Uploads']['S3Bucket']['Region']
53
54
  default_regions = @@profile[CLOUDFORMATION]['Defaults']['Regions']
54
55
  errors << "Path not found: #{Blufin::Terminal::format_invalid(cloudformation_template_path)}" unless Blufin::Files::path_exists(cloudformation_template_path)
55
56
  errors << "Invalid region: #{Blufin::Terminal::format_invalid(s3_region)}" unless App::AWS::VALID_REGIONS.include?(s3_region)
data/lib/awx.rb CHANGED
@@ -1,7 +1,7 @@
1
+ require 'blufin-lib'
1
2
  require 'columnist'
2
3
  require 'convoy'
3
4
  require 'yaml'
4
- require 'blufin-lib'
5
5
 
6
6
  require_relative 'version'
7
7
  require 'core/opt'
@@ -52,7 +52,8 @@ TEMPLATE
52
52
  awx_cloudformation.command :create, :aliases => [:c] do |awx_cloudformation_create|
53
53
  awx_cloudformation_create.summary 'Create stack'
54
54
  awx_cloudformation_create.options do |opts|
55
- if Blufin::Files::path_exists("#{File.expand_path(App::AWSProfile::get_profile['CloudFormation']['TemplatePath'])}/test")
55
+ # TODO AWX PROFILE - Must support S3.
56
+ if Blufin::Files::path_exists("#{File.expand_path(App::AWSProfile::get_profile['CloudFormation']['Templates']['Local']['Path'])}/test")
56
57
  opts.opt :test, 'Run through test-template.', :short => '-t', :long => '--test', :type => :boolean
57
58
  end
58
59
  opts.opt :test, "Re-run previous with cached values (if exists) \xe2\x80\x94 #{Blufin::Terminal::format_invalid('@NotImplemented')}", :short => '-R', :long => '--re-run', :type => :boolean
@@ -29,6 +29,8 @@ module AppCommand
29
29
  SPACER = '<<--Spacer-->>'
30
30
  CAPABILITIES = 'Capabilities'
31
31
  RETURN_VALUE = 'PjNkHK33EopWxCpzOQfuku3la'
32
+ EC2_USER_DATA = 'EC2UserData'
33
+ EC2_USER_DATA_FILE = 'cloud-config.yml'
32
34
 
33
35
  def execute
34
36
 
@@ -71,6 +73,9 @@ module AppCommand
71
73
 
72
74
  def opts_validate
73
75
 
76
+ # Windows is currently not supported, so bomb-out.
77
+ Blufin::Tools::os_not_supported([Blufin::Tools::OS_WINDOWS])
78
+
74
79
  # If Terminal window is smaller than 230, bomb-out.
75
80
  terminal_width_actual = Blufin::Terminal::get_terminal_width
76
81
  terminal_required_width = 227
@@ -94,6 +99,7 @@ module AppCommand
94
99
  ps = path_inner.split('/')
95
100
  template = ps[ps.length - 1]
96
101
  template_name = "#{category}/#{template}"
102
+ template_path = nil
97
103
  file_cloudformation = nil
98
104
  file_ruby = nil
99
105
  method_before_create = nil
@@ -110,10 +116,12 @@ module AppCommand
110
116
  single_serve = false
111
117
  deployment_stack = nil
112
118
  parameters = {}
119
+ parameters_no_sort = nil
113
120
  warnings_count = @warnings.length
114
121
  raise RuntimeError, "Template name must consist of [service]/[service-description] with exactly one slash, instead got: #{template_name}" if template_name.strip.split('/').length != 2
115
122
  Blufin::Files::get_files_in_dir(path_inner).each do |file|
116
- filename = Blufin::Files::extract_file_name(file)
123
+ filename = Blufin::Files::extract_file_name(file)
124
+ template_path = Blufin::Files::extract_path_name(file)
117
125
  if filename == 'template.yml'
118
126
  begin
119
127
  yml_data = YAML.load_file(File.expand_path(file))
@@ -126,7 +134,7 @@ module AppCommand
126
134
  @warnings << "\x1B[38;5;196m#{template_name}\x1B[38;5;240m \xe2\x80\x94 AWSTemplateFormatVersion: '2010-09-09' is missing." unless yml_data.has_key?('AWSTemplateFormatVersion')
127
135
  @warnings << "\x1B[38;5;196m#{template_name}\x1B[38;5;240m \xe2\x80\x94 This template either has no resources, invalid resources, or something else wrong with the resources." if !yml_data.has_key?('Resources') || yml_data['Resources'].nil? || !yml_data['Resources'].is_a?(Hash) || yml_data['Resources'].length == 0
128
136
  if yml_data.has_key?(PARAMETERS) && yml_data[PARAMETERS].is_a?(Hash) && yml_data[PARAMETERS].length > 0
129
- yml_data[PARAMETERS].each do |resource_name, data|
137
+ yml_data[PARAMETERS].each do |param_name, param_data|
130
138
  # Validate keys are in specific order.
131
139
  expected = {
132
140
  'Type' => true,
@@ -140,72 +148,77 @@ module AppCommand
140
148
  'MaxValue' => false,
141
149
  'ConstraintDescription' => false,
142
150
  }
143
- Blufin::Validate::assert_valid_keys(expected, data.keys, "#{file} \xe2\x86\x92 #{resource_name}")
144
- @warnings << "\x1B[38;5;196m#{template_name}\x1B[38;5;240m \xe2\x80\x94 Template has reserved parameter: #{Blufin::Terminal::format_invalid(resource_name)}" if [OPTION_STACK_NAME.downcase].concat(RESERVED_WORDS).include?(resource_name.downcase)
145
- parameters[resource_name] = data
146
- if @auto_fetch_resources.has_key?(resource_name)
147
- @warnings << "\x1B[38;5;196m#{template_name}\x1B[38;5;240m \xe2\x80\x94 Parameter: #{resource_name} cannot have default value: '#{data[DEFAULT]}' because it is a live look-up list (from AWS)." if data.keys.include?(DEFAULT)
151
+ Blufin::Validate::assert_valid_keys(expected, param_data.keys, "#{file} \xe2\x86\x92 #{param_name}")
152
+ @warnings << "\x1B[38;5;196m#{template_name}\x1B[38;5;240m \xe2\x80\x94 Template has reserved parameter: #{Blufin::Terminal::format_invalid(param_name)}" if [OPTION_STACK_NAME.downcase].concat(RESERVED_WORDS).include?(param_name.downcase)
153
+ parameters[param_name] = param_data
154
+ if @auto_fetch_resources.has_key?(param_name)
155
+ @warnings << "\x1B[38;5;196m#{template_name}\x1B[38;5;240m \xe2\x80\x94 Parameter: #{param_name} cannot have default value: '#{param_data[DEFAULT]}' because it is a live look-up list (from AWS)." if param_data.keys.include?(DEFAULT)
148
156
  end
149
157
  # Validate parameter type.
150
158
  valid_parameter_types = %w(String Number List<Number> CommaDelimitedList)
151
159
  valid_parameter_regexes = [/^AWS::[A-Za-z0-9]+::[A-Za-z0-9]+::[A-Za-z0-9]+$/, /^List<AWS::[A-Za-z0-9]+::[A-Za-z0-9]+::[A-Za-z0-9]+>$/]
152
- unless valid_parameter_types.include?(data['Type'])
160
+ unless valid_parameter_types.include?(param_data['Type'])
153
161
  matches_vpr = false
154
162
  valid_parameter_regexes.each do |vpr|
155
- matches_vpr = true if data['Type'] =~ vpr
163
+ matches_vpr = true if param_data['Type'] =~ vpr
156
164
  end
157
165
  if matches_vpr
158
166
  constraints = []
159
- constraints << 'AllowedPattern' if data.has_key?('AllowedPattern')
160
- constraints << 'MinLength' if data.has_key?('MinLength')
161
- constraints << 'MaxLength' if data.has_key?('MaxLength')
162
- constraints << 'MinValue' if data.has_key?('MinValue')
163
- constraints << 'MaxValue' if data.has_key?('MaxValue')
167
+ constraints << 'AllowedPattern' if param_data.has_key?('AllowedPattern')
168
+ constraints << 'MinLength' if param_data.has_key?('MinLength')
169
+ constraints << 'MaxLength' if param_data.has_key?('MaxLength')
170
+ constraints << 'MinValue' if param_data.has_key?('MinValue')
171
+ constraints << 'MaxValue' if param_data.has_key?('MaxValue')
164
172
  if constraints.any?
165
173
  @warnings << "\x1B[38;5;196m#{template_name}\x1B[38;5;240m \xe2\x80\x94 Invalid parameter constraint(s): #{Blufin::Terminal::format_invalid(constraints.join(','))}. These don't apply to AWS-Specific parameters."
166
174
  end
167
175
  else
168
- @warnings << "\x1B[38;5;196m#{template_name}\x1B[38;5;240m \xe2\x80\x94 Invalid parameter type: #{Blufin::Terminal::format_invalid(data['Type'])}"
176
+ @warnings << "\x1B[38;5;196m#{template_name}\x1B[38;5;240m \xe2\x80\x94 Invalid parameter type: #{Blufin::Terminal::format_invalid(param_data['Type'])}"
169
177
  end
170
178
  end
171
179
  # Can only have Max/MinLength if this is a String.
172
- if data.has_key?('MinLength') || data.has_key?('MaxLength') || data.has_key?('AllowedPattern')
173
- unless data['Type'] == 'String'
180
+ if param_data.has_key?('MinLength') || param_data.has_key?('MaxLength') || param_data.has_key?('AllowedPattern')
181
+ unless param_data['Type'] == 'String'
174
182
  constraints = []
175
- constraints << 'MinLength' if data.has_key?('MinLength')
176
- constraints << 'MaxLength' if data.has_key?('MaxLength')
177
- constraints << 'AllowedPattern' if data.has_key?('AllowedPattern')
183
+ constraints << 'MinLength' if param_data.has_key?('MinLength')
184
+ constraints << 'MaxLength' if param_data.has_key?('MaxLength')
185
+ constraints << 'AllowedPattern' if param_data.has_key?('AllowedPattern')
178
186
  @warnings << "\x1B[38;5;196m#{template_name}\x1B[38;5;240m \xe2\x80\x94 Invalid parameter constraint(s): #{Blufin::Terminal::format_invalid(constraints.join(','))}. To use these, type must be String."
179
187
  end
180
188
  end
181
189
  # Can only have Max/MinValue if this is a Number.
182
- if data.has_key?('MinValue') || data.has_key?('MaxValue')
183
- unless data['Type'] == 'Number'
190
+ if param_data.has_key?('MinValue') || param_data.has_key?('MaxValue')
191
+ unless param_data['Type'] == 'Number'
184
192
  constraints = []
185
- constraints << 'MinValue' if data.has_key?('MinValue')
186
- constraints << 'MaxValue' if data.has_key?('MaxValue')
193
+ constraints << 'MinValue' if param_data.has_key?('MinValue')
194
+ constraints << 'MaxValue' if param_data.has_key?('MaxValue')
187
195
  @warnings << "\x1B[38;5;196m#{template_name}\x1B[38;5;240m \xe2\x80\x94 Invalid parameter constraint(s): #{Blufin::Terminal::format_invalid(constraints.join(','))}. To use these, type must be Number."
188
196
  end
189
197
  end
190
198
  # If Allowed Values is set, certain conditions must apply.
191
- if data.has_key?('AllowedValues')
199
+ if param_data.has_key?('AllowedValues')
192
200
  %w(AllowedPattern MinLength MaxLength MinValue MaxValue).each do |invalid_key|
193
- if data.has_key?(invalid_key)
194
- @warnings << "\x1B[38;5;196m#{template_name}\x1B[38;5;240m \xe2\x80\x94 AllowedValues is set so cannot have: #{Blufin::Terminal::format_invalid(data['invalid_key'])}"
201
+ if param_data.has_key?(invalid_key)
202
+ @warnings << "\x1B[38;5;196m#{template_name}\x1B[38;5;240m \xe2\x80\x94 AllowedValues is set so cannot have: #{Blufin::Terminal::format_invalid(param_data['invalid_key'])}"
195
203
  end
196
204
  end
197
205
  # Must be Array.
198
- unless data['AllowedValues'].is_a?(Array)
199
- @warnings << "\x1B[38;5;196m#{template_name}\x1B[38;5;240m \xe2\x80\x94 AllowedValues must be Array, instead got: #{Blufin::Terminal::format_invalid(data['AllowedValues'].class)}"
206
+ unless param_data['AllowedValues'].is_a?(Array)
207
+ @warnings << "\x1B[38;5;196m#{template_name}\x1B[38;5;240m \xe2\x80\x94 AllowedValues must be Array, instead got: #{Blufin::Terminal::format_invalid(param_data['AllowedValues'].class)}"
200
208
  end
201
209
  end
210
+ # Validate EC2UserData parameter (make sure cloud-init.txt exists).
211
+ if param_name == EC2_USER_DATA
212
+ cloud_init_file = "#{template_path}/#{EC2_USER_DATA_FILE}"
213
+ @warnings << "\x1B[38;5;196m#{template_name}\x1B[38;5;240m \xe2\x80\x94 Template has #{Blufin::Terminal::format_highlight(EC2_USER_DATA)} parameter but no #{Blufin::Terminal::format_invalid(EC2_USER_DATA_FILE)} file." unless Blufin::Files::file_exists(cloud_init_file)
214
+ end
202
215
  end
203
216
  end
204
217
  # Validate description (if exists).
205
218
  if yml_data.has_key?(OPTION_DESCRIPTION)
206
219
  description = yml_data[OPTION_DESCRIPTION]
207
220
  # Validate replaceable value(s) exist.
208
- matches = description.scan(/{{[A-Za-z0-9]+}}/)
221
+ matches = description.scan(/{{[A-Za-z0-9]+}}/)
209
222
  matches.each do |match|
210
223
  match = match.gsub(/^{{/, '').gsub(/}}$/, '')
211
224
  unless parameters.keys.include?(match)
@@ -242,13 +255,14 @@ module AppCommand
242
255
  constant = constant.to_s
243
256
  expected_constants.delete(constant) if expected_constants.include?(constant)
244
257
  # Optional constants.
245
- intro = Template::INTRO if constant == 'INTRO'
246
- stack_name = Template::STACK_NAME if constant == 'STACK_NAME'
247
- projects = Template::PROJECTS if constant == 'PROJECTS'
248
- environments = Template::ENVIRONMENTS if constant == 'ENVIRONMENTS'
249
- regions = Template::REGIONS if constant == 'REGIONS'
250
- timeout = Template::TIMEOUT if constant == 'TIMEOUT'
251
- deployment_stack = Template::DEPLOYMENT_STACK if constant == 'DEPLOYMENT_STACK'
258
+ intro = Template::INTRO if constant == 'INTRO'
259
+ stack_name = Template::STACK_NAME if constant == 'STACK_NAME'
260
+ projects = Template::PROJECTS if constant == 'PROJECTS'
261
+ environments = Template::ENVIRONMENTS if constant == 'ENVIRONMENTS'
262
+ regions = Template::REGIONS if constant == 'REGIONS'
263
+ timeout = Template::TIMEOUT if constant == 'TIMEOUT'
264
+ deployment_stack = Template::DEPLOYMENT_STACK if constant == 'DEPLOYMENT_STACK'
265
+ parameters_no_sort = Template::PARAMETERS_NO_SORT if constant == 'PARAMETERS_NO_SORT'
252
266
  end
253
267
  # Validate stack name.
254
268
  if stack_name.nil? || stack_name.strip == ''
@@ -320,6 +334,16 @@ module AppCommand
320
334
  Object.send(:remove_const, :Template)
321
335
  end
322
336
  end
337
+ # Make sure no-sort parameters exist.
338
+ unless parameters_no_sort.nil?
339
+ if parameters_no_sort.is_a?(Array)
340
+ parameters_no_sort.each do |pns|
341
+ @warnings << "\x1B[38;5;196m#{template_name}\x1B[38;5;240m \xe2\x80\x94 Non-existent #{Blufin::Terminal::format_highlight('PARAMETERS_NO_SORT')} parameter: #{Blufin::Terminal::format_invalid(pns)}" unless parameters.keys.include?(pns)
342
+ end
343
+ else
344
+ @warnings << "\x1B[38;5;196m#{template_name}\x1B[38;5;240m \xe2\x80\x94 Expected constant #{Blufin::Terminal::format_highlight('PARAMETERS_NO_SORT')} to be Array, instead got: #{Blufin::Terminal::format_invalid(parameters_no_sort.class)}"
345
+ end
346
+ end
323
347
  @warnings << "\x1B[38;5;196m#{template_name}\x1B[38;5;240m \xe2\x80\x94 The #{Blufin::Terminal::format_highlight('template.yml')}\x1B[38;5;240m is missing, empty or invalid." if file_cloudformation.nil?
324
348
  @warnings << "\x1B[38;5;196m#{template_name}\x1B[38;5;240m \xe2\x80\x94 The #{Blufin::Terminal::format_highlight('template.rb')}\x1B[38;5;240m is missing, empty or invalid." if file_ruby.nil?
325
349
  @templates[category] = {} unless @templates.has_key?(category)
@@ -331,6 +355,7 @@ module AppCommand
331
355
  else
332
356
  @templates[category][template] = {
333
357
  :name => template,
358
+ :path => template_path,
334
359
  :broken => false,
335
360
  :file_cloudformation => file_cloudformation,
336
361
  :file_ruby => file_ruby,
@@ -339,6 +364,7 @@ module AppCommand
339
364
  :method_before_teardown => method_before_teardown,
340
365
  :method_after_teardown => method_after_teardown,
341
366
  :parameters => parameters,
367
+ :parameters_no_sort => parameters_no_sort,
342
368
  :intro => intro,
343
369
  :description => description,
344
370
  :stack_name => stack_name,
@@ -365,8 +391,8 @@ module AppCommand
365
391
 
366
392
  def opts_routing
367
393
 
368
- used_cache = true
369
- showing_tags = false
394
+ used_cache = true
395
+ showing_tags = false
370
396
 
371
397
  # Show prompt to select template.
372
398
  category, template, @template = select_template_prompt
@@ -430,10 +456,10 @@ module AppCommand
430
456
  capabilities_str = nil
431
457
 
432
458
  # Upload the template to S3.
433
- s3_url = App::AWSCloudFormation::upload_cloudformation_template(category, template, @params[OPTION_DESCRIPTION])
459
+ s3_url = App::AWSCloudFormation::upload_cloudformation_template(category, template, @params[OPTION_DESCRIPTION])
434
460
 
435
461
  # Validates the template.
436
- validation = App::AWSCli::cloudformation_stack_validate(@params[OPTION_REGION], s3_url)
462
+ validation = App::AWSCli::cloudformation_stack_validate(@params[OPTION_REGION], s3_url)
437
463
 
438
464
  # Check if validation output is JSON (and output appropriate format).
439
465
  begin
@@ -645,6 +671,10 @@ module AppCommand
645
671
  OPTION_DESCRIPTION => 'Should this stack be protected against accidental Termination?'
646
672
  }
647
673
  end
674
+ # If one of the parameters is EC2UserData, this parameter gets handled differently.
675
+ if @template[:parameters].is_a?(Hash) && @template[:parameters].has_key?(EC2_USER_DATA)
676
+ @template[:parameters][EC2_USER_DATA][OPTION_DESCRIPTION] = "#{EC2_USER_DATA_FILE} (base64 encoded & sent automatically)"
677
+ end
648
678
  # Get cached values (if exist and parameters haven't changed).
649
679
  # Even a one-character change in a description will invalidate the cache.
650
680
  cache_file = get_cache_file(category, template)
@@ -716,11 +746,11 @@ module AppCommand
716
746
  puts
717
747
  choices = []
718
748
  else
719
- choices = [{ value: 'y', text: 'Select this template' }]
720
- choices << { value: 'Y', text: "Select this template \x1B[38;5;198m(and apply cached values)\x1B[0m" } if @cache_valid
749
+ choices = [{value: 'y', text: 'Select this template'}]
750
+ choices << {value: 'Y', text: "Select this template \x1B[38;5;198m(and apply cached values)\x1B[0m"} if @cache_valid
721
751
  end
722
752
  # The prompt at the end of the intro.
723
- choices << { value: 'n', text: "\x1B[38;5;240m#{Blufin::Strings::RETURN_CHARACTER}\x1B[0m" }
753
+ choices << {value: 'n', text: "\x1B[38;5;240m#{Blufin::Strings::RETURN_CHARACTER}\x1B[0m"}
724
754
  choice = Blufin::Terminal::prompt_select('What would you like to do?', choices)
725
755
  case choice
726
756
  when 'y'
@@ -767,10 +797,14 @@ module AppCommand
767
797
  end
768
798
  help_text = 'Description (will be displayed in CloudFormation console).'
769
799
  return Blufin::Terminal::prompt_ask("Enter #{param_name}#{render_constraints(constraints)}", default: default, help: help_text)
800
+ elsif param_name == EC2_USER_DATA
801
+ puts Blufin::Terminal::display_prompt_text(EC2_USER_DATA, EC2_USER_DATA_FILE)
802
+ return "#{@template[:path]}/#{EC2_USER_DATA_FILE}"
770
803
  elsif param_name == OPTION_TIMEOUT
771
804
  return param_data[DEFAULT]
772
805
  elsif param_name == OPTION_TERM_PROTECT
773
- return Blufin::Terminal::prompt_yes?('Protect against accidental Termination?')
806
+ # Basically, by default Termination Protection is off (because most of the time your just testing and want to press Enter).
807
+ return !Blufin::Terminal::prompt_yes?("Allow accidental Termination? (type 'n' to enable Termination Protection)")
774
808
  elsif @auto_fetch_resources.has_key?(param_name)
775
809
  # Sort alphabetically.
776
810
  options = fetch_autocomplete_options(param_name, silent: true)
@@ -787,9 +821,11 @@ module AppCommand
787
821
  puts Blufin::Terminal::display_prompt_text(options_text, default_option)
788
822
  return default_option
789
823
  else
790
- # Sort alphabetically.
791
- options.uniq!
792
- options.sort!
824
+ unless @template[:parameters_no_sort].is_a?(Array) && @template[:parameters_no_sort].include?(param_name)
825
+ # Sort alphabetically.
826
+ options.uniq!
827
+ options.sort!
828
+ end
793
829
  # If we have a cached value, make that the first in the options list.
794
830
  options = move_default_option_to_top(options, param_name) if @cache.has_key?(param_name)
795
831
  puts Blufin::Terminal::display_prompt_help(param_data[OPTION_DESCRIPTION]) if param_data.has_key?(OPTION_DESCRIPTION)
@@ -921,6 +957,16 @@ module AppCommand
921
957
  def assemble_params(params)
922
958
  output = []
923
959
  params.each do |key, value|
960
+ if key == EC2_USER_DATA
961
+ b64_cmd = Blufin::Tools::value_based_on_os(mac: "openssl base64 -in #{value}", linux: "base64 -w0 #{value}")
962
+ result = Blufin::Terminal::command_capture(b64_cmd, nil, nil, nil)[0]
963
+ result = result.split("\n").join('')
964
+ output << {
965
+ 'ParameterKey' => key,
966
+ 'ParameterValue' => result
967
+ }
968
+ next
969
+ end
924
970
  unless RESERVED_WORDS.include?(key.downcase)
925
971
  output << {
926
972
  'ParameterKey' => key,
@@ -979,7 +1025,7 @@ module AppCommand
979
1025
  # Replaces current random stack suffix with another one.
980
1026
  # @return string
981
1027
  def replace_stack_suffix(current)
982
- current.gsub(/a[0-9a-z]{8}10w17[0-9a-z]{8}x/, random_stack_suffix)
1028
+ current.gsub(/a[0-9a-z]{16}10w17[0-9a-z]{16}x/, random_stack_suffix)
983
1029
  end
984
1030
 
985
1031
  end
data/lib/version.rb CHANGED
@@ -1 +1 @@
1
- AWX_VERSION = '0.4.2'
1
+ AWX_VERSION = '0.5.0'
@@ -22,14 +22,37 @@ mapping:
22
22
  CloudFormation:
23
23
  type: map
24
24
  mapping:
25
- S3Bucket:
26
- required: yes
27
- S3BucketPath:
25
+ Templates:
28
26
  required: yes
29
- S3BucketRegion:
30
- required: yes
31
- TemplatePath:
27
+ type: map
28
+ mapping:
29
+ Local:
30
+ type: map
31
+ mapping:
32
+ Path:
33
+ required: yes
34
+ S3Bucket:
35
+ type: map
36
+ mapping:
37
+ Name:
38
+ required: yes
39
+ Path:
40
+ required: yes
41
+ Region:
42
+ required: yes
43
+ Uploads:
32
44
  required: yes
45
+ type: map
46
+ mapping:
47
+ S3Bucket:
48
+ type: map
49
+ mapping:
50
+ Name:
51
+ required: yes
52
+ Path:
53
+ required: yes
54
+ Region:
55
+ required: yes
33
56
  Defaults:
34
57
  type: map
35
58
  required: yes
@@ -3,10 +3,18 @@ DynamoDBPath: <<-path/to/folder->>
3
3
  Profiles:
4
4
  - Profile: default
5
5
  CloudFormation:
6
- S3Bucket: <<-S3-bucket-name->>
7
- S3BucketPath: <<-S3-bucket-path/to/folder->>
8
- S3BucketRegion: <<-S3-bucket-region->>
9
- TemplatePath: <<-path/to/folder->>
6
+ Templates:
7
+ Local:
8
+ Path: <<-path->>
9
+ S3Bucket:
10
+ Name: <<-S3-bucket-name->>
11
+ Path: <<-S3-bucket-path->>
12
+ Region: <<-S3-bucket-region->>
13
+ Uploads:
14
+ S3Bucket:
15
+ Name: <<-S3-bucket-name->>
16
+ Path: <<-S3-bucket-path->>
17
+ Region: <<-S3-bucket-region->>
10
18
  Defaults:
11
19
  StackName: "{{CATEGORY}}-{{TEMPLATE}}-{{PROJECT}}-{{ENVIRONMENT}}-{{REGION}}-{{UUID}}"
12
20
  Timeout: 60
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: awx
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.2
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Albert Rannetsperger
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-08-09 00:00:00.000000000 Z
11
+ date: 2019-08-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: blufin-lib
@@ -122,7 +122,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
122
122
  requirements:
123
123
  - - ">="
124
124
  - !ruby/object:Gem::Version
125
- version: '2.0'
125
+ version: '2.3'
126
126
  required_rubygems_version: !ruby/object:Gem::Requirement
127
127
  requirements:
128
128
  - - ">="
@@ -130,7 +130,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
130
130
  version: '0'
131
131
  requirements: []
132
132
  rubyforge_project:
133
- rubygems_version: 2.6.12
133
+ rubygems_version: 2.5.1
134
134
  signing_key:
135
135
  specification_version: 4
136
136
  summary: An AWS-cli wrapper.