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