require "sfn" module Sfn module MonkeyPatch module Stack # Google specific monkey patch implementations module Google # Helper module to allow nested stack behavior to function as expected # internally within sfn module PretendStack # disable reload def reload self end # disable template load def perform_template_load Smash.new end # only show resources associated to this stack def resources collection = Miasma::Models::Orchestration::Stack::Resources.new(self) collection.define_singleton_method(:perform_population) do valid = stack.sparkleish_template.fetch(:resources, {}).keys stack.custom[:resources].find_all { |r| valid.include?(r[:name]) }.map do |attrs| Miasma::Models::Orchestration::Stack::Resource.new(stack, attrs).valid_state end end collection end # Sub-stacks never provide events def events collection = Miasma::Models::Orchestration::Stack::Events.new(self) collection.define_singleton_method(:perform_population) { [] } collection end end # Return all stacks contained within this stack # # @param recurse [TrueClass, FalseClass] recurse to fetch _all_ stacks # @return [Array] def nested_stacks_google(recurse = true) my_template = sparkleish_template if my_template[:resources][name] my_template = my_template.get(:resources, name, :properties, :stack) end n_stacks = my_template[:resources].map do |s_name, content| if content[:type] == "sparkleformation.stack" n_stack = self.class.new(api) n_stack.extend PretendStack n_layout = custom.fetch(:layout, {}).fetch(:resources, []).detect { |r| r[:name] == name } n_layout = (n_layout || custom.fetch(:layout, {})).fetch(:resources, []).detect { |r| r[:name] == s_name } || Smash.new n_stack.load_data( :name => s_name, :id => s_name, :template => content.get(:properties, :stack), :outputs => n_layout.fetch("outputs", []).map { |o_val| Smash.new(:key => o_val[:name], :value => o_val["finalValue"]) }, :custom => { :resources => resources.all.map(&:attributes), :layout => n_layout, }, ).valid_state n_stack.data[:logical_id] = s_name n_stack.data[:parent_stack] = self n_stack end end.compact if recurse (n_stacks + n_stacks.map(&:nested_stacks)).flatten.compact else n_stacks end end # @return [Hash] restructured google template def sparkleish_template_google(*args) copy_template = template.to_smash deref = lambda do |template| result = template.to_smash (result.delete(:resources) || []).each do |t_resource| t_name = t_resource.delete(:name) if t_resource[:type].to_s.end_with?(".jinja") schema = copy_template.fetch(:config, :content, :imports, []).delete("#{t_resource[:type]}.schema") schema_content = copy_template.fetch(:imports, []).detect do |s_item| s_item[:name] == schema end if schema_content t_resource.set(:parameters, schema_content.get(:content, :properties)) end n_template = copy_template.fetch(:imports, []).detect do |s_item| s_item[:name] == t_resource[:type] end if n_template t_resource[:type] = "sparkleformation.stack" current_properties = t_resource.delete(:properties) t_resource.set(:properties, :parameters, current_properties) if current_properties t_resource.set(:properties, :stack, deref.call(n_template[:content])) end end result.set(:resources, t_name, t_resource) end result end s_template = deref.call(Smash.new(:resources => copy_template.get(:config, :content, :resources))) if s_template.empty? template.to_smash else layout = custom.fetch(:layout, {}).to_smash (layout.delete(:resources) || []).each do |l_resource| layout.set(:resources, l_resource.delete(:name), l_resource) end args.include?(:remove_wrapper) ? s_template.get(:resources, name, :properties, :stack) : s_template end end # @return [Hash] def root_parameters_google sparkleish_template.fetch(:resources, name, :properties, :parameters, Smash.new) end end end end end