Skip to content
This repository has been archived by the owner on Oct 19, 2023. It is now read-only.

Commit

Permalink
Merge pull request #268 from rapid7/issue-267
Browse files Browse the repository at this point in the history
Add support to mark all resources in a stack with the "Retain" Deletion Policy
  • Loading branch information
mburns-r7 authored Nov 20, 2017
2 parents 19bffee + 0a185f2 commit 03ba3e8
Show file tree
Hide file tree
Showing 6 changed files with 30 additions and 20 deletions.
2 changes: 1 addition & 1 deletion .rubocop_todo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ Metrics/AbcSize:
# Offense count: 34
# Configuration parameters: CountComments, ExcludedMethods.
Metrics/BlockLength:
Max: 136
Max: 140

# Offense count: 5
# Configuration parameters: CountComments.
Expand Down
8 changes: 7 additions & 1 deletion bin/convection
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ module Convection
option :'very-verbose', :type => :boolean, :aliases => '--vv', :desc => 'Show unchanged stacks', default: true
option :cloudfiles, :type => :array, :default => %w(Cloudfile)
option :delayed_output, :type => :boolean, :desc => 'Delay output until operation completion.', :default => false
option :retain, :type => :boolean, :desc => 'Retain stack resources, without deleteing.', :default => false
def converge(stack = nil)
@outputs = []
operation('converge', stack)
Expand Down Expand Up @@ -62,6 +63,7 @@ module Convection
option :'very-verbose', :type => :boolean, :aliases => '--vv', :desc => 'Show unchanged stacks'
option :cloudfiles, :type => :array, :default => %w(Cloudfile)
option :delayed_output, :type => :boolean, :desc => 'Delay output until operation completion.', :default => false
option :retain, :type => :boolean, :desc => 'Retain stack resources, without deleteing.', :default => false
def diff(stack = nil)
@outputs = []
operation('diff', stack)
Expand Down Expand Up @@ -133,7 +135,11 @@ module Convection
cloud_array[:cloud].configure(File.absolute_path(cloud_array[:cloudfile_path], @cwd))
cloud = cloud_array[:cloud]
region = cloud.cloudfile.region
cloud.send(task_name, stack, stack_group: options[:stack_group], stacks: options[:stacks], exclude_stacks: options[:exclude_stacks]) do |event, errors|
operation_kwargs = {
stack_group: options[:stack_group], stacks: options[:stacks],
exclude_stacks: options[:exclude_stacks], retain: options[:retain]
}
cloud.send(task_name, stack, operation_kwargs) do |event, errors|
if options[:cloudfiles].length > 1 && options[:delayed_output]
output << { event: event, errors: errors }
else
Expand Down
4 changes: 2 additions & 2 deletions lib/convection/control/cloud.rb
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ def converge(to_stack, options = {}, &block)

filter_deck(options, &block).each_value do |stack|
block.call(Model::Event.new(:converge, "Stack #{ stack.name }", :info)) if block
stack.apply(&block)
stack.apply(retain: options[:retain], &block)

emit_credential_error_and_exit!(stack, &block) if stack.credential_error?
if stack.error?
Expand Down Expand Up @@ -142,7 +142,7 @@ def diff(to_stack, options = {}, &block)
filter_deck(options, &block).each_value do |stack|
block.call(Model::Event.new(:compare, "Compare local state of stack #{ stack.name } (#{ stack.cloud_name }) with remote template", :info))

difference = stack.diff
difference = stack.diff(retain: options[:retain])
# Find errors during diff
emit_credential_error_and_exit!(stack, &block) if stack.credential_error?
if stack.error?
Expand Down
13 changes: 6 additions & 7 deletions lib/convection/control/stack.rb
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,6 @@ def initialize(name, template, options = {}, &block)
# clouds use this, for example, to create security groups early
# in the dependency tree to avoid the chicken-and-egg problem.
@template.execute

rescue Aws::Errors::ServiceError => e
@errors << e
end
Expand Down Expand Up @@ -279,8 +278,8 @@ def to_json(pretty = false)
# template (in CloudFormation) and the state of the rendered
# template (what *would* be converged).
# @see Convection::Model::Template#diff
def diff
@template.diff(@current_template)
def diff(retain: false)
@template.diff(@current_template, retain: retain)
end

# @return [Boolean] whether the Resources section of the rendered
Expand Down Expand Up @@ -322,17 +321,17 @@ def resource_dependent_changes?
#
# @param block [Proc] a configuration block to pass any
# {Convection::Model::Event}s to.
def apply(&block)
def apply(retain: false, &block)
request_options = @options.clone.tap do |o|
o[:template_body] = to_json
o[:template_body] = to_json(retain: retain)
o[:parameters] = cf_parameters
o[:capabilities] = capabilities
end

# Get the state of existence before creation
existing_stack = exist?
if existing_stack
if diff.empty? ## No Changes. Just get resources and move on
if diff(retain: retain).empty? ## No Changes. Just get resources and move on
block.call(Model::Event.new(:complete, "Stack #{ name } has no changes", :info)) if block
get_status
return
Expand Down Expand Up @@ -552,7 +551,7 @@ def get_events(pages = nil, stack_name = id)
collection << event
end

break if pages == 0
break if pages.zero?
end

@last_event_seen = collection.first.event_id unless collection.empty?
Expand Down
17 changes: 11 additions & 6 deletions lib/convection/model/template.rb
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ def execute
end
end

def render(stack_ = nil)
def render(stack_ = nil, retain: false)
## Instantiate a new template with the definition block and an other stack
return clone(stack_).render unless stack_.nil?

Expand All @@ -263,7 +263,12 @@ def render(stack_ = nil)
'Parameters' => parameters.map(&:render),
'Mappings' => mappings.map(&:render),
'Conditions' => conditions.map(&:render),
'Resources' => all_resources.map(&:render),
'Resources' => all_resources.map do |resource|
if retain && resource.deletion_policy.nil?
resource.deletion_policy('Retain')
end
resource.render
end,
'Outputs' => outputs.map(&:render),
'Metadata' => metadata.map(&:render)
}
Expand All @@ -275,12 +280,12 @@ def all_resources
end
end

def diff(other, stack_ = nil)
render(stack_).diff(other).map { |diff| Diff.new(diff[0], *diff[1]) }
def diff(other, stack_ = nil, retain: false)
render(stack_, retain: retain).diff(other).map { |diff| Diff.new(diff[0], *diff[1]) }
end

def to_json(stack_ = nil, pretty = false)
rendered_stack = render(stack_)
def to_json(stack_ = nil, pretty = false, retain: false)
rendered_stack = render(stack_, retain: retain)
validate(rendered_stack)
return JSON.generate(rendered_stack) unless pretty
JSON.pretty_generate(rendered_stack)
Expand Down
6 changes: 3 additions & 3 deletions lib/convection/model/template/resource.rb
Original file line number Diff line number Diff line change
Expand Up @@ -323,13 +323,13 @@ def depends_on(resource)
@depends_on << (resource.is_a?(Resource) ? resource.name : resource)
end

# rubocop:disable Style/TrivialAccessors
# We don't want to use an accessor (e.g. deletion_policy=) because
# this is a DSL method
def deletion_policy(deletion_policy)
def deletion_policy(deletion_policy = :unset_deletion_policy)
return @deletion_policy if deletion_policy == :unset_deletion_policy

@deletion_policy = deletion_policy
end
# rubocop:enable Style/TrivialAccessors

def reference
{
Expand Down

0 comments on commit 03ba3e8

Please sign in to comment.