Class: CfnFlow::CLI

Inherits:
Thor
  • Object
show all
Defined in:
lib/cfn_flow/cli.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.exit_on_failure?Boolean

Returns:

  • (Boolean)


4
5
6
# File 'lib/cfn_flow/cli.rb', line 4

def self.exit_on_failure?
  CfnFlow.exit_on_failure?
end

Instance Method Details

#delete(name) ⇒ Object



136
137
138
139
140
141
142
# File 'lib/cfn_flow/cli.rb', line 136

def delete(name)
  stack = find_stack_in_service(name)
  if options[:force] || yes?("Are you sure you want to shut down #{name}?", :red)
    stack.delete
    say "Deleted stack #{name}"
  end
end

#deploy(environment) ⇒ Object



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/cfn_flow/cli.rb', line 54

def deploy(environment)
  # Export environment as an env var so it can be interpolated in config
  ENV['CFN_FLOW_ENVIRONMENT'] = environment

  begin
    params = CfnFlow.stack_params(environment)
    stack = CfnFlow.cfn_resource.create_stack(params)
  rescue Aws::CloudFormation::Errors::ValidationError => e
    raise Thor::Error.new(e.message)
  end

  say "Launching stack #{stack.name}"

  # Invoke events
  say "Polling for events..."
  invoke :events, [stack.name], ['--poll']


  # Optionally cleanup other stacks in this environment
  if options[:cleanup]
    puts "Finding stacks to clean up"
    list_stacks_in_service.select {|s|
      s.name != stack.name && \
        s.tags.any? {|tag| tag.key == 'CfnFlowEnvironment' && tag.value == environment }
    }.map(&:name).each do |name|
      delete(name)
    end
  end
end

#events(name) ⇒ Object



117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/cfn_flow/cli.rb', line 117

def events(name)
  stack = find_stack_in_service(name)

  say EventPresenter.header unless options['no-header']
  EventPresenter.present(stack.events) {|p| say p }

  if options[:poll]
    # Display events until we're COMPLETE/FAILED
    delay = (ENV['CFN_FLOW_EVENT_POLL_INTERVAL'] || 2).to_i
    stack.wait_until(max_attempts: -1, delay: delay) do |s|
      EventPresenter.present(s.events) {|p| say p }
      # Wait until the stack status ends with _FAILED or _COMPLETE
      s.stack_status.match(/_(FAILED|COMPLETE)$/)
    end
  end
end

#list(environment = nil) ⇒ Object



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/cfn_flow/cli.rb', line 86

def list(environment=nil)
  stacks = list_stacks_in_service
  if environment
    stacks.select! do |stack|
      stack.tags.any? {|tag| tag.key == 'CfnFlowEnvironment' && tag.value == environment }
    end
  end

  return if stacks.empty?

  table_header = options['no-header'] ? [] : [['NAME',  'ENVIRONMENT', 'STATUS', 'CREATED']]
  table_data = stacks.map do |s|
    env_tag = s.tags.detect {|tag| tag.key == 'CfnFlowEnvironment'}
    env = env_tag ? env_tag.value : 'NONE'

    [ s.name, env, s.stack_status, s.creation_time ]
  end

  print_table(table_header + table_data)
end

#publish(*templates) ⇒ Object



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/cfn_flow/cli.rb', line 33

def publish(*templates)
  if templates.empty?
    raise Thor::RequiredArgumentMissingError.new('You must specify a template to publish')
  end

  validate(*templates)

  release = publish_release
  templates.each do |path|
    t = Template.new(path)

    say "Publishing #{t.local_path} to #{t.url(release)}"
    t.upload(release)
  end
end

#show(name) ⇒ Object



109
110
111
112
# File 'lib/cfn_flow/cli.rb', line 109

def show(name)
  data = find_stack_in_service(name).data.to_hash
  say options[:json] ? MultiJson.dump(data, pretty: true) : data.to_yaml
end

#validate(*templates) ⇒ Object



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/cfn_flow/cli.rb', line 12

def validate(*templates)

  if templates.empty?
    raise Thor::RequiredArgumentMissingError.new('You must specify a template to validate')
  end

  templates.map{|path| Template.new(path) }.each do |template|
    say "Validating #{template.local_path}... "
    template.validate!
    say 'valid.', :green
  end
rescue Aws::CloudFormation::Errors::ValidationError => e
  raise Thor::Error.new("Invalid template. Message: #{e.message}")
rescue CfnFlow::Template::Error => e
  raise Thor::Error.new("Error loading template. (#{e.class}) Message: #{e.message}")
end

#versionObject

Version command



146
# File 'lib/cfn_flow/cli.rb', line 146

desc "version", "Prints the version information"