class BBC::Cosmos::Tools::Commands::Stack
Attributes
api[RW]
Public Class Methods
new(args = [], local_options = {}, thor_config = {})
click to toggle source
Calls superclass method
BBC::Cosmos::Tools::Commands::Base::new
# File lib/bbc/cosmos/tools/commands/stack.rb, line 19 def initialize(args = [], local_options = {}, thor_config = {}) super(args, local_options, thor_config) @l = -> data, component, environment do if data["Parameters"] && data["Parameters"]["ImageId"] data["Parameters"]["ImageId"]["Default"] = latest_ami_for(component, environment) end end @api = BBC::Cosmos::Tools::API.new(config.app["api"], options[:key_path]) end
Public Instance Methods
create(component = nil, main_stack = "true")
click to toggle source
# File lib/bbc/cosmos/tools/commands/stack.rb, line 79 def create(component = nil, main_stack = "true") say "#{banner}\n" components(options, component).each do |id| say get_key_value("\nComponent", id) type = Tools::Types::Factory.create(id, options, config) data = type.generate_data stack_data = Tools::Cloudformation::Generator.component_stack_details(config.resources, options, id) post_data = { "name_suffix" => options[:stack], "service_stack" => !main_stack.match(/(true|t|yes|y|1)$/i).nil?, "template" => data, "parameters" => Tools::Cloudformation::Generator.parameters(data, main_stack) } post_data["aws_account_id"] = stack_data["account_id"] unless stack_data["account_id"].nil? post_data["region"] = stack_data["region"] unless stack_data["region"].nil? response = api.post sprintf(config.app["stack_create_endpoint"], options[:env], id), JSON.pretty_generate(post_data) if response.success? say "Stack creation for component '#{component}' successfully started", :green else api_error(response, false) end end rescue Exception => e error e.message end
delete(component)
click to toggle source
# File lib/bbc/cosmos/tools/commands/stack.rb, line 199 def delete(component) say "#{banner(component)}\n" reply = yes?("Are you sure you want to delete the above stack?", :yellow) if reply || reply.nil? stack_name = "#{options[:env]}-#{component}-#{options[:stack]}" response = api.post sprintf(config.app["stack_delete"], options[:env], component, stack_name), JSON.pretty_generate({}) if response.success? say "Stack delete for component '#{component}' successfully started", :green else api_error response end else error "Action cancelled" end end
diff(component = nil)
click to toggle source
# File lib/bbc/cosmos/tools/commands/stack.rb, line 157 def diff(component = nil) components(options, component).each do |id| stack_name = "#{options[:env]}-#{id}-#{options[:stack]}" response = api.get sprintf(config.app["stack_template"], options[:env], id, stack_name) ### Copy-pasted: extract this logic out type = Tools::Types::Factory.create(id, options, config) data = type.generate_data.tap do |d| @l.call(d, id, options[:env]) end stack_meta = stack_data(component, stack_name, options[:env]) if data["Parameters"] data["Parameters"] = deep_merge( stack_parameters(stack_meta["parameters"], data["Parameters"]), data["Parameters"] ) params = Tools::Cloudformation::Generator.parameters(data, false) end post_data = { "template" => data, "parameters" => params || {} } ### if response.success? original_template = JSON.parse(response.body) removed, added = original_template.easy_diff(data) say JSON.pretty_generate(removed), :red say JSON.pretty_generate(added), :green else api_error(response, false) end end end
events(component = nil)
click to toggle source
# File lib/bbc/cosmos/tools/commands/stack.rb, line 223 def events(component = nil) say "#{banner}\n" components(options, component).each do |id| say get_key_value("\nComponent", id) stack_name = "#{options[:env]}-#{id}-#{options[:stack]}" response = api.get sprintf(config.app["stack_events"], options[:env], id, stack_name) if response.success? events = JSON.parse(response.body) data = events.slice(0, (options[:limit])).map do |event| event.split(" ") end print_table( build_table( ["Event type", "CF type", "Name", "Status"], data ) ) else api_error(response, false) end end end
generate(component)
click to toggle source
# File lib/bbc/cosmos/tools/commands/stack.rb, line 67 def generate(component) say "#{banner(component)}\n" type = Tools::Types::Factory.create(component, options, config) data = type.generate_data true say data, :white end
list(component = nil)
click to toggle source
# File lib/bbc/cosmos/tools/commands/stack.rb, line 33 def list(component = nil) say "#{banner}\n" components(options, component).each do |id| response = api.get sprintf(config.app["stacks"], options[:env], id) say get_key_value("\nComponent", id) if response.success? data = JSON.parse(response.body).map do |stack| [ stack["name"].split("-").last, stack["main_stack"], stack["updated_at"], stack["status"] ] end print_table( build_table( ["Name", "Main stack", "Updated at", "Status"], data ) ) else api_error(response, false) end end end
update(component = nil)
click to toggle source
# File lib/bbc/cosmos/tools/commands/stack.rb, line 114 def update(component = nil) say "#{banner}\n" components(options, component).each do |id| say get_key_value("\nComponent", id) stack_name = "#{options[:env]}-#{id}-#{options[:stack]}" type = Tools::Types::Factory.create(id, options, config) data = type.generate_data.tap do |d| @l.call(d, id, options[:env]) end stack_meta = stack_data(component, stack_name, options[:env]) if data["Parameters"] data["Parameters"] = deep_merge( stack_parameters(stack_meta["parameters"], data["Parameters"]), data["Parameters"] ) params = Tools::Cloudformation::Generator.parameters(data, false) end post_data = { "template" => data, "parameters" => params || {} } response = api.post sprintf(config.app["stack_update_endpoint"], options[:env], id, stack_name), JSON.pretty_generate(post_data) if response.success? say "Stack update for component '#{id}' successfully started", :green else api_error(response, false) end end end
Private Instance Methods
deep_merge(merger, mergee)
click to toggle source
# File lib/bbc/cosmos/tools/commands/stack.rb, line 272 def deep_merge(merger, mergee) merge_proc = proc { |_key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merge_proc) : v2 } merger.merge(mergee, &merge_proc) end
latest_ami_for(component, env = "int")
click to toggle source
# File lib/bbc/cosmos/tools/commands/stack.rb, line 266 def latest_ami_for(component, env = "int") response = api.get sprintf(config.app["deployments"], component, env) api_error response unless response.success? JSON.parse(response.body).first["image"]["ami_id"] end
stack_data(component, stack_name, env = "int")
click to toggle source
# File lib/bbc/cosmos/tools/commands/stack.rb, line 261 def stack_data(component, stack_name, env = "int") response = api.get sprintf(config.app["stack_details"], env, component, stack_name) JSON.parse(response.body) end
stack_parameters(stack_data, new_params)
click to toggle source
# File lib/bbc/cosmos/tools/commands/stack.rb, line 253 def stack_parameters(stack_data, new_params) stack_data.reduce({}) do |accum, (key, value)| accum.tap do |a| a[key] = { "Default" => value["value"] } if new_params.has_key? key end end end