steam_donkey 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +34 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +76 -0
- data/README.md +161 -0
- data/README.rdoc +6 -0
- data/Rakefile +54 -0
- data/bin/donkey +43 -0
- data/features/steam_donkey.feature +8 -0
- data/features/step_definitions/steam_donkey_steps.rb +6 -0
- data/features/support/env.rb +15 -0
- data/fixtures/templates/1/child1.template +2 -0
- data/fixtures/templates/child2.template +2 -0
- data/fixtures/templates/parent.template +2 -0
- data/lib/steam_donkey.rb +12 -0
- data/lib/steam_donkey/aws.rb +20 -0
- data/lib/steam_donkey/cli/output.rb +62 -0
- data/lib/steam_donkey/cloudformation/deploy_stack.rb +15 -0
- data/lib/steam_donkey/cloudformation/event_log.rb +108 -0
- data/lib/steam_donkey/cloudformation/exports_listing.rb +49 -0
- data/lib/steam_donkey/cloudformation/package.rb +100 -0
- data/lib/steam_donkey/cloudformation/stack_listing.rb +47 -0
- data/lib/steam_donkey/commands/cf.rb +102 -0
- data/lib/steam_donkey/commands/ec2.rb +31 -0
- data/lib/steam_donkey/config.rb +14 -0
- data/lib/steam_donkey/ec2/instance_listing.rb +54 -0
- data/lib/steam_donkey/resource_listing.rb +152 -0
- data/lib/steam_donkey/version.rb +3 -0
- data/steam_donkey.gemspec +28 -0
- data/steam_donkey.rdoc +5 -0
- data/test/default_test.rb +14 -0
- data/test/test_helper.rb +9 -0
- metadata +208 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
require 'aws-sdk'
|
|
2
|
+
|
|
3
|
+
def client_options(options)
|
|
4
|
+
result = {}
|
|
5
|
+
result[:profile] = options[:profile] if !options[:profile].nil?
|
|
6
|
+
result[:region] = options[:region] if !options[:region].nil?
|
|
7
|
+
result
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def cf_client(options)
|
|
11
|
+
Aws::CloudFormation::Client.new(client_options(options))
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def ec2_client(options)
|
|
15
|
+
Aws::EC2::Client.new(client_options(options))
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def s3_client(options)
|
|
19
|
+
Aws::S3::Client.new(client_options(options))
|
|
20
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
require 'command_line_reporter'
|
|
2
|
+
|
|
3
|
+
module SteamDonkey
|
|
4
|
+
module Cli
|
|
5
|
+
class Output
|
|
6
|
+
include CommandLineReporter
|
|
7
|
+
|
|
8
|
+
def initialize(render_headings, format)
|
|
9
|
+
@format = format
|
|
10
|
+
@render_headings = render_headings
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def render(headings, rows)
|
|
14
|
+
case @format
|
|
15
|
+
when 'pretty'
|
|
16
|
+
table do
|
|
17
|
+
row :header => true do
|
|
18
|
+
headings.each do |label|
|
|
19
|
+
column label, :width => max_width(rows, label)+ 2, :color => 'blue'
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
rows.each do |result|
|
|
24
|
+
row do
|
|
25
|
+
headings.each do |label|
|
|
26
|
+
value = result.detect { |f| f[:label] == label }[:value]
|
|
27
|
+
value = '-' if value.nil?
|
|
28
|
+
if value.is_a? Time
|
|
29
|
+
value = value.iso8601.to_s
|
|
30
|
+
else
|
|
31
|
+
value = '-' if value.methods.include? :empty? and value.empty?
|
|
32
|
+
end
|
|
33
|
+
column value
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
else
|
|
39
|
+
puts headings.join(',') if @render_headings
|
|
40
|
+
rows.each do |result|
|
|
41
|
+
puts result.map { |c| c[:value] }.join(',')
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def max_width(results, label)
|
|
47
|
+
width = results.map do |result|
|
|
48
|
+
value = result.detect { |f| f[:label] == label }[:value]
|
|
49
|
+
if value.nil?
|
|
50
|
+
0
|
|
51
|
+
elsif value.is_a? Time
|
|
52
|
+
value.iso8601.to_s.length
|
|
53
|
+
else
|
|
54
|
+
value.to_s.length
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
width << label.length
|
|
58
|
+
width.max
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
module SteamDonkey
|
|
2
|
+
module Cloudformation
|
|
3
|
+
class EventLog
|
|
4
|
+
|
|
5
|
+
def initialize(client, options)
|
|
6
|
+
@client = client
|
|
7
|
+
@options = options
|
|
8
|
+
@events_seen = []
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
BOLD = "[1m"
|
|
12
|
+
BLACK = "[30m"
|
|
13
|
+
RED = "[31m"
|
|
14
|
+
GREEN = "[32m"
|
|
15
|
+
YELLOW = "[33m"
|
|
16
|
+
BLUE = "[34m"
|
|
17
|
+
MAGENTA = "[35m"
|
|
18
|
+
CYAN = "[36m"
|
|
19
|
+
WHITE = "[37m"
|
|
20
|
+
|
|
21
|
+
def status_colors
|
|
22
|
+
{
|
|
23
|
+
"REVIEW_IN_PROGRESS" => "\033" + YELLOW,
|
|
24
|
+
|
|
25
|
+
"CREATE_IN_PROGRESS" => "\033" + YELLOW,
|
|
26
|
+
"CREATE_FAILED" => "\033" + RED,
|
|
27
|
+
"CREATE_COMPLETE" => "\033" + GREEN,
|
|
28
|
+
|
|
29
|
+
"DELETE_IN_PROGRESS" => "\033" + RED,
|
|
30
|
+
"DELETE_FAILED" => "\033" + RED,
|
|
31
|
+
"DELETE_COMPLETE" => "\033" + BOLD,
|
|
32
|
+
"DELETE_SKIPPED" => "\033" + BOLD,
|
|
33
|
+
|
|
34
|
+
"UPDATE_IN_PROGRESS" => "\033" + YELLOW,
|
|
35
|
+
"UPDATE_FAILED" => "\033" + RED,
|
|
36
|
+
"UPDATE_COMPLETE" => "\033" + GREEN,
|
|
37
|
+
"UPDATE_COMPLETE_CLEANUP_IN_PROGRESS" => "\033" + YELLOW,
|
|
38
|
+
|
|
39
|
+
"UPDATE_ROLLBACK_IN_PROGRESS" => "\033" + RED,
|
|
40
|
+
"UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS" => "\033" + RED,
|
|
41
|
+
"UPDATE_ROLLBACK_COMPLETE" => "\033" + GREEN
|
|
42
|
+
}
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def list
|
|
46
|
+
printf("%s%-20s %-44s %-26s %s%s\n",
|
|
47
|
+
"\033[1m",
|
|
48
|
+
"Timestamp",
|
|
49
|
+
"Status",
|
|
50
|
+
"Resource Type",
|
|
51
|
+
"Logical Id",
|
|
52
|
+
"\033[0m"
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
trap("SIGINT") { throw :ctrl_c }
|
|
56
|
+
catch :ctrl_c do
|
|
57
|
+
begin
|
|
58
|
+
events = []
|
|
59
|
+
stack_events.each do |response|
|
|
60
|
+
new_events(response).each do |event|
|
|
61
|
+
@events_seen << event.event_id
|
|
62
|
+
if after_desired_time(event)
|
|
63
|
+
events.unshift event
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
print_events(events)
|
|
68
|
+
sleep 5 if @options[:follow]
|
|
69
|
+
end while @options[:follow]
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def after_desired_time(event)
|
|
74
|
+
event.timestamp > @options[:since]
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def stack_name
|
|
78
|
+
@options[:stack_name]
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def stack_events
|
|
82
|
+
@client.describe_stack_events(:stack_name => stack_name)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def new_events(response)
|
|
86
|
+
response.stack_events.select(&self.method(:is_new?))
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def is_new?(event)
|
|
90
|
+
!@events_seen.include? event.event_id
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def print_events(events)
|
|
94
|
+
events.each do |event|
|
|
95
|
+
# puts "#{event.timestamp.iso8601}"
|
|
96
|
+
printf("%-20s %s%-44s%s %-26s %s\n",
|
|
97
|
+
event.timestamp.iso8601,
|
|
98
|
+
status_colors[event.resource_status], event.resource_status, "\033[0m",
|
|
99
|
+
event.resource_type,
|
|
100
|
+
event.logical_resource_id
|
|
101
|
+
)
|
|
102
|
+
end
|
|
103
|
+
STDOUT.flush
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
require 'aws-sdk'
|
|
2
|
+
|
|
3
|
+
module SteamDonkey
|
|
4
|
+
module Cloudformation
|
|
5
|
+
class ExportsListing
|
|
6
|
+
include SteamDonkey::ResourceListing
|
|
7
|
+
|
|
8
|
+
def initialize(client, options = {})
|
|
9
|
+
@client = client
|
|
10
|
+
init(options[:sort], options[:filters], options[:columns])
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def aliases
|
|
14
|
+
[
|
|
15
|
+
{ test: /^StackId$/i, value: 'ExportingStackId' }
|
|
16
|
+
]
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def search
|
|
20
|
+
result = []
|
|
21
|
+
exports = @client.list_exports
|
|
22
|
+
begin
|
|
23
|
+
last_token = exports.next_token
|
|
24
|
+
exports.exports.map do |export|
|
|
25
|
+
result << export
|
|
26
|
+
end
|
|
27
|
+
exports = @client.list_exports({ :next_token => exports.next_token })
|
|
28
|
+
end while last_token != exports.next_token
|
|
29
|
+
|
|
30
|
+
result
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def select_column(column, stack)
|
|
34
|
+
begin
|
|
35
|
+
c = column.clone
|
|
36
|
+
case column[:name]
|
|
37
|
+
when 'nil'
|
|
38
|
+
else
|
|
39
|
+
c[:value] = stack.send(column[:name].underscore)
|
|
40
|
+
end
|
|
41
|
+
c
|
|
42
|
+
rescue
|
|
43
|
+
raise "Unknown column #{column[:name]}"
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
require 'pathname'
|
|
2
|
+
|
|
3
|
+
module SteamDonkey
|
|
4
|
+
module Cloudformation
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Template
|
|
8
|
+
|
|
9
|
+
def initialize(dirname, filename)
|
|
10
|
+
@dirname = dirname
|
|
11
|
+
@filename = filename
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def path
|
|
15
|
+
File.join(@dirname, @filename)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def name
|
|
19
|
+
@filename
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def contains_child_templates?
|
|
23
|
+
!templates.empty?
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def templates
|
|
27
|
+
@child_references ||= scan_for_child_templates path
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def relative_path(root)
|
|
31
|
+
template_path = Pathname.new(path)
|
|
32
|
+
root_path = Pathname.new(root)
|
|
33
|
+
template_path.relative_path_from(root_path)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def packaged_template(bucket, prefix, root_path)
|
|
37
|
+
lines = []
|
|
38
|
+
File.readlines(path).each do |line|
|
|
39
|
+
new_line = line
|
|
40
|
+
line.scan /\.\/(.+)$/ do |child_path|
|
|
41
|
+
unless child_path.empty?
|
|
42
|
+
new_line = line.gsub(/\.\/.+$/, "https://s3-eu-west-1.amazonaws.com/#{bucket}/#{prefix}/#{child_path.first}")
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
lines << new_line
|
|
46
|
+
end
|
|
47
|
+
lines.join
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
private
|
|
51
|
+
|
|
52
|
+
def scan_for_child_templates(template)
|
|
53
|
+
child_templates = []
|
|
54
|
+
child_templates << self
|
|
55
|
+
File.readlines(template).each do |line|
|
|
56
|
+
line.scan /\.\/(.+)$/ do |child_path|
|
|
57
|
+
unless child_path.empty?
|
|
58
|
+
child = create_child_template(child_path.first)
|
|
59
|
+
child_templates << child
|
|
60
|
+
child_templates.push(*(child.templates))
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
child_templates.uniq
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def create_child_template(path)
|
|
68
|
+
child_path = File.join(@dirname, path)
|
|
69
|
+
Template.new File.dirname(child_path), File.basename(child_path)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
class Package
|
|
74
|
+
def initialize(client, quiet, dry_run)
|
|
75
|
+
@client = client
|
|
76
|
+
@quiet = quiet || false
|
|
77
|
+
@dry_run = dry_run || false
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def package(path, bucket, prefix)
|
|
81
|
+
template_dir = File.dirname(File.absolute_path(path))
|
|
82
|
+
template_name = File.basename(path)
|
|
83
|
+
|
|
84
|
+
root_template = Template.new(template_dir, template_name)
|
|
85
|
+
|
|
86
|
+
root_template.templates.each do |template|
|
|
87
|
+
puts "Uploading s3://#{bucket}/#{prefix}/#{template.relative_path(template_dir)}" unless @quiet
|
|
88
|
+
@client.put_object({
|
|
89
|
+
body: template.packaged_template(bucket, prefix, template_dir),
|
|
90
|
+
bucket: bucket,
|
|
91
|
+
key: "#{prefix}/#{template.relative_path(template_dir)}"
|
|
92
|
+
}) unless @dry_run
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
"https://s3-eu-west-1.amazonaws.com/#{bucket}/#{prefix}/#{root_template.name}"
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
require 'aws-sdk'
|
|
2
|
+
|
|
3
|
+
module SteamDonkey
|
|
4
|
+
module Cloudformation
|
|
5
|
+
class StackListing
|
|
6
|
+
include SteamDonkey::ResourceListing
|
|
7
|
+
|
|
8
|
+
def initialize(client, options = {})
|
|
9
|
+
@client = client
|
|
10
|
+
init(options[:sort], options[:filters], options[:columns])
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def aliases
|
|
14
|
+
[
|
|
15
|
+
{ test: /^Id$/i, value: 'StackId' },
|
|
16
|
+
{ test: /^Name$/i, value: 'StackName' },
|
|
17
|
+
{ test: /^Status/i, value: 'StackStatus' },
|
|
18
|
+
{ test: /^StatusReason/i, value: 'StackStatusReason' },
|
|
19
|
+
]
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def search
|
|
23
|
+
@client.list_stacks.map do |response|
|
|
24
|
+
response.stack_summaries.map do |stack|
|
|
25
|
+
stack
|
|
26
|
+
end
|
|
27
|
+
end.flatten
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def select_column(column, stack)
|
|
31
|
+
begin
|
|
32
|
+
c = column.clone
|
|
33
|
+
case column[:name]
|
|
34
|
+
when /^Tags\./i
|
|
35
|
+
c[:value] = find_tag(stack, column[:name].split('.').last)
|
|
36
|
+
else
|
|
37
|
+
c[:value] = stack.send(column[:name].underscore)
|
|
38
|
+
end
|
|
39
|
+
c
|
|
40
|
+
rescue
|
|
41
|
+
raise "Unknown column,#{column[:name]}"
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
require 'chronic'
|
|
2
|
+
|
|
3
|
+
desc 'Manage and view cloudformation stacks and templates'
|
|
4
|
+
command [:cf] do |cf|
|
|
5
|
+
|
|
6
|
+
cf.desc 'List cloudformation stacks'
|
|
7
|
+
cf.command [:list, :ls] do |list|
|
|
8
|
+
|
|
9
|
+
list.switch [:raw, :r], :default_value => false, :negatable => false, :desc => "Output unformatted, useful when piping results to other commands"
|
|
10
|
+
list.switch [:headings, :h], :default_value => false, :desc => "Toggle column headings"
|
|
11
|
+
|
|
12
|
+
list.flag [:filters, :f], :default_value => 'Status=!/DELETE_COMPLETE/', :desc => ""
|
|
13
|
+
list.flag [:columns, :c], :default_value => 'Name,CreationTime,Status', :desc => ""
|
|
14
|
+
list.flag [:sort, :s], :default_value => 'CreationTime=desc,Name', :desc => ""
|
|
15
|
+
|
|
16
|
+
list.flag [:output, :o], :default_value => 'pretty', :must_match => { "pretty" => :pretty, "raw" => :raw }
|
|
17
|
+
|
|
18
|
+
list.action do |global_options, options, args|
|
|
19
|
+
listing_options = {
|
|
20
|
+
:filters => options[:filters],
|
|
21
|
+
:columns => options[:columns],
|
|
22
|
+
:sort => options[:sort]
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
stack_listing = SteamDonkey::Cloudformation::StackListing.new(cf_client(global_options), listing_options)
|
|
26
|
+
|
|
27
|
+
output = SteamDonkey::Cli::Output.new true, options[:output]
|
|
28
|
+
output.render stack_listing.column_labels, stack_listing.list
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
cf.desc 'List stack events'
|
|
33
|
+
cf.command [:events] do |events|
|
|
34
|
+
|
|
35
|
+
events.flag ['stack-name', :s], :arg_name => 'STACK_NAME', :required => true, :desc => "Stack name"
|
|
36
|
+
events.switch ['follow', :f], :default_value => false, :negatable => false
|
|
37
|
+
|
|
38
|
+
events.action do |global_options, options, args|
|
|
39
|
+
list_options = {
|
|
40
|
+
:follow => options[:follow],
|
|
41
|
+
:stack_name => options[:'stack-name'],
|
|
42
|
+
:since => Chronic.parse("2 years ago")
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
event_log = SteamDonkey::Cloudformation::EventLog.new(cf_client(global_options), list_options)
|
|
46
|
+
event_log.list
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
cf.desc 'List cloudformation exports'
|
|
51
|
+
cf.command [:exports] do |exports|
|
|
52
|
+
|
|
53
|
+
exports.switch [:raw, :r], :default_value => false, :negatable => false, :desc => "Output unformatted, useful when piping results to other commands"
|
|
54
|
+
exports.switch [:headings, :h], :default_value => false, :desc => "Toggle column headings"
|
|
55
|
+
|
|
56
|
+
exports.flag [:filters, :f], :default_value => '', :desc => ""
|
|
57
|
+
exports.flag [:columns, :c], :default_value => 'Name,Value', :desc => ""
|
|
58
|
+
exports.flag [:sort, :s], :default_value => 'Name', :desc => ""
|
|
59
|
+
|
|
60
|
+
exports.flag [:output, :o], :default_value => 'pretty', :must_match => { "pretty" => :pretty, "raw" => :raw }
|
|
61
|
+
|
|
62
|
+
exports.action do |global_options, options, args|
|
|
63
|
+
listing_options = {
|
|
64
|
+
:filters => options[:filters],
|
|
65
|
+
:columns => options[:columns],
|
|
66
|
+
:sort => options[:sort]
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
exports_listing = SteamDonkey::Cloudformation::ExportsListing.new(cf_client(global_options), listing_options)
|
|
70
|
+
|
|
71
|
+
output = SteamDonkey::Cli::Output.new true, options[:output]
|
|
72
|
+
output.render exports_listing.column_labels, exports_listing.list
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
cf.desc 'Package cloudformation template and upload to S3'
|
|
77
|
+
cf.command [:package] do |p|
|
|
78
|
+
|
|
79
|
+
p.flag [:template, :t], :required => true, :desc => "Path to template to package and upload"
|
|
80
|
+
p.flag [:bucket, :b], :desc => "Name of the S3 bucket to upload packaged templates to"
|
|
81
|
+
p.flag [:prefix, :p], :desc => "Prefix to prepend to uploaded templates"
|
|
82
|
+
p.switch ['launch-console', :l], :default_value => false, :negatable => false, :desc => "Launch CloudFormation console with uploaded template"
|
|
83
|
+
p.switch ['dry-run', :d], :default_value => false, :negatable => false
|
|
84
|
+
p.switch [:quiet, :q], :default_value => false, :negatable => false
|
|
85
|
+
|
|
86
|
+
p.action do |global_options, options, args|
|
|
87
|
+
bucket_name = options[:bucket] || global_options[:rc][:cloudformation][:package]["bucketName"]
|
|
88
|
+
bucket_path_prefix = options[:prefix] || global_options[:rc][:cloudformation][:package]["bucketPathPrefix"]
|
|
89
|
+
|
|
90
|
+
package = SteamDonkey::Cloudformation::Package.new(s3_client(global_options), options[:quiet], options['dry-run'])
|
|
91
|
+
|
|
92
|
+
template_url = package.package options[:template], bucket_name, bucket_path_prefix
|
|
93
|
+
|
|
94
|
+
puts template_url unless options[:quiet]
|
|
95
|
+
|
|
96
|
+
if options['launch-console']
|
|
97
|
+
`open https://console.aws.amazon.com/cloudformation/home?region=eu-west-1#/stacks/new?templateURL=#{template_url}`
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|