bbc-cosmos-tools 0.5.2 → 0.6.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 +4 -4
- data/Gemfile +1 -1
- data/bbc-cosmos-tools.gemspec +5 -4
- data/bin/bbc-cosmos-tools +3 -3
- data/lib/bbc/cosmos/tools/api.rb +6 -8
- data/lib/bbc/cosmos/tools/app.rb +4 -4
- data/lib/bbc/cosmos/tools/cloudformation/generator.rb +20 -23
- data/lib/bbc/cosmos/tools/commands/base.rb +8 -10
- data/lib/bbc/cosmos/tools/commands/component.rb +79 -19
- data/lib/bbc/cosmos/tools/commands/config.rb +24 -33
- data/lib/bbc/cosmos/tools/commands/release.rb +100 -112
- data/lib/bbc/cosmos/tools/commands/stack.rb +60 -72
- data/lib/bbc/cosmos/tools/config.rb +19 -22
- data/lib/bbc/cosmos/tools/cosmos_configuration.rb +4 -6
- data/lib/bbc/cosmos/tools/types/base_type.rb +6 -7
- data/lib/bbc/cosmos/tools/types/cfndsl.rb +2 -3
- data/lib/bbc/cosmos/tools/version.rb +1 -1
- metadata +19 -6
@@ -1,8 +1,8 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
1
|
+
require "json"
|
2
|
+
require "pathname"
|
3
|
+
require "bbc/cosmos/tools/commands/base"
|
4
|
+
require "bbc/cosmos/tools/cosmos_configuration"
|
5
|
+
require "bbc/cosmos/tools/api"
|
6
6
|
|
7
7
|
module BBC
|
8
8
|
module Cosmos
|
@@ -15,168 +15,156 @@ module BBC
|
|
15
15
|
|
16
16
|
def initialize(args = [], local_options = {}, thor_config = {})
|
17
17
|
super(args, local_options, thor_config)
|
18
|
-
@api = BBC::Cosmos::Tools::API.new(config.app[
|
18
|
+
@api = BBC::Cosmos::Tools::API.new(config.app["api"], options[:key_path])
|
19
19
|
end
|
20
20
|
|
21
21
|
method_option :tags, :type => :array, :default => nil
|
22
22
|
desc "release list [COMPONENT = nil]", "Lists releases for a component"
|
23
23
|
def list(component = nil)
|
24
|
-
|
24
|
+
say banner
|
25
25
|
|
26
|
-
|
26
|
+
components(options, component).each do |id|
|
27
|
+
response = api.get sprintf(config.app["release"], id)
|
28
|
+
say get_key_value("\nComponent", id)
|
27
29
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
if response.success?
|
34
|
-
data = []
|
35
|
-
JSON.parse(response.body)['releases'].slice!(0, options[:limit]).map do |release|
|
36
|
-
data << [release['version'], release['created_at']]
|
37
|
-
end
|
38
|
-
|
39
|
-
print_table(
|
40
|
-
build_table(['Version', 'Created at'], data)
|
41
|
-
)
|
42
|
-
say "\n"
|
43
|
-
else
|
44
|
-
api_error response
|
30
|
+
if response.success?
|
31
|
+
data = []
|
32
|
+
JSON.parse(response.body)["releases"].slice!(0, options[:limit]).map do |release|
|
33
|
+
data << [release["version"], release["created_at"]]
|
45
34
|
end
|
46
|
-
end
|
47
35
|
|
48
|
-
|
49
|
-
|
36
|
+
print_table(
|
37
|
+
build_table(["Version", "Created at"], data)
|
38
|
+
)
|
39
|
+
say "\n"
|
40
|
+
else
|
41
|
+
api_error response
|
42
|
+
end
|
50
43
|
end
|
44
|
+
|
45
|
+
rescue Exception => e
|
46
|
+
error e.message
|
51
47
|
end
|
52
48
|
|
53
49
|
desc "release deploy [COMPONENT = nil, RELEASE_ID = nil]", "Deploys a release to the specific enironment"
|
54
50
|
method_option :tags, :type => :array, :default => nil, :desc => "The tags of the components you want to deploy (i.e 'renderer')"
|
55
|
-
method_option :from, :type => :string, :default =>
|
51
|
+
method_option :from, :type => :string, :default => "release", :desc => "The location that the deployment shold be taken from (release|int|test)"
|
56
52
|
def deploy(component = nil, release_id = nil)
|
53
|
+
say banner
|
54
|
+
|
55
|
+
components(options, component).each do |id|
|
56
|
+
begin
|
57
|
+
|
58
|
+
component_release = release_id
|
59
|
+
if release_id.nil?
|
60
|
+
|
61
|
+
post_data = {}
|
62
|
+
endpoint = config.app["deploy"]
|
63
|
+
|
64
|
+
case options[:from]
|
65
|
+
when "release"
|
66
|
+
response = api.get sprintf(config.app["release"], id)
|
67
|
+
api_error response unless response.success?
|
68
|
+
component_release = JSON.parse(response.body)["releases"].first["version"]
|
69
|
+
post_data = {
|
70
|
+
"release_version" => component_release
|
71
|
+
}
|
72
|
+
when "int", "test", "live"
|
73
|
+
|
74
|
+
endpoint = config.app["snapshot_deploy"]
|
75
|
+
response = api.get sprintf(config.app["deployments"], id, options[:from])
|
76
|
+
api_error response unless response.success?
|
77
|
+
snapshot_id = JSON.parse(response.body).first["snapshot"]["snapshot_id"]
|
78
|
+
post_data = {
|
79
|
+
"snapshot_id" => snapshot_id
|
80
|
+
}
|
57
81
|
|
58
|
-
|
59
|
-
|
60
|
-
components(options, component).each do |id|
|
61
|
-
begin
|
62
|
-
|
63
|
-
component_release = release_id
|
64
|
-
if release_id.nil?
|
65
|
-
|
66
|
-
post_data = {}
|
67
|
-
endpoint = config.app['deploy']
|
68
|
-
|
69
|
-
case options[:from]
|
70
|
-
when 'release'
|
71
|
-
response = api.get sprintf(config.app['release'], id)
|
72
|
-
api_error response unless response.success?
|
73
|
-
component_release = JSON.parse(response.body)['releases'].first['version']
|
74
|
-
post_data = {
|
75
|
-
'release_version' => component_release
|
76
|
-
}
|
77
|
-
when 'int', 'test', 'live'
|
78
|
-
|
79
|
-
endpoint = config.app['snapshot_deploy']
|
80
|
-
response = api.get sprintf(config.app['deployments'], id, options[:from])
|
81
|
-
api_error response unless response.success?
|
82
|
-
snapshot_id = JSON.parse(response.body).first['snapshot']['snapshot_id']
|
83
|
-
post_data = {
|
84
|
-
'snapshot_id' => snapshot_id
|
85
|
-
}
|
86
|
-
|
87
|
-
else
|
88
|
-
raise("Invalid location: #{options[:from]} to deploy from")
|
89
|
-
end
|
82
|
+
else
|
83
|
+
fail("Invalid location: #{options[:from]} to deploy from")
|
90
84
|
end
|
85
|
+
end
|
91
86
|
|
92
|
-
|
93
|
-
|
94
|
-
if response.success?
|
87
|
+
response = api.post sprintf(endpoint, options[:env], id), JSON.generate(post_data)
|
95
88
|
|
96
|
-
|
97
|
-
say get_key_value("Version", post_data['snapshot_id'] ? post_data['snapshot_id'] : post_data['release_version'])
|
89
|
+
if response.success?
|
98
90
|
|
99
|
-
|
100
|
-
|
91
|
+
say get_key_value("\nComponent", id)
|
92
|
+
say get_key_value("Version", post_data["snapshot_id"] ? post_data["snapshot_id"] : post_data["release_version"])
|
101
93
|
|
102
|
-
|
103
|
-
|
104
|
-
end
|
94
|
+
data = JSON.parse(response.body)
|
95
|
+
say "\nDeployment started successfully: #{config.app['api']}#{data['url']}\n", :green
|
105
96
|
|
106
|
-
|
107
|
-
|
97
|
+
else
|
98
|
+
api_error response
|
108
99
|
end
|
109
|
-
end
|
110
100
|
|
101
|
+
rescue Exception => e
|
102
|
+
error(e.message, false)
|
103
|
+
end
|
104
|
+
end
|
111
105
|
end
|
112
106
|
|
113
107
|
desc "release deployed [COMPONENT = nil]", "Lists releases deloyed for a component in the specified environment"
|
114
108
|
method_option :tags, :type => :array, :default => nil, :desc => "The tags of the components you want to deploy (i.e 'renderer')"
|
115
109
|
def deployed(component = nil)
|
116
|
-
|
117
|
-
|
118
|
-
say banner
|
110
|
+
say banner
|
119
111
|
|
120
|
-
|
112
|
+
components(options, component).each do |id|
|
113
|
+
response = api.get sprintf(config.app["deployments"], id, options[:env])
|
114
|
+
say get_key_value("\nComponent", id)
|
121
115
|
|
122
|
-
|
123
|
-
|
116
|
+
if response.success?
|
117
|
+
data = JSON.parse(response.body)
|
124
118
|
|
125
|
-
if
|
126
|
-
|
127
|
-
|
128
|
-
if data.empty?
|
129
|
-
say "There are currently no deployments for this component", :yellow
|
130
|
-
else
|
119
|
+
if data.empty?
|
120
|
+
say "There are currently no deployments for this component", :yellow
|
121
|
+
else
|
131
122
|
|
132
|
-
|
123
|
+
deployments = []
|
133
124
|
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
125
|
+
data.slice!(0, options[:limit].to_i).map do |release|
|
126
|
+
deployments << [
|
127
|
+
release["release"]["version"],
|
128
|
+
release["started_at"],
|
129
|
+
release["id"],
|
130
|
+
release["created_by"]["email_address"],
|
131
|
+
deploy_status(release["status"])
|
132
|
+
]
|
133
|
+
end
|
143
134
|
|
144
|
-
|
145
|
-
|
146
|
-
|
135
|
+
print_table(
|
136
|
+
build_table(["Release", "Deployed at", "Deployment id", "Deployed by", "Status"], deployments)
|
137
|
+
)
|
147
138
|
|
148
|
-
|
149
|
-
end
|
150
|
-
else
|
151
|
-
api_error response
|
139
|
+
say "\n"
|
152
140
|
end
|
141
|
+
else
|
142
|
+
api_error response
|
153
143
|
end
|
154
|
-
|
155
|
-
rescue Exception => e
|
156
|
-
error e.message
|
157
144
|
end
|
145
|
+
|
146
|
+
rescue Exception => e
|
147
|
+
error e.message
|
158
148
|
end
|
159
149
|
|
160
150
|
private
|
161
151
|
|
162
152
|
def deploy_status(status)
|
163
153
|
case status
|
164
|
-
when
|
154
|
+
when "pending_bake"
|
165
155
|
set_color(status, :yellow)
|
166
|
-
when
|
156
|
+
when "pending_stack_update_resolution"
|
167
157
|
set_color(status, :yellow)
|
168
|
-
when
|
158
|
+
when "done"
|
169
159
|
set_color(status, :green)
|
170
|
-
when
|
160
|
+
when "failed"
|
171
161
|
set_color(status, :red)
|
172
162
|
else
|
173
163
|
set_color(status, :white)
|
174
164
|
end
|
175
165
|
end
|
176
|
-
|
177
166
|
end
|
178
167
|
end
|
179
168
|
end
|
180
169
|
end
|
181
170
|
end
|
182
|
-
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require "json"
|
2
2
|
require "bbc/cosmos/tools/config"
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require "bbc/cosmos/tools/commands/base"
|
4
|
+
require "bbc/cosmos/tools/cloudformation/generator"
|
5
5
|
require "bbc/cosmos/tools/types/factory"
|
6
6
|
|
7
7
|
module BBC
|
@@ -11,46 +11,44 @@ module BBC
|
|
11
11
|
class Stack < Base
|
12
12
|
attr_accessor :api
|
13
13
|
|
14
|
-
class_option :stack, :type => :string, :default =>
|
15
|
-
class_option :type, :type => :string, :default =>
|
14
|
+
class_option :stack, :type => :string, :default => "main", :desc => "The name of the stack to use"
|
15
|
+
class_option :type, :type => :string, :default => "cfndsl", :desc => "The format of your your CloudFormation (default is cfndsl, but can also be json or yaml)", :enum => %w(cfndsl json yaml)
|
16
16
|
|
17
17
|
def initialize(args = [], local_options = {}, thor_config = {})
|
18
18
|
super(args, local_options, thor_config)
|
19
19
|
|
20
20
|
@l = -> data, component, environment do
|
21
|
-
if data[
|
22
|
-
data[
|
21
|
+
if data["Parameters"] && data["Parameters"]["ImageId"]
|
22
|
+
data["Parameters"]["ImageId"]["Default"] = latest_ami_for(component, environment)
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
-
@api = BBC::Cosmos::Tools::API.new(config.app[
|
26
|
+
@api = BBC::Cosmos::Tools::API.new(config.app["api"], options[:key_path])
|
27
27
|
end
|
28
28
|
|
29
29
|
desc "stack list [COMPONENT = nil]", "Lists stacks for a component"
|
30
30
|
method_option :tags, :type => :array, :default => nil, :desc => "The tags of the components you want to deploy (i.e 'renderer')"
|
31
31
|
def list(component = nil)
|
32
|
-
|
33
32
|
say "#{banner}\n"
|
34
33
|
|
35
34
|
components(options, component).each do |id|
|
36
|
-
|
37
|
-
response = api.get sprintf(config.app['stacks'], options[:env], id)
|
35
|
+
response = api.get sprintf(config.app["stacks"], options[:env], id)
|
38
36
|
say get_key_value("\nComponent", id)
|
39
37
|
|
40
38
|
if response.success?
|
41
39
|
|
42
40
|
data = JSON.parse(response.body).map do |stack|
|
43
41
|
[
|
44
|
-
stack[
|
45
|
-
stack[
|
46
|
-
stack[
|
47
|
-
stack[
|
42
|
+
stack["name"].split("-").last,
|
43
|
+
stack["main_stack"],
|
44
|
+
stack["updated_at"],
|
45
|
+
stack["status"]
|
48
46
|
]
|
49
47
|
end
|
50
48
|
|
51
49
|
print_table(
|
52
50
|
build_table(
|
53
|
-
[
|
51
|
+
["Name", "Main stack", "Updated at", "Status"],
|
54
52
|
data
|
55
53
|
)
|
56
54
|
)
|
@@ -61,61 +59,56 @@ module BBC
|
|
61
59
|
end
|
62
60
|
end
|
63
61
|
|
64
|
-
method_option :variant, :type => :string, :default =>
|
62
|
+
method_option :variant, :type => :string, :default => "default", :desc => "The variant to use, i.e default|scheduled"
|
65
63
|
method_option :group, :type => :string, :default => nil, :desc => "The group name to override the component id"
|
66
64
|
desc "stack generate [COMPONENT]", "Generates a cloudformation template based on a type of component, the identifier and the environment"
|
67
65
|
def generate(component)
|
68
|
-
|
69
66
|
say "#{banner(component)}\n"
|
70
67
|
|
71
68
|
type = Tools::Types::Factory.create(component, options, config)
|
72
69
|
data = type.generate_data true
|
73
70
|
say data, :white
|
74
|
-
|
75
71
|
end
|
76
72
|
|
77
|
-
method_option :variant, :type => :string, :default =>
|
73
|
+
method_option :variant, :type => :string, :default => "default", :desc => "The variant to use, i.e default|scheduled"
|
78
74
|
method_option :group, :type => :string, :default => nil, :desc => "The group name to override the component id"
|
79
75
|
method_option :tags, :type => :array, :default => nil, :desc => "The tags of the components you want to deploy (i.e 'renderer')"
|
80
76
|
desc "stack create [COMPONENT, MAIN_STACK = true]", "Generates and create the cloudformation template for the specific component"
|
81
|
-
def create(component = nil, main_stack =
|
82
|
-
|
83
|
-
say "#{banner}\n"
|
84
|
-
|
85
|
-
components(options, component).each do |id|
|
86
|
-
say get_key_value("\nComponent", id)
|
87
|
-
|
88
|
-
type = Tools::Types::Factory.create(id, options, config)
|
89
|
-
data = type.generate_data
|
90
|
-
stack_data = Tools::Cloudformation::Generator.component_stack_details(config.resources, options, id)
|
91
|
-
|
92
|
-
post_data = {
|
93
|
-
'name_suffix' => options[:stack],
|
94
|
-
'service_stack' => main_stack.match(/(true|t|yes|y|1)$/i) != nil,
|
95
|
-
'template' => data,
|
96
|
-
'parameters' => Tools::Cloudformation::Generator.parameters(data, main_stack),
|
97
|
-
}
|
77
|
+
def create(component = nil, main_stack = "true")
|
78
|
+
say "#{banner}\n"
|
98
79
|
|
99
|
-
|
100
|
-
|
80
|
+
components(options, component).each do |id|
|
81
|
+
say get_key_value("\nComponent", id)
|
101
82
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
83
|
+
type = Tools::Types::Factory.create(id, options, config)
|
84
|
+
data = type.generate_data
|
85
|
+
stack_data = Tools::Cloudformation::Generator.component_stack_details(config.resources, options, id)
|
86
|
+
|
87
|
+
post_data = {
|
88
|
+
"name_suffix" => options[:stack],
|
89
|
+
"service_stack" => !main_stack.match(/(true|t|yes|y|1)$/i).nil?,
|
90
|
+
"template" => data,
|
91
|
+
"parameters" => Tools::Cloudformation::Generator.parameters(data, main_stack)
|
92
|
+
}
|
93
|
+
|
94
|
+
post_data["aws_account_id"] = stack_data["account_id"] unless stack_data["account_id"].nil?
|
95
|
+
response = api.post sprintf(config.app["stack_create_endpoint"], options[:env], id), JSON.pretty_generate(post_data)
|
96
|
+
|
97
|
+
if response.success?
|
98
|
+
say "Stack creation for component '#{component}' successfully started", :green
|
99
|
+
else
|
100
|
+
api_error(response, false)
|
107
101
|
end
|
108
|
-
rescue Exception => e
|
109
|
-
error e.message
|
110
102
|
end
|
103
|
+
rescue Exception => e
|
104
|
+
error e.message
|
111
105
|
end
|
112
106
|
|
113
|
-
method_option :variant, :type => :string, :default =>
|
107
|
+
method_option :variant, :type => :string, :default => "default", :desc => "The variant to use, i.e default|scheduled"
|
114
108
|
method_option :group, :type => :string, :default => nil, :desc => "The group name to override the component id"
|
115
109
|
method_option :tags, :type => :array, :default => nil, :desc => "The tags of the components you want to deploy (i.e 'renderer')"
|
116
110
|
desc "stack update [COMPONENT = nil]", "Generates and updates the cloudformation template for the specific component"
|
117
111
|
def update(component = nil)
|
118
|
-
|
119
112
|
say "#{banner}\n"
|
120
113
|
|
121
114
|
components(options, component).each do |id|
|
@@ -125,26 +118,26 @@ module BBC
|
|
125
118
|
|
126
119
|
type = Tools::Types::Factory.create(id, options, config)
|
127
120
|
data = type.generate_data.tap do |d|
|
128
|
-
@l.(d, id, options[:env])
|
121
|
+
@l.call(d, id, options[:env])
|
129
122
|
end
|
130
123
|
|
131
124
|
stack_meta = stack_data(component, stack_name, options[:env])
|
132
125
|
|
133
|
-
if data[
|
134
|
-
data[
|
135
|
-
stack_parameters(stack_meta[
|
136
|
-
data[
|
126
|
+
if data["Parameters"]
|
127
|
+
data["Parameters"] = deep_merge(
|
128
|
+
stack_parameters(stack_meta["parameters"]),
|
129
|
+
data["Parameters"]
|
137
130
|
)
|
138
131
|
|
139
132
|
params = Tools::Cloudformation::Generator.parameters(data, false)
|
140
133
|
end
|
141
134
|
|
142
135
|
post_data = {
|
143
|
-
|
144
|
-
|
136
|
+
"template" => data,
|
137
|
+
"parameters" => params || {}
|
145
138
|
}
|
146
139
|
|
147
|
-
response = api.post sprintf(config.app[
|
140
|
+
response = api.post sprintf(config.app["stack_update_endpoint"], options[:env], id, stack_name), JSON.pretty_generate(post_data)
|
148
141
|
|
149
142
|
if response.success?
|
150
143
|
say "Stack update for component '#{id}' successfully started", :green
|
@@ -152,12 +145,10 @@ module BBC
|
|
152
145
|
api_error(response, false)
|
153
146
|
end
|
154
147
|
end
|
155
|
-
|
156
148
|
end
|
157
149
|
|
158
150
|
desc "stack delete [COMPONENT]", "Deletes a stack"
|
159
151
|
def delete(component)
|
160
|
-
|
161
152
|
say "#{banner(component)}\n"
|
162
153
|
|
163
154
|
reply = yes?("Are you sure you want to delete the above stack?", :yellow)
|
@@ -165,7 +156,7 @@ module BBC
|
|
165
156
|
|
166
157
|
stack_name = "#{options[:env]}-#{component}-#{options[:stack]}"
|
167
158
|
|
168
|
-
response = api.post sprintf(config.app[
|
159
|
+
response = api.post sprintf(config.app["stack_delete"], options[:env], component, stack_name), JSON.pretty_generate({})
|
169
160
|
|
170
161
|
if response.success?
|
171
162
|
say "Stack delete for component '#{component}' successfully started", :green
|
@@ -173,35 +164,33 @@ module BBC
|
|
173
164
|
api_error response
|
174
165
|
end
|
175
166
|
else
|
176
|
-
error
|
167
|
+
error "Action cancelled"
|
177
168
|
end
|
178
|
-
|
179
169
|
end
|
180
170
|
|
181
171
|
desc "stack events [COMPONENT = nil]", "Shows the stack events for a component"
|
182
|
-
method_option :stack, :type => :string, :default =>
|
172
|
+
method_option :stack, :type => :string, :default => "main", :desc => "The name of the stack to use"
|
183
173
|
method_option :limit, :type => :numeric, :default => 5, :desc => "Limit how many records to show"
|
184
174
|
method_option :tags, :type => :array, :default => nil, :desc => "The tags of the components you want to deploy (i.e 'renderer')"
|
185
175
|
def events(component = nil)
|
186
|
-
|
187
176
|
say "#{banner}\n"
|
188
177
|
|
189
178
|
components(options, component).each do |id|
|
190
179
|
say get_key_value("\nComponent", id)
|
191
180
|
|
192
181
|
stack_name = "#{options[:env]}-#{id}-#{options[:stack]}"
|
193
|
-
response = api.get sprintf(config.app[
|
182
|
+
response = api.get sprintf(config.app["stack_events"], options[:env], id, stack_name)
|
194
183
|
|
195
184
|
if response.success?
|
196
185
|
events = JSON.parse(response.body)
|
197
186
|
|
198
|
-
data = events.slice(0,(options[:limit])).map do |event|
|
187
|
+
data = events.slice(0, (options[:limit])).map do |event|
|
199
188
|
event.split(" ")
|
200
189
|
end
|
201
190
|
|
202
191
|
print_table(
|
203
192
|
build_table(
|
204
|
-
[
|
193
|
+
["Event type", "CF type", "Name", "Status"],
|
205
194
|
data
|
206
195
|
)
|
207
196
|
)
|
@@ -223,22 +212,21 @@ module BBC
|
|
223
212
|
end
|
224
213
|
end
|
225
214
|
|
226
|
-
def stack_data(component, stack_name, env =
|
227
|
-
response = api.get sprintf(config.app[
|
215
|
+
def stack_data(component, stack_name, env = "int")
|
216
|
+
response = api.get sprintf(config.app["stack_details"], env, component, stack_name)
|
228
217
|
JSON.parse(response.body)
|
229
218
|
end
|
230
219
|
|
231
|
-
def latest_ami_for(component, env =
|
232
|
-
response = api.get sprintf(config.app[
|
220
|
+
def latest_ami_for(component, env = "int")
|
221
|
+
response = api.get sprintf(config.app["deployments"], component, env)
|
233
222
|
api_error response unless response.success?
|
234
|
-
JSON.parse(response.body).first[
|
223
|
+
JSON.parse(response.body).first["image"]["ami_id"]
|
235
224
|
end
|
236
225
|
|
237
226
|
def deep_merge(merger, mergee)
|
238
|
-
merge_proc =
|
227
|
+
merge_proc = proc { |_key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merge_proc) : v2 }
|
239
228
|
merger.merge(mergee, &merge_proc)
|
240
229
|
end
|
241
|
-
|
242
230
|
end
|
243
231
|
end
|
244
232
|
end
|