require 'sfn' module Sfn class Command # Export command class Export < Command include Sfn::CommandModule::Base include Sfn::Utils::ObjectStorage # Run export action def execute! raise NotImplementedError.new 'Implementation updates required' stack_name = name_args.first ui.info "#{ui.color('Stack Export:', :bold)} #{stack_name}" ui.confirm 'Perform export' stack = provider.stacks.get(stack_name) if(stack) export_options = Smash.new.tap do |opts| [:chef_popsicle, :chef_environment_parameter, :ignore_parameters].each do |key| opts[key] = config[key] unless config[key].nil? end end exporter = Sfn::Utils::StackExporter.new(stack, export_options) result = exporter.export outputs = [ write_to_file(result, stack), write_to_bucket(result, stack) ].compact if(outputs.empty?) ui.warn 'No persistent output location defined. Printing export:' ui.info _format_json(result) end ui.info "#{ui.color('Stack export', :bold)} (#{name_args.first}): #{ui.color('complete', :green)}" unless(outputs.empty?) outputs.each do |output| ui.info ui.color(" -> #{output}", :blue) end end else ui.fatal "Failed to discover requested stack: #{ui.color(stack_name, :red, :bold)}" exit -1 end end # Generate file name for stack export JSON contents # # @param stack [Miasma::Models::Orchestration::Stack] # @return [String] file name def export_file_name(stack) name = config[:file] if(name) if(name.respond_to?(:call)) name.call(stack) else name.to_s end else "#{stack.stack_name}-#{Time.now.to_i}.json" end end # Write stack export to local file # # @param payload [Hash] stack export payload # @param stack [Misama::Stack::Orchestration::Stack] # @return [String, NilClass] path to file def write_to_file(payload, stack) raise NotImplementedError if(config[:path]) full_path = File.join( config[:path], export_file_name(stack) ) _, bucket, path = full_path.split('/', 3) directory = provider.service_for(:storage, :provider => :local, :local_root => '/' ).directories.get(bucket) file_store(payload, path, directory) end end # Write stack export to remote bucket # # @param payload [Hash] stack export payload # @param stack [Miasma::Models::Orchestration::Stack] # @return [String, NilClass] remote bucket key def write_to_bucket(payload, stack) raise NotImplementedError if(bucket = config[:bucket]) key_path = File.join(*[ bucket_prefix(stack), export_file_name(stack) ].compact ) file_store(payload, key_path, provider.service_for(:storage).directories.get(bucket)) end end end end end