Class: Jets::Cfn::Ship
Constant Summary
Constants included
from Timing
Timing::RECORD_LOG_PATH
Instance Method Summary
collapse
#cfn, #lambda, #logs, #s3, #s3_resource, #sns, #sts
#stack_exists?, #stack_in_progress?
Methods included from Timing
clear, #record_data, #record_log, report
Constructor Details
#initialize(options) ⇒ Ship
Returns a new instance of Ship.
Instance Method Details
#capabilities ⇒ Object
135
136
137
138
139
140
141
|
# File 'lib/jets/cfn/ship.rb', line 135
def capabilities
["CAPABILITY_IAM", "CAPABILITY_NAMED_IAM"] end
|
#command_with_iam(capabilities) ⇒ Object
131
132
133
|
# File 'lib/jets/cfn/ship.rb', line 131
def command_with_iam(capabilities)
"#{File.basename($0)} #{ARGV.join(' ')} --capabilities #{capabilities}"
end
|
#create_stack ⇒ Object
48
49
50
51
|
# File 'lib/jets/cfn/ship.rb', line 48
def create_stack
cfn.create_stack(stack_options)
end
|
#prompt_for_iam(capabilities) ⇒ Object
123
124
125
126
127
128
129
|
# File 'lib/jets/cfn/ship.rb', line 123
def prompt_for_iam(capabilities)
puts "This stack will create IAM resources. Please approve to run the command again with #{capabilities} capabilities."
puts " #{command_with_iam(capabilities)}"
puts "Please confirm (y/n)"
$stdin.gets end
|
#run ⇒ Object
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
# File 'lib/jets/cfn/ship.rb', line 12
def run
upload_to_s3 if @options[:stack_type] == :full
stack_in_progress?(@parent_stack_name)
puts "Deploying CloudFormation stack with jets app!"
begin
save_stack
rescue Aws::CloudFormation::Errors::InsufficientCapabilitiesException => e
capabilities = e.message.match(/\[(.*)\]/)[1]
confirm = prompt_for_iam(capabilities)
if confirm =~ /^y/
@options.merge!(capabilities: [capabilities])
puts "Re-running: #{command_with_iam(capabilities).colorize(:green)}"
retry
else
puts "Exited"
exit 1
end
end
wait_for_stack
prewarm
show_api_endpoint
end
|
#save_stack ⇒ Object
40
41
42
43
44
45
46
|
# File 'lib/jets/cfn/ship.rb', line 40
def save_stack
if stack_exists?(@parent_stack_name)
update_stack
else
create_stack
end
end
|
#show_api_endpoint ⇒ Object
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
# File 'lib/jets/cfn/ship.rb', line 97
def show_api_endpoint
return unless @options[:stack_type] == :full return if Jets::Router.routes.empty?
resp, status = stack_status
return if status.include?("ROLLBACK")
resp = cfn.describe_stack_resources(stack_name: @parent_stack_name)
resources = resp.stack_resources
api_gateway = resources.find { |resource| resource.logical_resource_id == "ApiGateway" }
stack_id = api_gateway["physical_resource_id"]
resp = cfn.describe_stacks(stack_name: stack_id)
stack = resp["stacks"].first
output = stack["outputs"].find { |o| o["output_key"] == "RestApiUrl" }
endpoint = output["output_value"]
puts "API Gateway Endpoint: #{endpoint}"
end
|
#stack_options ⇒ Object
options common to both create_stack and update_stack
65
66
67
68
69
70
71
72
|
# File 'lib/jets/cfn/ship.rb', line 65
def stack_options
{
stack_name: @parent_stack_name,
template_body: IO.read(@template_path),
capabilities: capabilities, }
end
|
#stack_status ⇒ Object
117
118
119
120
121
|
# File 'lib/jets/cfn/ship.rb', line 117
def stack_status
resp = cfn.describe_stacks(stack_name: @parent_stack_name)
status = resp.stacks[0].stack_status
[resp, status]
end
|
#update_stack ⇒ Object
54
55
56
57
58
59
60
61
|
# File 'lib/jets/cfn/ship.rb', line 54
def update_stack
begin
cfn.update_stack(stack_options)
rescue Aws::CloudFormation::Errors::ValidationError => e
puts "ERROR: #{e.message}".red
true end
end
|
#upload_to_s3 ⇒ Object
Upload both code and child templates to s3
144
145
146
147
148
149
|
# File 'lib/jets/cfn/ship.rb', line 144
def upload_to_s3
raise "Did not specify @options[:s3_bucket] #{@options[:s3_bucket].inspect}" unless @options[:s3_bucket]
uploader = Upload.new(@options[:s3_bucket])
uploader.upload
end
|
#wait_for_stack ⇒ Object
check for /(_COMPLETE|_FAILED)$/ status
75
76
77
|
# File 'lib/jets/cfn/ship.rb', line 75
def wait_for_stack
Jets::Cfn::Status.new(@options).wait
end
|