lib/sfn/command_module/stack.rb in sfn-3.0.8 vs lib/sfn/command_module/stack.rb in sfn-3.0.10
- old
+ new
@@ -97,20 +97,16 @@
def execute_apply_stack(provider_stack, receiver_stack, mappings)
receiver_stack.apply_stack(provider_stack, :mapping => mappings)
true
end
- # Prompt for parameter values and store result
+ # Generate name prefix for config parameter based on location and
+ # extract template parameters
#
- # @param sparkle [SparkleFormation, Hash]
- # @param opts [Hash]
- # @option opts [Hash] :current_parameters current stack parameter values
- # @option opts [Miasma::Models::Orchestration::Stack] :stack existing stack
- # @return [Hash]
- def populate_parameters!(sparkle, opts={})
- current_parameters = opts.fetch(:current_parameters, {})
- current_stack = opts[:stack]
+ # @param sparkle [SparkleFormation, Hash] template instance
+ # @return [Array<Array<String>, Smash>] prefix value, parameters
+ def prefix_parameters_setup(sparkle)
if(sparkle.is_a?(SparkleFormation))
parameter_prefix = sparkle.root? ? [] : (sparkle.root_path - [sparkle.root]).map do |s|
Bogo::Utility.camel(s.name)
end
stack_parameters = sparkle.compile.parameters
@@ -119,83 +115,139 @@
parameter_prefix = []
stack_parameters = TEMPLATE_PARAMETER_LOCATIONS.map do |loc_key|
sparkle[loc_key]
end.compact.first || Smash.new
end
- unless(stack_parameters.empty?)
- if(config.get(:parameter).is_a?(Array))
- config[:parameter] = Smash[
- *config.get(:parameter).map(&:to_a).flatten
- ]
+ [parameter_prefix, stack_parameters]
+ end
+
+ # Format config defined parameters to ensure expected layout
+ def format_config_parameters!
+ if(config.get(:parameter).is_a?(Array))
+ config[:parameter] = Smash[
+ *config.get(:parameter).map(&:to_a).flatten
+ ]
+ end
+ if(config.get(:parameters))
+ config.set(:parameters,
+ config.get(:parameters).merge(config.fetch(:parameter, Smash.new))
+ )
+ else
+ config.set(:parameters, config.fetch(:parameter, Smash.new))
+ end
+ end
+
+ # Determine correct configuration parameter key
+ #
+ # @param parameter_prefix [Array<String>] nesting prefix names
+ # @param parameter_name [String] parameter name
+ # @return [Array<String>] [expected_template_key, configuration_used_key]
+ def locate_config_parameter_key(parameter_prefix, parameter_name)
+ check_name = parameter_name.downcase.tr('-_', '')
+ check_prefix = parameter_prefix.map{|i| i.downcase.tr('-_', '') }
+ key_match = config[:parameters].keys.detect do |cp_key|
+ cp_key = cp_key.to_s.downcase.split('__').map{|i| i.tr('-_', '') }.join('__')
+ cp_key.start_with?(check_prefix.join('__')) &&
+ cp_key.split('__').last == check_name
+ end
+ actual_key = (parameter_prefix + [parameter_name]).compact.join('__')
+ if(key_match)
+ config[:parameters][actual_key] = config[:parameters].delete(key_match)
+ end
+ actual_key
+ end
+
+ # Populate stack parameter value via user interaction
+ #
+ # @param sparkle [SparkleFormation, Hash] template
+ # @param ns_key [String] configuration parameter key name
+ # @param param_name [String] template parameter name
+ # @param param_value [Hash] template parameter value
+ # @param current_parameters [Hash] currently set stack parameters
+ # @param param_banner [TrueClass, FalseClass] parameter banner has been printed
+ # @return [TrueClass, FalseClass] parameter banner has been printed
+ def set_parameter(sparkle, ns_key, param_name, param_value, current_parameters, param_banner)
+ valid = false
+ attempt = 0
+ if(!valid && !param_banner)
+ if(sparkle.is_a?(SparkleFormation))
+ ui.info "#{ui.color('Stack runtime parameters:', :bold)} - template: #{ui.color(sparkle.root_path.map(&:name).map(&:to_s).join(' > '), :green, :bold)}"
+ else
+ ui.info ui.color('Stack runtime parameters:', :bold)
end
- if(config.get(:parameters))
- config.set(:parameters,
- config.get(:parameters).merge(config.fetch(:parameter, Smash.new))
+ param_banner = true
+ end
+ until(valid)
+ attempt += 1
+ default = config[:parameters].fetch(
+ ns_key, current_parameters.fetch(
+ param_name, TEMPLATE_PARAMETER_DEFAULTS.map{|loc_key| param_value[loc_key]}.compact.first
)
+ )
+ if(config[:interactive_parameters])
+ answer = ui.ask_question("#{param_name.split(/([A-Z]+[^A-Z]*)/).find_all{|s|!s.empty?}.join(' ')}", :default => default)
else
- config.set(:parameters, config.fetch(:parameter, Smash.new))
+ answer = default
end
+ validation = validate_parameter(answer, param_value)
+ if(validation == true)
+ config[:parameters][ns_key] = answer
+ valid = true
+ else
+ validation.each do |validation_error|
+ ui.error validation_error.last
+ end
+ end
+ if(attempt > MAX_PARAMETER_ATTEMPTS)
+ ui.fatal 'Failed to receive allowed parameter!'
+ exit 1
+ end
+ end
+ param_banner
+ end
+
+ # Prompt for parameter values and store result
+ #
+ # @param sparkle [SparkleFormation, Hash]
+ # @param opts [Hash]
+ # @option opts [Hash] :current_parameters current stack parameter values
+ # @option opts [Miasma::Models::Orchestration::Stack] :stack existing stack
+ # @return [Hash]
+ def populate_parameters!(sparkle, opts={})
+ current_parameters = opts.fetch(:current_parameters, {})
+ current_stack = opts[:stack]
+ parameter_prefix, stack_parameters = prefix_parameters_setup(sparkle)
+ unless(stack_parameters.empty?)
+ format_config_parameters!
param_banner = false
- stack_parameters.each do |k,v|
- ns_k = (parameter_prefix + [k]).compact.join('__')
- next if config[:parameters][ns_k]
- valid = false
+ stack_parameters.each do |param_name, param_value|
+ ns_key = locate_config_parameter_key(parameter_prefix, param_name)
# When parameter is a hash type, it is being set via
# intrinsic function and we don't modify
- if(function_set_parameter?(current_parameters[k]))
+ if(function_set_parameter?(current_parameters[param_name]))
if(current_stack)
- enable_set = validate_stack_parameter(current_stack, k, ns_k, current_parameters[k])
+ enable_set = validate_stack_parameter(current_stack, param_name, ns_key, current_parameters[param_name])
else
enable_set = true
end
if(enable_set)
# NOTE: direct set dumps the stack (nfi). Smash will
# auto dup it, and works, so yay i guess.
- config[:parameters][ns_k] = current_parameters[k].is_a?(Hash) ? Smash.new(current_parameters[k]) : current_parameters[k].dup
+ config[:parameters][ns_key] = current_parameters[param_name].is_a?(Hash) ?
+ Smash.new(current_parameters[param_name]) :
+ current_parameters[param_name].dup
valid = true
end
else
if(current_stack && current_stack.data[:parent_stack])
- use_expected = validate_stack_parameter(current_stack, k, ns_k, current_parameters[k])
+ use_expected = validate_stack_parameter(current_stack, param_name, ns_key, current_parameters[param_name])
unless(use_expected)
- current_parameters[k] = current_stack.parameters[k]
+ current_parameters[param_name] = current_stack.parameters[param_name]
end
end
end
- attempt = 0
- if(!valid && !param_banner)
- if(sparkle.is_a?(SparkleFormation))
- ui.info "#{ui.color('Stack runtime parameters:', :bold)} - template: #{ui.color(sparkle.root_path.map(&:name).map(&:to_s).join(' > '), :green, :bold)}"
- else
- ui.info ui.color('Stack runtime parameters:', :bold)
- end
- param_banner = true
- end
- until(valid)
- attempt += 1
- default = config[:parameters].fetch(
- ns_k, current_parameters.fetch(
- k, TEMPLATE_PARAMETER_DEFAULTS.map{|loc_key| v[loc_key]}.compact.first
- )
- )
- if(config[:interactive_parameters])
- answer = ui.ask_question("#{k.split(/([A-Z]+[^A-Z]*)/).find_all{|s|!s.empty?}.join(' ')}", :default => default)
- else
- answer = default
- end
- validation = validate_parameter(answer, v)
- if(validation == true)
- config[:parameters][ns_k] = answer
- valid = true
- else
- validation.each do |validation_error|
- ui.error validation_error.last
- end
- end
- if(attempt > MAX_PARAMETER_ATTEMPTS)
- ui.fatal 'Failed to receive allowed parameter!'
- exit 1
- end
+ unless(valid)
+ param_banner = set_parameter(sparkle, ns_key, param_name, param_value, current_parameters, param_banner)
end
end
end
Smash[
config.fetch(:parameters, {}).map do |k,v|