lib/cfer/core/stack.rb in cfer-0.2.0 vs lib/cfer/core/stack.rb in cfer-0.3.0

- old
+ new

@@ -3,11 +3,16 @@ # Defines the structure of a CloudFormation stack class Stack < Cfer::Block include Cfer::Core include Cfer::Cfn + # The parameters strictly as passed via command line + attr_reader :input_parameters + + # The fully resolved parameters, including defaults and parameters fetched from an existing stack during an update attr_reader :parameters + attr_reader :options def converge! if @options[:client] @options[:client].converge self @@ -18,14 +23,10 @@ if @options[:client] @options[:client].tail self, &block end end - def resolve(val) - @options[:client] ? @options[:client].resolve(val) : val - end - def initialize(options = {}) self[:AWSTemplateFormatVersion] = '2010-09-09' self[:Description] = '' @options = options @@ -35,21 +36,27 @@ self[:Conditions] = {} self[:Resources] = {} self[:Outputs] = {} @parameters = HashWithIndifferentAccess.new + @input_parameters = HashWithIndifferentAccess.new + if options[:client] + begin + @parameters.merge! options[:client].fetch_parameters + rescue Cfer::Util::StackDoesNotExistError + Cfer::LOGGER.debug "Can't include current stack parameters because the stack doesn't exist yet." + end + end + if options[:parameters] options[:parameters].each do |key, val| - @parameters[key] = resolve(val) + @input_parameters[key] = @parameters[key] = val end end end - def pre_block - end - # Sets the description for this CloudFormation stack def description(desc) self[:Description] = desc end @@ -78,39 +85,16 @@ param = {} options.each do |key, v| k = key.to_s.camelize.to_sym param[k] = case k - when :AllowedValues - str_list = v.join(',') - verify_param(name, "Parameter #{name} must be one of: #{str_list}") { |input_val| str_list.include?(input_val) } - str_list when :AllowedPattern if v.class == Regexp - verify_param(name, "Parameter #{name} must match /#{v.source}/") { |input_val| v =~ input_val } v.source - else - verify_param(name, "Parameter #{name} must match /#{v}/") { |input_val| Regexp.new(v) =~ input_val } - v end - when :MaxLength - verify_param(name, "Parameter #{name} must have length <= #{v}") { |input_val| input_val.length <= v.to_i } - v - when :MinLength - verify_param(name, "Parameter #{name} must have length >= #{v}") { |input_val| input_val.length >= v.to_i } - v - when :MaxValue - verify_param(name, "Parameter #{name} must be <= #{v}") { |input_val| input_val.to_i <= v.to_i } - v - when :MinValue - verify_param(name, "Parameter #{name} must be >= #{v}") { |input_val| input_val.to_i >= v.to_i } - v - when :Description - Preconditions.check_argument(v.length <= 4000, "#{key} must be <= 4000 characters") - v when :Default - @parameters[name] ||= resolve(v) + @parameters[name] ||= v end param[k] ||= v end param[:Type] ||= 'String' self[:Parameters][name] = param @@ -146,21 +130,25 @@ # Adds an output to the CloudFormation stack. # @param name [String] The Logical ID of the output parameter # @param value [String] Value to return # @param options [Hash] Extra options for this output parameter - # @option options [String] :Description Informationa bout the value + # @option options [String] :Description Information about the value def output(name, value, options = {}) self[:Outputs][name] = options.merge('Value' => value) end # Renders the stack into a CloudFormation template. # @return [String] The final template def to_cfn to_h.to_json end + def client + @options[:client] || raise(Cfer::Util::CferError, "Stack has no associated client.") + end + # Includes template code from one or more files, and evals it in the context of this stack. # Filenames are relative to the file containing the invocation of this method. def include_template(*files) calling_file = caller.first.split(/:\d/,2).first dirname = File.dirname(calling_file) @@ -168,12 +156,12 @@ path = File.join(dirname, file) instance_eval(File.read(path), path) end end - private - def verify_param(param_name, err_msg) - raise Cfer::Util::CferError, err_msg if (@parameters[param_name] && !yield(@parameters[param_name].to_s)) + def lookup_output(stack, out) + client = @options[:client] || raise(Cfer::Util::CferError, "Can not fetch stack outputs without a client") + client.fetch_output(stack, out) end end end