prima-twig 0.13.37 → 0.14.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/bin/twig-deploy +107 -50
- data/bin/twig-feature +739 -632
- data/lib/command.rb +24 -37
- data/lib/prima_twig.rb +4 -12
- metadata +19 -166
- data/bin/twig-build +0 -2153
- data/bin/twig-update-ami +0 -197
- data/lib/prima_aws_client.rb +0 -494
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 5f327ab5415e9942da77bcd72b306ee83fb183c9
|
4
|
+
data.tar.gz: 32a4d9ae10f89a8dc829a2f58ade4debc5ff7b3a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fea86d11be56b30e65b4e164c9d7836776ded2f2decc1db6685febb5271bde01a1f17d0cf737170e3f33a28c4ca61b015831689cbfb9f5e3ef9cde21505b5632
|
7
|
+
data.tar.gz: 4a1ca207cf83cd866451bf4a726deb01775c701d4e9dab75064814f9deb4f65b63b5fe446afad2d35d33ac9adea3542042eb36584311ad69c7b024e590fe895a
|
data/bin/twig-deploy
CHANGED
@@ -2,13 +2,9 @@
|
|
2
2
|
|
3
3
|
require 'rubygems'
|
4
4
|
require_relative '../lib/prima_twig.rb'
|
5
|
-
require_relative '../lib/prima_aws_client.rb'
|
6
5
|
require 'colorize'
|
7
6
|
require 'highline/import'
|
8
|
-
require 'aws-sdk
|
9
|
-
require 'aws-sdk-cloudformation'
|
10
|
-
require 'aws-sdk-ecs'
|
11
|
-
require 'aws-sdk-s3'
|
7
|
+
require 'aws-sdk'
|
12
8
|
require 'redcarpet'
|
13
9
|
require 'mail'
|
14
10
|
require 'erb'
|
@@ -49,17 +45,12 @@ end
|
|
49
45
|
|
50
46
|
class Review
|
51
47
|
include Command
|
52
|
-
include PrimaAwsClient
|
53
48
|
|
54
49
|
def initialize
|
55
50
|
@prima = Prima.new
|
56
|
-
output "Controllo se ci sono aggiornamenti da fare..."
|
57
|
-
exec "gem update prima-twig && twig deploy #{ARGV.join ' '}" unless `gem outdated`.lines.grep(/^prima-twig \(.*\)/).empty?
|
58
51
|
@cf = Aws::CloudFormation::Client.new
|
59
52
|
@ecs = Aws::ECS::Client.new
|
60
53
|
@s3 = Aws::S3::Client.new
|
61
|
-
@batch = Aws::Batch::Client.new
|
62
|
-
@s3_bucket = "prima-artifacts-encrypted"
|
63
54
|
end
|
64
55
|
|
65
56
|
def execute! args
|
@@ -94,10 +85,19 @@ class Review
|
|
94
85
|
end
|
95
86
|
end
|
96
87
|
|
97
|
-
user = `git config user.name
|
88
|
+
user = `git config user.name`
|
98
89
|
artifact = artifacts.select {|v| v[:rev] == artifact_rev}.first
|
99
90
|
|
100
91
|
do_deploy! artifact_rev
|
92
|
+
exec_step "terminal-notifier -message 'Deploy terminato, vuoi lanciare paparatzinger?'" if which 'terminal-notifier'
|
93
|
+
|
94
|
+
confirm_message = "Vuoi lanciare paparatzinger?"
|
95
|
+
launch_paparatzinger = @prima.yesno confirm_message.blue
|
96
|
+
|
97
|
+
if launch_paparatzinger
|
98
|
+
output "Avvio paparatzinger per gli screenshot".yellow
|
99
|
+
job_name = launch_paparatzinger(artifact[:commit_msg])
|
100
|
+
end
|
101
101
|
|
102
102
|
mail = Mail.new do
|
103
103
|
from 'deploy@prima.it'
|
@@ -113,6 +113,7 @@ class Review
|
|
113
113
|
body << "Revision: [#{artifact[:rev]}](https://github.com/primait/prima/commit/#{artifact[:rev]}) del #{artifact[:created_at].strftime('%d/%m/%Y %H:%M:%S')}\n\n"
|
114
114
|
body << "Branch: [#{artifact[:branch]}](https://github.com/primait/prima/tree/#{artifact[:branch]})\n\n"
|
115
115
|
body << "Commit: #{commit_msg.gsub(/_/, '\_')}\n\n"
|
116
|
+
body << "Screenshots (tra qualche minuto): [BrowserStack](https://www.browserstack.com/automate) (Filtrare per: \"#{get_paparatzinger_job_name(commit_msg).gsub(/_/, '\_')}\")" if launch_paparatzinger
|
116
117
|
|
117
118
|
htmlBody = Redcarpet::Markdown.new(Redcarpet::Render::HTML.new).render body
|
118
119
|
|
@@ -127,38 +128,21 @@ class Review
|
|
127
128
|
mail.html_part = html_part
|
128
129
|
mail.text_part = text_part
|
129
130
|
|
130
|
-
opts = {address: '
|
131
|
-
opts[:user_name] = @prima.
|
132
|
-
opts[:password] = @prima.config['
|
133
|
-
|
134
|
-
exec_step "git checkout master"
|
131
|
+
opts = {address: 'smtp.mandrillapp.com', port: '587'}
|
132
|
+
opts[:user_name] = 'deploy@prima.it'
|
133
|
+
opts[:password] = @prima.config['mandrill']
|
135
134
|
|
136
135
|
mail.delivery_method(:smtp, opts)
|
137
136
|
mail.deliver
|
138
137
|
|
139
|
-
|
140
|
-
|
141
|
-
launch_crawler
|
142
|
-
|
138
|
+
exec_step "git checkout master"
|
143
139
|
exec_step "terminal-notifier -message 'Deploy terminato'" if which 'terminal-notifier'
|
144
140
|
end
|
145
141
|
|
146
|
-
def invalidate_prismic_cache
|
147
|
-
[
|
148
|
-
"guarantee",
|
149
|
-
"glossary",
|
150
|
-
"guide",
|
151
|
-
"faq"
|
152
|
-
].each do |page|
|
153
|
-
|
154
|
-
exec_step "curl -X POST -H \"Content-Type: application/json\" https://www.prima.it/api/cms/update/#{page}?apikey=#{@prima.config['prima_apikey']}"
|
155
|
-
end
|
156
|
-
end
|
157
|
-
|
158
142
|
def reload_parameters!
|
159
143
|
artifact_rev = ''
|
160
144
|
resp = @cf.describe_stacks({
|
161
|
-
stack_name: "ecs-task-web-
|
145
|
+
stack_name: "ecs-task-web-production"
|
162
146
|
})
|
163
147
|
resp.stacks[0].parameters.each do |param|
|
164
148
|
if param.parameter_key == 'ReleaseVersion'
|
@@ -187,42 +171,111 @@ class Review
|
|
187
171
|
exec_step "git checkout #{artifact_rev}"
|
188
172
|
exec_step deploy_command
|
189
173
|
|
190
|
-
stack_name_web = 'ecs-task-web-
|
191
|
-
stack_name_consumer = 'ecs-task-consumer-
|
192
|
-
stack_name_cron = 'ecs-task-consumer-
|
193
|
-
stack_name_job = 'batch-job-php-production'
|
174
|
+
stack_name_web = 'ecs-task-web-production'
|
175
|
+
stack_name_consumer = 'ecs-task-consumer-production'
|
176
|
+
stack_name_cron = 'ecs-task-consumer-production'
|
194
177
|
wait_for_stack_ready(stack_name_web) unless stack_ready?(stack_name_web)
|
195
178
|
wait_for_stack_ready(stack_name_consumer) unless stack_ready?(stack_name_consumer)
|
196
179
|
wait_for_stack_ready(stack_name_cron) unless stack_ready?(stack_name_cron)
|
197
|
-
wait_for_stack_ready(stack_name_job) unless stack_ready?(stack_name_job)
|
198
180
|
end
|
199
181
|
|
200
182
|
def get_artifacts
|
201
183
|
artifacts = []
|
202
|
-
resp = @s3.list_objects(bucket:
|
184
|
+
resp = @s3.list_objects(bucket: 'prima-artifacts', prefix: 'prima')
|
203
185
|
resp.contents.each do |l|
|
204
|
-
|
205
|
-
rev = l.key.match(/^prima\/(\w{15}).tar.gz$/).captures.first if l.key.match(/^prima\/(\w{15}).tar.gz$/)
|
186
|
+
rev = l.key.match(/(\w{15}).tar.gz$/).captures.first if l.key.match(/(\w{15}).tar.gz$/)
|
206
187
|
if rev
|
207
|
-
object = @s3.head_object(bucket:
|
188
|
+
object = @s3.head_object(bucket: 'prima-artifacts', key: l.key)
|
208
189
|
commit_msg = ''
|
209
190
|
commit_msg = Base64.decode64(object.metadata['commit_msg']).strip if object.metadata.has_key? 'commit_msg'
|
210
|
-
artifacts << {rev: rev, created_at: object.last_modified, branch: object.metadata['branch'], commit_msg: commit_msg } if
|
191
|
+
artifacts << {rev: rev, created_at: object.last_modified, branch: object.metadata['branch'], commit_msg: commit_msg } if object.metadata.has_key? 'branch'
|
211
192
|
end
|
212
193
|
end
|
213
194
|
artifacts.sort_by { |v| v[:created_at] }.reverse
|
214
195
|
end
|
215
196
|
|
216
|
-
def
|
217
|
-
|
197
|
+
def wait_for_stack_ready(stack_name)
|
198
|
+
ready = false
|
199
|
+
sleep_seconds = 5
|
200
|
+
output "Attendo che lo stack #{stack_name} finisca di essere deployato...\n".yellow
|
201
|
+
while !ready
|
202
|
+
ready = true if stack_ready?(stack_name)
|
203
|
+
seconds_elapsed = 0
|
204
|
+
while true
|
205
|
+
break if seconds_elapsed >= sleep_seconds
|
206
|
+
print '.'.yellow; STDOUT.flush
|
207
|
+
sleep 1
|
208
|
+
seconds_elapsed += 1
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
output "\nStack #{stack_name} deployato con successo!\n".green
|
213
|
+
end
|
214
|
+
|
215
|
+
def stack_ready?(stack_name)
|
216
|
+
resp = @cf.describe_stacks({
|
217
|
+
stack_name: stack_name
|
218
|
+
})
|
219
|
+
['CREATE_COMPLETE', 'UPDATE_COMPLETE'].include? resp.stacks[0].stack_status
|
220
|
+
end
|
221
|
+
|
222
|
+
def launch_paparatzinger(job_name)
|
223
|
+
@s3.get_object(
|
224
|
+
response_target: '/tmp/paparatzinger_twig.yml',
|
225
|
+
bucket: 'prima-deploy',
|
226
|
+
key: 'paparatzinger_twig.yml')
|
218
227
|
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
228
|
+
paparatzinger_config = YAML.load_file '/tmp/paparatzinger_twig.yml'
|
229
|
+
|
230
|
+
uri = URI.parse(paparatzinger_config['prima_api_search_url'])
|
231
|
+
body = Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') do |http|
|
232
|
+
req = Net::HTTP::Get.new(uri)
|
233
|
+
req["x-apikey"] = paparatzinger_config['prima_api_token']
|
234
|
+
response = http.request req
|
235
|
+
response.body
|
236
|
+
end
|
237
|
+
|
238
|
+
saves = JSON.parse body
|
239
|
+
|
240
|
+
save_code = saves.sample["code"]
|
241
|
+
url_garanzie = "https://www.prima.it/preventivo/auto/#{save_code}/garanzie?browserstack=true"
|
242
|
+
job_name = get_paparatzinger_job_name(clean_commit_message(job_name))
|
243
|
+
|
244
|
+
logical_resource_id = 'TaskDefinitionPaparatzinger'
|
245
|
+
resp = @cf.describe_stack_resource({
|
246
|
+
stack_name: 'ecs-task-paparatzinger-production',
|
247
|
+
logical_resource_id: logical_resource_id
|
223
248
|
})
|
224
249
|
|
225
|
-
|
250
|
+
resp = @ecs.run_task({
|
251
|
+
cluster: 'ecs-cluster-tools-ECSCluster-1I4THZHRXOTO5',
|
252
|
+
task_definition: resp.stack_resource_detail.physical_resource_id,
|
253
|
+
overrides: {
|
254
|
+
container_overrides: [
|
255
|
+
{
|
256
|
+
name: 'paparatzinger',
|
257
|
+
environment: [
|
258
|
+
{
|
259
|
+
name: 'JOB_NAME',
|
260
|
+
value: job_name,
|
261
|
+
},
|
262
|
+
{
|
263
|
+
name: 'VERSION',
|
264
|
+
value: paparatzinger_config['version'],
|
265
|
+
},
|
266
|
+
{
|
267
|
+
name: 'URL_GARANZIE',
|
268
|
+
value: url_garanzie
|
269
|
+
}
|
270
|
+
]
|
271
|
+
}
|
272
|
+
]
|
273
|
+
},
|
274
|
+
count: 1
|
275
|
+
})
|
276
|
+
output "Paparatzinger lanciato con successo. URL: #{url_garanzie}\n".green
|
277
|
+
|
278
|
+
job_name
|
226
279
|
end
|
227
280
|
|
228
281
|
end
|
@@ -234,6 +287,10 @@ def clean_commit_message(commit_msg)
|
|
234
287
|
commit_msg[0..99]
|
235
288
|
end
|
236
289
|
|
290
|
+
def get_paparatzinger_job_name(job_name)
|
291
|
+
job_name.gsub /[^0-9a-z]/i, '-'
|
292
|
+
end
|
293
|
+
|
237
294
|
def which(cmd)
|
238
295
|
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
|
239
296
|
ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
|
data/bin/twig-feature
CHANGED
@@ -2,113 +2,54 @@
|
|
2
2
|
|
3
3
|
require 'rubygems'
|
4
4
|
require_relative '../lib/prima_twig.rb'
|
5
|
-
require_relative '../lib/prima_aws_client.rb'
|
6
|
-
require 'digest'
|
7
|
-
require 'json'
|
8
5
|
require 'launchy'
|
6
|
+
require 'digest'
|
9
7
|
require 'pp'
|
10
|
-
require 'redis'
|
11
8
|
|
12
9
|
class Release
|
13
10
|
include Command
|
14
|
-
include PrimaAwsClient
|
15
11
|
|
16
|
-
def initialize
|
12
|
+
def initialize
|
17
13
|
@prima = Prima.new
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
14
|
+
@cf = Aws::CloudFormation::Client.new
|
15
|
+
@elb = Aws::ElasticLoadBalancing::Client.new
|
16
|
+
@alb = Aws::ElasticLoadBalancingV2::Client.new
|
17
|
+
@ec2 = Aws::EC2::Client.new
|
18
|
+
@ecs = Aws::ECS::Client.new
|
19
|
+
@s3 = Aws::S3::Client.new
|
20
|
+
@asg = Aws::AutoScaling::Client.new
|
21
|
+
@s3_bucket = 'prima-artifacts'
|
22
|
+
@artifact_path = '/tmp/prima-artifact.zip'
|
23
|
+
@import_db_task = 'arn:aws:ecs:eu-west-1:001575623345:task-definition/ecs-task-db-restore-TaskDefinitionDbRestore-8A9N41PAYMJ2:1'
|
24
|
+
@prima_built = false
|
25
|
+
@urania_built = false
|
26
|
+
@ermes_built = false
|
27
|
+
@bburago_built = false
|
28
|
+
@backoffice_built = false
|
25
29
|
@dns_record_identifier = nil
|
26
30
|
@ecs_cluster_name = nil
|
27
|
-
@deploy_update = false
|
28
|
-
@projects = {
|
29
|
-
'prima' => {},
|
30
|
-
'urania' => {},
|
31
|
-
'ermes' => {},
|
32
|
-
'bburago' => {},
|
33
|
-
'hal9000' => {},
|
34
|
-
'fidaty' => {},
|
35
|
-
'peano' => {},
|
36
|
-
# 'rogoreport' => {},
|
37
|
-
'assange' => {},
|
38
|
-
'borat' => {},
|
39
|
-
'crash' => {},
|
40
|
-
'activia' => {},
|
41
|
-
'skynet' => {},
|
42
|
-
'roger' => {},
|
43
|
-
'rachele' => {},
|
44
|
-
'leftorium' => {},
|
45
|
-
'pyxis-npm' => {},
|
46
|
-
'starsky' => {},
|
47
|
-
'hutch' => {},
|
48
|
-
'maia' => {},
|
49
|
-
'legion' => {},
|
50
|
-
'vianello' => {},
|
51
|
-
'domus' => {}
|
52
|
-
# 'toretto' => {}
|
53
|
-
}
|
54
|
-
@base_stack_name_alb = 'ecs-alb-http-public-qa-'
|
55
|
-
@base_stack_name_alb_ws = 'ecs-alb-ws-public-qa-'
|
56
|
-
@git_branch = ''
|
57
|
-
@cloudflare = Rubyflare.connect_with(ENV['CLOUDFLARE_EMAIL'], ENV['CLOUDFLARE_APIKEY'])
|
58
31
|
end
|
59
32
|
|
60
|
-
def execute!
|
33
|
+
def execute! args
|
61
34
|
case args[0]
|
62
|
-
when
|
35
|
+
when "start"
|
63
36
|
start_feature!
|
64
|
-
when
|
37
|
+
when "finish"
|
65
38
|
finish_feature!
|
66
|
-
when
|
67
|
-
abort('Non sei nella cartella di qainit') unless Dir.pwd.match 'qainit$' or Dir.pwd.match '/drone/src'
|
39
|
+
when "deploy"
|
68
40
|
if ['terminate', 'stop', 'shutdown', 'halt', 'destroy'].include? args[1]
|
69
|
-
|
70
|
-
elsif 'update' == args[1]
|
71
|
-
qainit_deploy_update!
|
72
|
-
else
|
73
|
-
if args[1]
|
74
|
-
select_branches(args[1..-1])
|
75
|
-
else
|
76
|
-
select_branches
|
77
|
-
end
|
78
|
-
qainit_deploy!
|
79
|
-
end
|
80
|
-
when 'suite'
|
81
|
-
abort('Non sei nella cartella di qainit') unless Dir.pwd.match 'qainit$'
|
82
|
-
if 'deploy' == args[1]
|
83
|
-
suite_py_branches(args[2])
|
84
|
-
qainit_deploy!(true)
|
85
|
-
end
|
86
|
-
when 'deploy'
|
87
|
-
abort('Non sei nella cartella di artemide') unless Dir.pwd.match 'artemide$'
|
88
|
-
if 'lock' == args[1]
|
89
|
-
deploy_lock!
|
90
|
-
end
|
91
|
-
when 'aggregator'
|
92
|
-
if 'enable' == args[1]
|
93
|
-
aggregator_enable!
|
94
|
-
elsif 'disable' == args[1]
|
95
|
-
aggregator_disable!
|
41
|
+
deploy_shutdown!
|
96
42
|
else
|
97
|
-
|
43
|
+
deploy_feature!
|
98
44
|
end
|
99
45
|
else
|
100
|
-
|
46
|
+
stop_if true, [:wrong_args, ['start', 'finish', 'deploy', 'deploy stop']]
|
101
47
|
end
|
102
48
|
end
|
103
49
|
|
104
|
-
def stop_for_wrong_args
|
105
|
-
puts help_content
|
106
|
-
stop_if true, [:wrong_args, ['start', 'finish', 'deploy', 'deploy project_name', 'deploy stop', 'deploy update', 'aggregator enable', 'aggregator disable']]
|
107
|
-
end
|
108
|
-
|
109
50
|
def start_feature!
|
110
51
|
branch_name = @prima.clean_branch_name(ask('Inserisci il nome del branch (puoi omettere feature/): '.cyan))
|
111
|
-
stop_unless
|
52
|
+
stop_unless branch_name.length > 0, 'Devi inserire il nome del branch'
|
112
53
|
branch_name.prepend 'feature/' unless branch_name.include? 'feature'
|
113
54
|
|
114
55
|
output "Il nome del branch sarà " + branch_name.yellow
|
@@ -118,135 +59,6 @@ class Release
|
|
118
59
|
exec_step "git checkout -b " + branch_name
|
119
60
|
end
|
120
61
|
|
121
|
-
def aggregator_disable!
|
122
|
-
output 'Disable aggregator'
|
123
|
-
|
124
|
-
output "Recupero le informazioni relative al puntamento dei record DNS..."
|
125
|
-
output "Recupero le informazioni sui QA attivi..."
|
126
|
-
stack_list, envs = get_stacks()
|
127
|
-
|
128
|
-
env_hash = nil
|
129
|
-
unless envs.empty?
|
130
|
-
env_hash = envs.detect do |key, tags|
|
131
|
-
aggregator_enabled = tags.detect do |tag|
|
132
|
-
tag.key === "hostname_pattern_priority" and tag.value === "1"
|
133
|
-
end.is_a?(Aws::CloudFormation::Types::Tag)
|
134
|
-
aggregator_enabled
|
135
|
-
end[0]
|
136
|
-
dns_records = @cloudflare.get("zones/1fb634f19c43dfb0162cc4cb91915da2/dns_records", {per_page: 100, type: 'CNAME', content: get_alb_host(@base_stack_name_alb + env_hash[3..8])})
|
137
|
-
stop_if dns_records.body[:result].empty?, "I record DNS degli aggregatori non stanno puntando ad un QA".red
|
138
|
-
change_hostname_priority(env_hash, hostname_pattern_priority())
|
139
|
-
dns_to_staging(env_hash)
|
140
|
-
else
|
141
|
-
output 'Nessun QA trovato'.red
|
142
|
-
exit
|
143
|
-
end
|
144
|
-
|
145
|
-
output 'Finito!'.green
|
146
|
-
end
|
147
|
-
|
148
|
-
def aggregator_enable!
|
149
|
-
output 'Enable aggregator'
|
150
|
-
|
151
|
-
output 'Recupero le informazioni relative al puntamento dei record DNS...'
|
152
|
-
dns_records = @cloudflare.get('zones/1fb634f19c43dfb0162cc4cb91915da2/dns_records', { per_page: 100, type: 'CNAME', content: 'staging.prima.it' })
|
153
|
-
stop_if dns_records.body[:result].empty?, "I record DNS degli aggregatori stanno gia' puntando ad un QA".red
|
154
|
-
|
155
|
-
output "Recupero le informazioni sui QA attivi..."
|
156
|
-
stack_list, envs = get_stacks()
|
157
|
-
|
158
|
-
env_hash = nil
|
159
|
-
unless envs.empty?
|
160
|
-
env_hash = choose do |menu|
|
161
|
-
menu.prompt = "Scegli il QA al quale vuoi far puntare gli ambienti di staging dei comparatori: ".cyan
|
162
|
-
menu.shell = true
|
163
|
-
envs.each do |key, env|
|
164
|
-
title = ""
|
165
|
-
env.each do |e|
|
166
|
-
title << "\n#{e.key.upcase}: #{e.value}"
|
167
|
-
end
|
168
|
-
msg = "#{@prima.reduce_size(title, 1000)}".light_blue
|
169
|
-
menu.choice(msg) { key }
|
170
|
-
end
|
171
|
-
end
|
172
|
-
else
|
173
|
-
output "Nessun QA trovato".red
|
174
|
-
exit
|
175
|
-
end
|
176
|
-
|
177
|
-
change_hostname_priority(env_hash, "1")
|
178
|
-
|
179
|
-
dns_records.body[:result].each do |dns|
|
180
|
-
if dns[:name] =~ /^\w+\-\w+\-staging\.prima\.it$/
|
181
|
-
output "Changing #{dns[:name]} DNS record"
|
182
|
-
@cloudflare.put("zones/1fb634f19c43dfb0162cc4cb91915da2/dns_records/#{dns[:id]}", {type: 'CNAME', name: dns[:name], content: get_alb_host(@base_stack_name_alb + env_hash[3..8]), proxied: true, ttl: 1})
|
183
|
-
end
|
184
|
-
end
|
185
|
-
|
186
|
-
output "Finito!".green
|
187
|
-
end
|
188
|
-
|
189
|
-
def change_hostname_priority(env_hash, hostname_pattern_priority)
|
190
|
-
cluster_stack_name = "ecs-cluster-#{env_hash}"
|
191
|
-
tags = get_stack_tags(cluster_stack_name).map do |tag|
|
192
|
-
if tag.key === "hostname_pattern_priority"
|
193
|
-
{
|
194
|
-
key: "hostname_pattern_priority",
|
195
|
-
value: hostname_pattern_priority
|
196
|
-
}
|
197
|
-
else
|
198
|
-
tag
|
199
|
-
end
|
200
|
-
end
|
201
|
-
|
202
|
-
stack_list = stack_list()
|
203
|
-
|
204
|
-
stack_list.each do |stack|
|
205
|
-
if stack.stack_name.match(/#{env_hash}$/)
|
206
|
-
stack_name = stack.stack_name
|
207
|
-
update_stack(stack_name, get_stack_template(stack_name), get_stack_parameters(stack_name), tags)
|
208
|
-
end
|
209
|
-
end
|
210
|
-
|
211
|
-
stack_list.each do |stack|
|
212
|
-
if stack.stack_name.match(/#{env_hash}$/)
|
213
|
-
wait_for_stack_ready(stack.stack_name) unless stack_ready?(stack.stack_name)
|
214
|
-
end
|
215
|
-
end
|
216
|
-
|
217
|
-
stack_name_web = "ecs-task-web-#{env_hash}"
|
218
|
-
parameters = get_stack_parameters(stack_name_web).map do |param|
|
219
|
-
if param.parameter_key === "HostnamePatternPriority"
|
220
|
-
{
|
221
|
-
parameter_key: "HostnamePatternPriority",
|
222
|
-
parameter_value: hostname_pattern_priority
|
223
|
-
}
|
224
|
-
elsif param.parameter_key === "HostnamePatternAggregatorPriority"
|
225
|
-
{
|
226
|
-
parameter_key: "HostnamePatternAggregatorPriority",
|
227
|
-
parameter_value: (hostname_pattern_priority.to_i + 1).to_s
|
228
|
-
}
|
229
|
-
else
|
230
|
-
param
|
231
|
-
end
|
232
|
-
end
|
233
|
-
|
234
|
-
update_stack(stack_name_web, get_stack_template(stack_name_web), parameters)
|
235
|
-
|
236
|
-
wait_for_stack_ready(stack_name_web) unless stack_ready?(stack_name_web)
|
237
|
-
end
|
238
|
-
|
239
|
-
def dns_to_staging(env_hash)
|
240
|
-
output "Recupero le informazioni relative al puntamento dei record DNS..."
|
241
|
-
dns_records = @cloudflare.get("zones/1fb634f19c43dfb0162cc4cb91915da2/dns_records", {per_page: 100, type: 'CNAME', content: get_alb_host(@base_stack_name_alb + env_hash[3..8])})
|
242
|
-
dns_records.body[:result].each do |dns|
|
243
|
-
if dns[:name] =~ /^\w+\-\w+\-staging\.prima\.it$/
|
244
|
-
output "Changing #{dns[:name]} DNS record"
|
245
|
-
@cloudflare.put("zones/1fb634f19c43dfb0162cc4cb91915da2/dns_records/#{dns[:id]}", {type: 'CNAME', name: dns[:name], content: 'staging.prima.it', proxied: true, ttl: 1})
|
246
|
-
end
|
247
|
-
end
|
248
|
-
end
|
249
|
-
|
250
62
|
def finish_feature!
|
251
63
|
current_branch_name = @prima.twig.current_branch_name
|
252
64
|
stop_unless (current_branch_name =~ /^feature\//), "Non sei su un branch di feature, non posso mergiare nulla"
|
@@ -267,8 +79,13 @@ class Release
|
|
267
79
|
end
|
268
80
|
|
269
81
|
def deploy_shutdown!
|
270
|
-
|
271
|
-
stack_list
|
82
|
+
envs = {}
|
83
|
+
stack_list.each do |stack|
|
84
|
+
unless stack.stack_name.match(/spotfleet-allinone-qa-(\w+)$/)
|
85
|
+
env_hash = stack.stack_name.match(/qa-(\w+)$/)[0]
|
86
|
+
envs[env_hash] = stack.tags unless envs.has_key?(env_hash)
|
87
|
+
end
|
88
|
+
end
|
272
89
|
|
273
90
|
env_hash = nil
|
274
91
|
unless envs.empty?
|
@@ -277,511 +94,818 @@ class Release
|
|
277
94
|
menu.shell = true
|
278
95
|
|
279
96
|
envs.each do |key, env|
|
280
|
-
title =
|
281
|
-
|
282
|
-
title << "\n#{e.key}: #{e.value} "
|
283
|
-
end
|
284
|
-
msg = @prima.reduce_size(title, 1000).to_s.light_blue
|
97
|
+
title = @prima.reduce_size("#{env[0].key}: #{env[0].value} #{env[1].key}: #{env[1].value} #{env[2].key}: #{env[2].value} #{env[3].key}: #{env[3].value}", 100)
|
98
|
+
msg = "#{title}".light_blue
|
285
99
|
menu.choice(msg) { key }
|
286
100
|
end
|
287
101
|
end
|
288
102
|
else
|
289
|
-
output
|
103
|
+
output "Nessun environment trovato".red
|
290
104
|
exit
|
291
105
|
end
|
292
106
|
|
293
107
|
cluster_stack_name = nil
|
294
|
-
stacks_to_delete = []
|
295
108
|
stack_list.each do |stack|
|
296
109
|
if stack.stack_name.match(/#{env_hash}$/)
|
297
110
|
if stack.stack_name.match(/ecs-cluster/)
|
298
111
|
cluster_stack_name = stack.stack_name
|
299
112
|
else
|
300
|
-
|
301
|
-
stacks_to_delete.push(stack.stack_name)
|
302
|
-
delete_stack(stack.stack_name)
|
113
|
+
delete_stack(stack.stack_name) if stack.stack_name.match(/#{env_hash}$/)
|
303
114
|
end
|
304
115
|
end
|
305
116
|
end
|
306
117
|
|
307
|
-
cluster_stack_name = "ecs-cluster-#{env_hash}"
|
308
|
-
aggregator_enabled = get_stack_tags(cluster_stack_name).detect do |tag|
|
309
|
-
tag.key === "hostname_pattern_priority" and tag.value === "1"
|
310
|
-
end.is_a?(Aws::CloudFormation::Types::Tag)
|
311
|
-
|
312
|
-
if aggregator_enabled
|
313
|
-
dns_to_staging(env_hash)
|
314
|
-
end
|
315
|
-
|
316
118
|
# Se non ha finito di cancellare le altre non si puo' cancellare il cluster
|
317
|
-
output "Attendo
|
318
|
-
|
319
|
-
while stacks_to_delete.length > 0
|
320
|
-
sleep 13
|
321
|
-
stacks_to_delete.each do |stack_name|
|
322
|
-
stacks_to_delete = stacks_to_delete - [stack_name] unless stack_exists?(stack_name)
|
323
|
-
end
|
324
|
-
output "Stack ancora attivi: #{stacks_to_delete.length.to_s}. Attendo altri 10 secondi per eliminare il cluster ECS"
|
325
|
-
end
|
326
|
-
|
119
|
+
output "Attendo 60 secondi per poter eliminare il cluster ECS"
|
120
|
+
sleep 60
|
327
121
|
delete_stack(cluster_stack_name)
|
328
|
-
delete_stack(@base_stack_name_alb + env_hash[3..8])
|
329
|
-
delete_stack(@base_stack_name_alb_ws + env_hash[3..8])
|
330
122
|
output "Finito!".green
|
331
123
|
end
|
332
124
|
|
333
|
-
def
|
334
|
-
|
125
|
+
def deploy_feature!
|
126
|
+
`sudo true` # cosi' non chiede la password dopo
|
335
127
|
`git pull && git submodule init && git submodule update`
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
128
|
+
prima_branch = choose_branch_to_deploy('prima')
|
129
|
+
backoffice_branch = choose_branch_to_deploy('backoffice')
|
130
|
+
urania_branch = choose_branch_to_deploy('urania')
|
131
|
+
ermes_branch = choose_branch_to_deploy('ermes')
|
132
|
+
bburago_branch = choose_branch_to_deploy('bburago')
|
133
|
+
socket_branch = {name: "master"}
|
134
|
+
pamela_branch = {name: "master"}
|
135
|
+
|
136
|
+
@dns_record_identifier = "#{@prima.clean_branch_name(prima_branch[:name])}-#{@prima.clean_branch_name(backoffice_branch[:name])}-#{@prima.clean_branch_name(urania_branch[:name])}-#{@prima.clean_branch_name(ermes_branch[:name])}-#{@prima.clean_branch_name(bburago_branch[:name])}".gsub(/feature./, '')[0..35].gsub(/(-+$)/, '')
|
137
|
+
|
138
|
+
tags = [
|
139
|
+
{
|
140
|
+
key: "prima",
|
141
|
+
value: prima_branch[:name]
|
142
|
+
},
|
143
|
+
{
|
144
|
+
key: "urania",
|
145
|
+
value: urania_branch[:name]
|
146
|
+
},
|
147
|
+
{
|
148
|
+
key: "backoffice",
|
149
|
+
value: backoffice_branch[:name]
|
150
|
+
},
|
151
|
+
{
|
152
|
+
key: "ermes",
|
153
|
+
value: ermes_branch[:name]
|
154
|
+
},
|
155
|
+
{
|
156
|
+
key: "bburago",
|
157
|
+
value: bburago_branch[:name]
|
158
|
+
}
|
159
|
+
]
|
160
|
+
|
161
|
+
deploy_id = Digest::MD5.hexdigest(prima_branch[:name] + backoffice_branch[:name] + urania_branch[:name] + socket_branch[:name] + pamela_branch[:name] + ermes_branch[:name] + bburago_branch[:name])
|
162
|
+
|
163
|
+
cluster_stack_name = "ecs-cluster-qa-#{deploy_id}"
|
164
|
+
create_cluster_stack(cluster_stack_name, tags) unless stack_exists?(cluster_stack_name)
|
165
|
+
wait_for_stack_ready(cluster_stack_name) unless stack_ready?(cluster_stack_name)
|
166
|
+
|
167
|
+
resp = @cf.describe_stack_resource({stack_name: cluster_stack_name, logical_resource_id: 'ECSCluster'})
|
168
|
+
@ecs_cluster_name = resp.stack_resource_detail.physical_resource_id
|
169
|
+
|
170
|
+
asg_stack_name = "ecs-asg-allinone-qa-#{deploy_id}"
|
171
|
+
create_asg_stack(asg_stack_name, tags) unless stack_exists?(asg_stack_name)
|
172
|
+
|
173
|
+
stack_name_db = "ecs-task-db-qa-#{deploy_id}"
|
174
|
+
stack_body = IO.read('cloudformation/stacks/task/db.yml')
|
175
|
+
parameters = [
|
176
|
+
{
|
177
|
+
parameter_key: "Environment",
|
178
|
+
parameter_value: "qa"
|
179
|
+
},
|
180
|
+
{
|
181
|
+
parameter_key: "ECSClusterName",
|
182
|
+
parameter_value: @ecs_cluster_name
|
183
|
+
}
|
184
|
+
]
|
185
|
+
create_stack(stack_name_db, stack_body, parameters, tags) unless stack_exists?(stack_name_db)
|
186
|
+
|
187
|
+
create_prima_artifact(prima_branch[:revision], prima_branch[:name]) unless artifact_exists?('prima-artifacts', "prima/#{prima_branch[:revision]}")
|
188
|
+
create_urania_artifact(urania_branch[:revision]) unless artifact_exists?('prima-artifacts', "microservices/urania/#{urania_branch[:revision]}-qa.tar.gz")
|
189
|
+
create_ermes_artifact(ermes_branch[:revision]) unless artifact_exists?('prima-artifacts', "microservices/ermes/#{ermes_branch[:revision]}-qa.tar.gz")
|
190
|
+
create_bburago_artifact(bburago_branch[:revision]) unless artifact_exists?('prima-artifacts', "microservices/bburago/#{bburago_branch[:revision]}-qa.tar.gz")
|
191
|
+
create_backoffice_artifact(backoffice_branch[:revision], deploy_id) unless artifact_exists?('prima-artifacts', "backoffice/#{backoffice_branch[:revision]}-#{deploy_id}.zip")
|
192
|
+
|
193
|
+
wait_for_stack_ready(stack_name_db) unless stack_ready?(stack_name_db)
|
194
|
+
import_dbs(ec2_ip_address(asg_stack_name)) unless stack_exists?("ecs-task-web-qa-#{deploy_id}")
|
195
|
+
|
196
|
+
stack_name_web = "ecs-task-web-qa-#{deploy_id}"
|
197
|
+
git_checkout_version('prima', prima_branch[:revision])
|
198
|
+
stack_body = IO.read('projects/prima/app/cloudformation/tasks/web.yml')
|
199
|
+
parameters = [
|
200
|
+
{
|
201
|
+
parameter_key: "Environment",
|
202
|
+
parameter_value: "qa"
|
203
|
+
},
|
204
|
+
{
|
205
|
+
parameter_key: "ReleaseVersion",
|
206
|
+
parameter_value: prima_branch[:revision]
|
207
|
+
},
|
208
|
+
{
|
209
|
+
parameter_key: "TaskDesiredCount",
|
210
|
+
parameter_value: "1"
|
211
|
+
},
|
212
|
+
{
|
213
|
+
parameter_key: "ECSClusterName",
|
214
|
+
parameter_value: @ecs_cluster_name
|
215
|
+
},
|
216
|
+
{
|
217
|
+
parameter_key: "ALBShortName",
|
218
|
+
parameter_value: "ecs-task-web-qa-#{deploy_id}"[0..31]
|
219
|
+
},
|
220
|
+
{
|
221
|
+
parameter_key: "WebQaBaseHostname",
|
222
|
+
parameter_value: "#{@dns_record_identifier}.qa.colaster.com"
|
223
|
+
}
|
224
|
+
]
|
225
|
+
if stack_exists?(stack_name_web)
|
226
|
+
update_stack(stack_name_web, stack_body, parameters) if @prima_built
|
356
227
|
else
|
357
|
-
|
358
|
-
|
228
|
+
create_stack(stack_name_web, stack_body, parameters, tags)
|
229
|
+
end
|
230
|
+
|
231
|
+
stack_name_consumer = "ecs-task-consumer-qa-#{deploy_id}"
|
232
|
+
git_checkout_version('prima', prima_branch[:revision])
|
233
|
+
stack_body = IO.read('projects/prima/app/cloudformation/tasks/consumer.yml')
|
234
|
+
parameters = [
|
235
|
+
{
|
236
|
+
parameter_key: "Environment",
|
237
|
+
parameter_value: "qa"
|
238
|
+
},
|
239
|
+
{
|
240
|
+
parameter_key: "ReleaseVersion",
|
241
|
+
parameter_value: prima_branch[:revision]
|
242
|
+
},
|
243
|
+
{
|
244
|
+
parameter_key: "ECSClusterName",
|
245
|
+
parameter_value: @ecs_cluster_name
|
246
|
+
}
|
247
|
+
]
|
248
|
+
if stack_exists?(stack_name_consumer)
|
249
|
+
update_stack(stack_name_consumer, stack_body, parameters) if @prima_built
|
250
|
+
else
|
251
|
+
create_stack(stack_name_consumer, stack_body, parameters, tags)
|
252
|
+
end
|
253
|
+
|
254
|
+
stack_name_urania = "ecs-task-urania-qa-#{deploy_id}"
|
255
|
+
git_checkout_version('urania', urania_branch[:revision])
|
256
|
+
stack_body = IO.read('projects/urania/deploy/task.yml')
|
257
|
+
parameters = [
|
258
|
+
{
|
259
|
+
parameter_key: "Environment",
|
260
|
+
parameter_value: "qa"
|
261
|
+
},
|
262
|
+
{
|
263
|
+
parameter_key: "ReleaseVersion",
|
264
|
+
parameter_value: urania_branch[:revision]
|
265
|
+
},
|
266
|
+
{
|
267
|
+
parameter_key: "TaskDesiredCount",
|
268
|
+
parameter_value: "1"
|
269
|
+
},
|
270
|
+
{
|
271
|
+
parameter_key: "ECSClusterName",
|
272
|
+
parameter_value: @ecs_cluster_name
|
273
|
+
},
|
274
|
+
{
|
275
|
+
parameter_key: "ALBShortName",
|
276
|
+
parameter_value: "ecs-task-urania-qa-#{deploy_id}"[0..31]
|
277
|
+
}
|
278
|
+
]
|
279
|
+
if stack_exists?(stack_name_urania)
|
280
|
+
update_stack(stack_name_urania, stack_body, parameters) if @urania_built
|
281
|
+
else
|
282
|
+
create_stack(stack_name_urania, stack_body, parameters, tags)
|
283
|
+
end
|
284
|
+
|
285
|
+
stack_name_ermes = "ecs-task-ermes-qa-#{deploy_id}"
|
286
|
+
git_checkout_version('ermes', ermes_branch[:revision])
|
287
|
+
stack_body = IO.read('projects/ermes/deploy/task.yml')
|
288
|
+
parameters = [
|
289
|
+
{
|
290
|
+
parameter_key: "Environment",
|
291
|
+
parameter_value: "qa"
|
292
|
+
},
|
293
|
+
{
|
294
|
+
parameter_key: "ReleaseVersion",
|
295
|
+
parameter_value: ermes_branch[:revision]
|
296
|
+
},
|
297
|
+
{
|
298
|
+
parameter_key: "ECSClusterName",
|
299
|
+
parameter_value: @ecs_cluster_name
|
300
|
+
}
|
301
|
+
]
|
302
|
+
if stack_exists?(stack_name_ermes)
|
303
|
+
update_stack(stack_name_ermes, stack_body, parameters) if @ermes_built
|
304
|
+
else
|
305
|
+
create_stack(stack_name_ermes, stack_body, parameters, tags)
|
306
|
+
end
|
307
|
+
|
308
|
+
stack_name_bburago = "ecs-task-bburago-qa-#{deploy_id}"
|
309
|
+
git_checkout_version('bburago', bburago_branch[:revision])
|
310
|
+
stack_body = IO.read('projects/bburago/deploy/task.yml')
|
311
|
+
parameters = [
|
312
|
+
{
|
313
|
+
parameter_key: "Environment",
|
314
|
+
parameter_value: "qa"
|
315
|
+
},
|
316
|
+
{
|
317
|
+
parameter_key: "ReleaseVersion",
|
318
|
+
parameter_value: bburago_branch[:revision]
|
319
|
+
},
|
320
|
+
{
|
321
|
+
parameter_key: "ECSClusterName",
|
322
|
+
parameter_value: @ecs_cluster_name
|
323
|
+
},
|
324
|
+
{
|
325
|
+
parameter_key: "TaskDesiredCount",
|
326
|
+
parameter_value: "1"
|
327
|
+
},
|
328
|
+
{
|
329
|
+
parameter_key: "ALBShortName",
|
330
|
+
parameter_value: "ecs-task-bburago-qa-#{deploy_id}"[0..31]
|
331
|
+
}
|
332
|
+
]
|
333
|
+
if stack_exists?(stack_name_bburago)
|
334
|
+
update_stack(stack_name_bburago, stack_body, parameters) if @bburago_built
|
335
|
+
else
|
336
|
+
create_stack(stack_name_bburago, stack_body, parameters, tags)
|
337
|
+
end
|
338
|
+
|
339
|
+
git_checkout_version('backoffice', backoffice_branch[:revision])
|
340
|
+
stack_name_backoffice = "ecs-task-backoffice-qa-#{deploy_id}"
|
341
|
+
stack_body = IO.read('projects/backoffice/deploy/task.yml')
|
342
|
+
parameters = [
|
343
|
+
{
|
344
|
+
parameter_key: "Environment",
|
345
|
+
parameter_value: "qa"
|
346
|
+
},
|
347
|
+
{
|
348
|
+
parameter_key: "ReleaseVersion",
|
349
|
+
parameter_value: "#{backoffice_branch[:revision]}-#{deploy_id}"
|
350
|
+
},
|
351
|
+
{
|
352
|
+
parameter_key: "TaskDesiredCount",
|
353
|
+
parameter_value: "1"
|
354
|
+
},
|
355
|
+
{
|
356
|
+
parameter_key: "ECSClusterName",
|
357
|
+
parameter_value: @ecs_cluster_name
|
358
|
+
},
|
359
|
+
{
|
360
|
+
parameter_key: "ALBShortName",
|
361
|
+
parameter_value: "ecs-task-backoffice-qa-#{deploy_id}"[0..31]
|
362
|
+
}
|
363
|
+
]
|
364
|
+
if stack_exists?(stack_name_backoffice)
|
365
|
+
update_stack(stack_name_backoffice, stack_body, parameters) if @backoffice_built
|
366
|
+
else
|
367
|
+
create_stack(stack_name_backoffice, stack_body, parameters, tags)
|
359
368
|
end
|
360
369
|
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
370
|
+
wait_for_stack_ready(stack_name_web) unless stack_ready?(stack_name_web)
|
371
|
+
wait_for_stack_ready(stack_name_consumer) unless stack_ready?(stack_name_consumer)
|
372
|
+
wait_for_stack_ready(stack_name_urania) unless stack_ready?(stack_name_urania)
|
373
|
+
wait_for_stack_ready(stack_name_backoffice) unless stack_ready?(stack_name_backoffice)
|
374
|
+
wait_for_stack_ready(stack_name_ermes) unless stack_ready?(stack_name_ermes)
|
375
|
+
wait_for_stack_ready(stack_name_bburago) unless stack_ready?(stack_name_bburago)
|
376
|
+
|
377
|
+
update_service_defaults(stack_name_web)
|
378
|
+
update_service_defaults(stack_name_consumer)
|
379
|
+
update_service_defaults(stack_name_urania)
|
380
|
+
update_service_defaults(stack_name_backoffice)
|
381
|
+
update_service_defaults(stack_name_ermes)
|
382
|
+
update_service_defaults(stack_name_bburago)
|
383
|
+
|
384
|
+
stack_name_route53 = "ecs-route53-qa-#{deploy_id}"
|
385
|
+
stack_body = IO.read('cloudformation/stacks/route53/qa.yml')
|
386
|
+
parameters = [
|
387
|
+
{
|
388
|
+
parameter_key: "DnsRecordIdentifier",
|
389
|
+
parameter_value: @dns_record_identifier
|
390
|
+
},
|
391
|
+
{
|
392
|
+
parameter_key: "PrimaElbHostname",
|
393
|
+
parameter_value: get_alb_host(stack_name_web)
|
394
|
+
},
|
395
|
+
{
|
396
|
+
parameter_key: "BackofficeElbHostname",
|
397
|
+
parameter_value: get_alb_host(stack_name_backoffice)
|
398
|
+
},
|
399
|
+
{
|
400
|
+
parameter_key: "UraniaElbHostname",
|
401
|
+
parameter_value: get_alb_host(stack_name_urania)
|
402
|
+
},
|
403
|
+
{
|
404
|
+
parameter_key: "BburagoElbHostname",
|
405
|
+
parameter_value: get_alb_host(stack_name_bburago)
|
406
|
+
}
|
407
|
+
]
|
408
|
+
create_stack(stack_name_route53, stack_body, parameters, tags) unless stack_exists?(stack_name_route53)
|
409
|
+
|
410
|
+
prima_hostname = get_route53_hostname(stack_name_web)
|
411
|
+
urania_hostname = get_route53_hostname(stack_name_urania)
|
412
|
+
bburago_hostname = get_route53_hostname(stack_name_bburago)
|
413
|
+
backoffice_hostname = get_route53_hostname(stack_name_backoffice)
|
414
|
+
|
415
|
+
wait_for_stack_ready(stack_name_route53) unless stack_ready?(stack_name_route53)
|
416
|
+
|
417
|
+
output "Prima url: #{prima_hostname}\n".cyan
|
418
|
+
output "Prima RI url: #{prima_hostname.sub("www", "wwwri")}\n".cyan
|
419
|
+
output "Urania url: #{urania_hostname}\n".cyan
|
420
|
+
output "Backoffice url: #{backoffice_hostname}\n".cyan
|
421
|
+
output "Bburago url: #{bburago_hostname}\n".cyan
|
422
|
+
output "SSH connection: ssh ec2-user@#{ec2_ip_address(asg_stack_name)} -i ~/.ssh/ecs-cluster-qa.pem".cyan
|
423
|
+
output "Deploy effettuato, everything is awesome!\n".green
|
424
|
+
end
|
425
|
+
|
426
|
+
def get_route53_hostname(stack_name)
|
427
|
+
case
|
428
|
+
when stack_name.include?('web')
|
429
|
+
host = "www.#{@dns_record_identifier}.qa.colaster.com"
|
430
|
+
when stack_name.include?('urania')
|
431
|
+
host = "urania.#{@dns_record_identifier}.qa.colaster.com"
|
432
|
+
when stack_name.include?('backoffice')
|
433
|
+
host = "backoffice.#{@dns_record_identifier}.qa.colaster.com"
|
434
|
+
when stack_name.include?('bburago')
|
435
|
+
host = "bburago.#{@dns_record_identifier}.qa.colaster.com"
|
366
436
|
end
|
367
|
-
|
368
|
-
update_cluster_stack(cluster_stack_name, tags)
|
369
|
-
|
370
|
-
output "Finito!".green
|
437
|
+
host
|
371
438
|
end
|
372
439
|
|
373
|
-
def
|
374
|
-
|
375
|
-
|
376
|
-
|
377
|
-
|
440
|
+
def ec2_ip_address(asg_stack_name)
|
441
|
+
resp = @cf.describe_stack_resource({
|
442
|
+
stack_name: asg_stack_name,
|
443
|
+
logical_resource_id: 'ECSAutoScalingGroup'
|
444
|
+
})
|
445
|
+
resp = @asg.describe_auto_scaling_groups({
|
446
|
+
auto_scaling_group_names: [resp.stack_resource_detail.physical_resource_id],
|
447
|
+
max_records: 1
|
448
|
+
})
|
449
|
+
instance_id = resp.auto_scaling_groups[0].instances[0].instance_id
|
450
|
+
resp = @ec2.describe_instances({instance_ids: [instance_id]})
|
451
|
+
resp.reservations[0].instances[0].private_ip_address
|
452
|
+
end
|
378
453
|
|
379
|
-
|
380
|
-
|
454
|
+
def get_alb_host(stack_name)
|
455
|
+
case
|
456
|
+
when stack_name.include?('web')
|
457
|
+
logical_resource_id = 'EcsApplicationLoadBalancerPublic'
|
458
|
+
when stack_name.include?('urania')
|
459
|
+
logical_resource_id = 'EcsApplicationLoadBalancerInternal'
|
460
|
+
when stack_name.include?('backoffice')
|
461
|
+
logical_resource_id = 'EcsApplicationLoadBalancerPublic'
|
462
|
+
when stack_name.include?('bburago')
|
463
|
+
logical_resource_id = 'EcsApplicationLoadBalancerInternal'
|
464
|
+
end
|
465
|
+
resp = @cf.describe_stack_resource({
|
466
|
+
stack_name: stack_name,
|
467
|
+
logical_resource_id: logical_resource_id
|
468
|
+
})
|
469
|
+
resp = @alb.describe_load_balancers({
|
470
|
+
load_balancer_arns: [resp.stack_resource_detail.physical_resource_id]
|
471
|
+
})
|
472
|
+
resp.load_balancers[0].dns_name
|
473
|
+
end
|
381
474
|
|
382
|
-
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
387
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
msg = "#{@prima.reduce_size(title, 1000)}".light_blue
|
393
|
-
menu.choice(msg) { key }
|
394
|
-
end
|
395
|
-
end
|
396
|
-
else
|
397
|
-
output "Nessun QA trovato".red
|
398
|
-
exit
|
475
|
+
def get_elb_host(stack_name)
|
476
|
+
case
|
477
|
+
when stack_name.include?('web')
|
478
|
+
logical_resource_id = 'EcsElasticLoadBalancerPublic'
|
479
|
+
when stack_name.include?('urania')
|
480
|
+
logical_resource_id = 'EcsElasticLoadBalancerInternal'
|
481
|
+
when stack_name.include?('backoffice')
|
482
|
+
logical_resource_id = 'EcsElasticLoadBalancerPublic'
|
483
|
+
when stack_name.include?('bburago')
|
484
|
+
logical_resource_id = 'EcsElasticLoadBalancerInternal'
|
399
485
|
end
|
486
|
+
resp = @cf.describe_stack_resource({
|
487
|
+
stack_name: stack_name,
|
488
|
+
logical_resource_id: logical_resource_id
|
489
|
+
})
|
490
|
+
resp = @elb.describe_load_balancers({
|
491
|
+
load_balancer_names: [resp.stack_resource_detail.physical_resource_id],
|
492
|
+
page_size: 1
|
493
|
+
})
|
494
|
+
resp.load_balancer_descriptions[0].dns_name
|
495
|
+
end
|
400
496
|
|
401
|
-
|
402
|
-
|
403
|
-
|
497
|
+
def update_service_defaults(stack_name)
|
498
|
+
case
|
499
|
+
when stack_name.include?('web')
|
500
|
+
logical_resource_id = 'ECSServiceWeb'
|
501
|
+
when stack_name.include?('consumer')
|
502
|
+
logical_resource_id = 'ECSServiceConsumer'
|
503
|
+
when stack_name.include?('urania')
|
504
|
+
logical_resource_id = 'ECSServiceUrania'
|
505
|
+
when stack_name.include?('backoffice')
|
506
|
+
logical_resource_id = 'ECSServiceBackoffice'
|
507
|
+
when stack_name.include?('ermes')
|
508
|
+
logical_resource_id = 'ECSServiceErmes'
|
509
|
+
when stack_name.include?('bburago')
|
510
|
+
logical_resource_id = 'ECSServiceBburago'
|
511
|
+
else
|
512
|
+
raise "Service name non gestito per lo stack #{stack_name}"
|
513
|
+
end
|
514
|
+
resp = @cf.describe_stack_resource({
|
515
|
+
stack_name: stack_name,
|
516
|
+
logical_resource_id: logical_resource_id
|
517
|
+
})
|
518
|
+
resp = @ecs.update_service({
|
519
|
+
cluster: @ecs_cluster_name,
|
520
|
+
service: resp.stack_resource_detail.physical_resource_id,
|
521
|
+
deployment_configuration: {
|
522
|
+
minimum_healthy_percent: 0,
|
523
|
+
maximum_percent: 100
|
524
|
+
}
|
525
|
+
})
|
526
|
+
end
|
527
|
+
|
528
|
+
def create_urania_artifact(revision)
|
529
|
+
@urania_built = true
|
530
|
+
output "Preparo l'artifact .zip\n".yellow
|
531
|
+
|
532
|
+
git_checkout_version('urania', revision)
|
533
|
+
|
534
|
+
Dir.chdir 'projects/urania'
|
535
|
+
|
536
|
+
[
|
537
|
+
"docker-compose build web",
|
538
|
+
"docker run -v $PWD:/code -w /code -e MIX_ENV=qa --entrypoint /bin/sh urania_web \
|
539
|
+
'-c' 'mix local.hex --force && mix hex.info && \
|
540
|
+
mix deps.get && mix compile && mix deps.compile && \
|
541
|
+
mv rel/vm.args rel/config.exs /tmp/ && mix release.clean --implode --no-confirm && \
|
542
|
+
mkdir rel && mv /tmp/vm.args /tmp/config.exs rel/ && mix release --env=qa'",
|
543
|
+
"sudo chown -R `whoami` ."
|
544
|
+
].each do |cmd|
|
545
|
+
output "Eseguo #{cmd}".yellow
|
546
|
+
res = %x[ #{cmd} ]
|
547
|
+
if $?.exitstatus != 0
|
548
|
+
color = 'red'
|
549
|
+
else
|
550
|
+
color = 'green'
|
404
551
|
end
|
552
|
+
output res.send color
|
553
|
+
stop_if (color == 'red'), "Errore durante la build dell'artifact".red
|
405
554
|
end
|
406
|
-
deploy_feature!
|
407
555
|
|
408
|
-
|
409
|
-
|
556
|
+
artifact_path = Dir.glob("rel/urania/releases/*/urania.tar.gz").first
|
557
|
+
upload_artifact(artifact_path, "microservices/urania/#{revision}-qa.tar.gz")
|
410
558
|
|
411
|
-
|
412
|
-
projects.each_key do |project|
|
413
|
-
return projects[project]['name'] if not projects[project]['default_branch']
|
414
|
-
end
|
559
|
+
Dir.chdir '../../'
|
415
560
|
end
|
416
561
|
|
417
|
-
def
|
418
|
-
|
562
|
+
def create_ermes_artifact(revision)
|
563
|
+
@ermes_built = true
|
564
|
+
output "Preparo l'artifact .zip\n".yellow
|
565
|
+
|
566
|
+
git_checkout_version('ermes', revision)
|
419
567
|
|
420
|
-
|
568
|
+
Dir.chdir 'projects/ermes'
|
421
569
|
|
422
|
-
|
423
|
-
|
424
|
-
|
570
|
+
[
|
571
|
+
"docker-compose build app",
|
572
|
+
"docker run -v $PWD:/code -w /code -e MIX_ENV=qa --entrypoint /bin/sh ermes_app \
|
573
|
+
'-c' 'mix local.hex --force && mix hex.info && \
|
574
|
+
mix deps.get && mix compile && mix deps.compile && \
|
575
|
+
mv rel/vm.args rel/config.exs /tmp/ && mix release.clean --implode --no-confirm && \
|
576
|
+
mkdir rel && mv /tmp/vm.args /tmp/config.exs rel/ && mix release --env=qa'",
|
577
|
+
"sudo chown -R `whoami` ."
|
578
|
+
].each do |cmd|
|
579
|
+
output "Eseguo #{cmd}".yellow
|
580
|
+
res = %x[ #{cmd} ]
|
581
|
+
if $?.exitstatus != 0
|
582
|
+
color = 'red'
|
583
|
+
else
|
584
|
+
color = 'green'
|
425
585
|
end
|
586
|
+
output res.send color
|
587
|
+
stop_if (color == 'red'), "Errore durante la build dell'artifact".red
|
426
588
|
end
|
427
|
-
end
|
428
589
|
|
429
|
-
|
430
|
-
|
431
|
-
end
|
590
|
+
artifact_path = Dir.glob("rel/ermes/releases/*/ermes.tar.gz").first
|
591
|
+
upload_artifact(artifact_path, "microservices/ermes/#{revision}-qa.tar.gz")
|
432
592
|
|
433
|
-
|
434
|
-
`git config user.email`.gsub("\n", '')
|
593
|
+
Dir.chdir '../../'
|
435
594
|
end
|
436
595
|
|
437
|
-
def
|
438
|
-
|
596
|
+
def create_bburago_artifact(revision)
|
597
|
+
@bburago_built = true
|
598
|
+
output "Preparo l'artifact .zip\n".yellow
|
439
599
|
|
440
|
-
|
600
|
+
git_checkout_version('bburago', revision)
|
441
601
|
|
442
|
-
|
443
|
-
feature_number = ''
|
444
|
-
unless quiet
|
445
|
-
output "Inserisci la feature a cui si riferisce il QA: [#{default_name}]".cyan
|
446
|
-
feature_number = String(STDIN.gets.chomp)
|
447
|
-
end
|
448
|
-
feature_number = default_name if feature_number.empty?
|
449
|
-
branch_name = get_git_user + '_' + feature_number
|
602
|
+
Dir.chdir 'projects/bburago'
|
450
603
|
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
604
|
+
[
|
605
|
+
"docker-compose build web",
|
606
|
+
"docker run -v $PWD:/code -w /code -e MIX_ENV=qa --entrypoint /bin/sh bburago_web \
|
607
|
+
'-c' 'mix local.hex --force && mix hex.info && \
|
608
|
+
mix deps.get && mix compile && mix deps.compile && \
|
609
|
+
mv rel/vm.args rel/config.exs /tmp/ && mix release.clean --implode --no-confirm && \
|
610
|
+
mkdir rel && mv /tmp/vm.args /tmp/config.exs rel/ && mix release --env=qa'",
|
611
|
+
"sudo chown -R `whoami` ."
|
612
|
+
].each do |cmd|
|
613
|
+
output "Eseguo #{cmd}".yellow
|
614
|
+
res = %x[ #{cmd} ]
|
615
|
+
if $?.exitstatus != 0
|
616
|
+
color = 'red'
|
617
|
+
else
|
618
|
+
color = 'green'
|
619
|
+
end
|
620
|
+
output res.send color
|
621
|
+
stop_if (color == 'red'), "Errore durante la build dell'artifact".red
|
455
622
|
end
|
456
623
|
|
457
|
-
|
624
|
+
artifact_path = Dir.glob("rel/bburago/releases/*/bburago.tar.gz").first
|
625
|
+
upload_artifact(artifact_path, "microservices/bburago/#{revision}-qa.tar.gz")
|
458
626
|
|
459
|
-
|
460
|
-
|
461
|
-
update_drone_yml!
|
462
|
-
|
463
|
-
`git add projects && \
|
464
|
-
git add branch_names .drone.yml && \
|
465
|
-
git commit -m '#{branch_name}' && \
|
466
|
-
git push -f --set-upstream origin #{branch_name} && \
|
467
|
-
git checkout master`
|
627
|
+
Dir.chdir '../../'
|
468
628
|
end
|
469
629
|
|
470
|
-
def
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
former_branches = `git branch -a | grep remotes/ | grep -v HEAD | sed 's/ remotes\\/origin\\///g'`.split "\n"
|
476
|
-
git_user = get_git_user
|
477
|
-
# stampiamo la lista
|
478
|
-
chosen_branch = choose do |menu|
|
479
|
-
menu.prompt = "Scegli il QA che vuoi aggiornare: ".cyan
|
480
|
-
menu.shell = true
|
481
|
-
former_branches.delete('master')
|
482
|
-
former_branches.each_with_index do |branch, index|
|
483
|
-
msg = index.odd? ? branch.white : branch.light_yellow # uno bianco e uno giallo alternati
|
484
|
-
msg = branch.start_with?(git_user) ? msg.on_blue : msg.on_black # i branch creati da chi lancia l'update sono su sfondo più chiaro
|
485
|
-
menu.choice(msg) { branch }
|
486
|
-
end
|
487
|
-
end
|
488
|
-
# checkout master, checkout branch, pull branch
|
489
|
-
`git checkout master && git checkout #{chosen_branch} && git pull`
|
630
|
+
def create_backoffice_artifact(revision, deploy_id)
|
631
|
+
@backoffice_built = true
|
632
|
+
output "Preparo l'artifact .zip\n".yellow
|
633
|
+
|
634
|
+
git_checkout_version('backoffice', revision)
|
490
635
|
|
491
|
-
|
636
|
+
Dir.chdir 'projects/backoffice'
|
492
637
|
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
638
|
+
['node_modules'].each do |dir|
|
639
|
+
unless File.directory?(dir)
|
640
|
+
if File.directory?("../../../backoffice/#{dir}")
|
641
|
+
exec_step "rsync -a ../../../backoffice/#{dir} ."
|
642
|
+
end
|
498
643
|
end
|
499
644
|
end
|
500
645
|
|
501
|
-
|
502
|
-
|
503
|
-
|
646
|
+
stack_name_web = "ecs-task-web-qa-notneeded"
|
647
|
+
web_qa_host = get_route53_hostname(stack_name_web)
|
648
|
+
webri_qa_host = web_qa_host.sub("www", "wwwri")
|
649
|
+
|
650
|
+
[
|
651
|
+
"docker-compose build workers",
|
652
|
+
"cd ../../ && docker run -e GIT_DIR=$PWD -v $PWD:/usr/app/src -w /usr/app/src/projects/backoffice blinkmobile/bower install --allow-root",
|
653
|
+
"docker run -v $PWD:/code -w /code -e PHANTOMJS_BIN=/code/node_modules/grunt-selenium-webdriver/node_modules/phantomjs/bin/phantomjs --entrypoint /bin/bash backoffice_workers '-c' 'sed -i \"s/web-qa-url/#{web_qa_host}/g\" Gruntfile.js && sed -i \"s/web-qa-ri-url/#{webri_qa_host}/g\" Gruntfile.js && npm install && grunt qa'",
|
654
|
+
"sudo chown -R `whoami` ."
|
655
|
+
].each do |cmd|
|
656
|
+
output "Eseguo #{cmd}".yellow
|
657
|
+
res = %x[ #{cmd} ]
|
658
|
+
if $?.exitstatus != 0
|
659
|
+
color = 'red'
|
660
|
+
else
|
661
|
+
color = 'green'
|
662
|
+
end
|
663
|
+
output res.send color
|
664
|
+
stop_if (color == 'red'), "Errore durante la build dell'artifact".red
|
504
665
|
end
|
505
666
|
|
506
|
-
|
507
|
-
|
508
|
-
|
667
|
+
artifact_path = '/tmp/backoffice.zip'
|
668
|
+
exec_step "rm -f #{artifact_path} && zip -9 -r #{artifact_path} bin/"
|
669
|
+
upload_artifact(artifact_path, "backoffice/#{revision}-#{deploy_id}.zip")
|
509
670
|
|
510
|
-
|
511
|
-
`git commit -m 'update'`
|
512
|
-
`git push && git checkout master`
|
671
|
+
Dir.chdir '../../'
|
513
672
|
end
|
514
673
|
|
515
|
-
def
|
516
|
-
|
517
|
-
|
518
|
-
former_branches = `git branch -a | grep remotes/ | grep -v HEAD | sed 's/ remotes\\/origin\\///g'`.split "\n"
|
519
|
-
if selection.nil?
|
520
|
-
# stampiamo la lista
|
521
|
-
chosen_branch = choose do |menu|
|
522
|
-
menu.prompt = "Scegli il QA che vuoi spegnere: ".cyan
|
523
|
-
menu.shell = true
|
524
|
-
git_user = get_git_user
|
525
|
-
former_branches.delete('master')
|
526
|
-
former_branches.each_with_index do |branch, index|
|
527
|
-
msg = index.odd? ? branch.white : branch.light_yellow # uno bianco e uno giallo alternati
|
528
|
-
msg = branch.start_with?(git_user) ? msg.on_blue : msg.on_black # i branch creati da chi lancia l'update sono su sfondo blu
|
529
|
-
menu.choice(msg) { branch }
|
530
|
-
end
|
531
|
-
end
|
532
|
-
else
|
533
|
-
chosen_branch = selection
|
534
|
-
end
|
535
|
-
# checkout master, checkout branch, pull branch, push sul branch con commit vuoto
|
536
|
-
`git checkout master && git checkout #{chosen_branch} && git pull`
|
537
|
-
`git commit --allow-empty -m 'shutdown' && git push && git checkout master`
|
538
|
-
end
|
674
|
+
def create_prima_artifact(revision, branch_name)
|
675
|
+
@prima_built = true
|
676
|
+
output "Preparo l'artifact .zip\n".yellow
|
539
677
|
|
540
|
-
|
541
|
-
output "Recupero le informazioni sui QA attivi..."
|
542
|
-
stack_list, envs = get_stacks
|
678
|
+
git_checkout_version('prima', revision)
|
543
679
|
|
544
|
-
|
680
|
+
Dir.chdir 'projects/prima'
|
545
681
|
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
|
550
|
-
if stack.stack_name.match(/ecs-cluster/)
|
551
|
-
cluster_stack_name = stack.stack_name
|
552
|
-
else
|
553
|
-
break unless stack.stack_name.match(/#{env_hash}$/)
|
554
|
-
stacks_to_delete.push(stack.stack_name)
|
555
|
-
delete_stack(stack.stack_name)
|
682
|
+
['vendor'].each do |dir|
|
683
|
+
unless File.directory?(dir)
|
684
|
+
if File.directory?("../../../prima/#{dir}")
|
685
|
+
exec_step "rsync -a ../../../prima/#{dir} ."
|
556
686
|
end
|
557
687
|
end
|
558
688
|
end
|
559
689
|
|
560
|
-
|
561
|
-
|
562
|
-
aggregator_enabled = get_stack_tags(cluster_stack_name).detect do |tag|
|
563
|
-
tag.key === "hostname_pattern_priority" and tag.value === "1"
|
564
|
-
end.is_a?(Aws::CloudFormation::Types::Tag)
|
690
|
+
backoffice_qa_host = get_route53_hostname("ecs-task-backoffice-qa-notneeded")
|
691
|
+
web_qa_host = get_route53_hostname("ecs-task-web-qa-notneeded")
|
565
692
|
|
566
|
-
|
567
|
-
|
693
|
+
[
|
694
|
+
"bin/local_build_artifact.sh #{branch_name} #{web_qa_host} #{backoffice_qa_host}"
|
695
|
+
].each do |cmd|
|
696
|
+
output "Eseguo #{cmd}".yellow
|
697
|
+
res = %x[ #{cmd} ]
|
698
|
+
if $?.exitstatus != 0
|
699
|
+
color = 'red'
|
700
|
+
else
|
701
|
+
color = 'green'
|
568
702
|
end
|
703
|
+
output res.send color
|
704
|
+
exec_step "docker stop redis" if color == 'red'
|
705
|
+
stop_if (color == 'red'), "Errore durante la build dell'artifact".red
|
569
706
|
end
|
570
707
|
|
571
|
-
|
572
|
-
|
708
|
+
Dir.chdir "../../"
|
709
|
+
end
|
710
|
+
|
711
|
+
def git_checkout_version(project, revision)
|
712
|
+
Dir.chdir "projects/#{project}"
|
713
|
+
exec_step "git checkout -- . && git clean -f -d && git checkout #{revision}"
|
714
|
+
Dir.chdir "../../"
|
715
|
+
end
|
716
|
+
|
717
|
+
def upload_artifact(source_path, destination_path)
|
718
|
+
output "Upload dell'artifact in corso (#{(File.size(source_path).to_f / 2**20).round(2)} MiB)\n".yellow
|
719
|
+
s3 = Aws::S3::Resource.new
|
720
|
+
obj = s3.bucket(@s3_bucket).object(destination_path)
|
721
|
+
obj.upload_file(source_path)
|
573
722
|
|
574
|
-
|
575
|
-
|
576
|
-
|
577
|
-
|
723
|
+
output "#{@s3_bucket}/#{destination_path} uploadato con successo!\n".green
|
724
|
+
end
|
725
|
+
|
726
|
+
def wait_for_stack_ready(stack_name)
|
727
|
+
ready = false
|
728
|
+
sleep_seconds = 10
|
729
|
+
output "Attendo che lo stack #{stack_name} finisca di essere inizializzato...\n".yellow
|
730
|
+
while !ready
|
731
|
+
ready = true if stack_ready?(stack_name)
|
732
|
+
seconds_elapsed = 0
|
733
|
+
while true
|
734
|
+
break if seconds_elapsed >= sleep_seconds
|
735
|
+
print '.'.yellow; STDOUT.flush
|
736
|
+
sleep 1
|
737
|
+
seconds_elapsed += 1
|
578
738
|
end
|
579
|
-
output "Stack ancora attivi: #{stacks_to_delete.length.to_s}. Attendo altri 10 secondi per eliminare il cluster ECS"
|
580
739
|
end
|
581
740
|
|
582
|
-
|
583
|
-
delete_stack(@base_stack_name_alb + env_hash[3..8]) if stack_exists?(@base_stack_name_alb + env_hash[3..8])
|
584
|
-
delete_stack(@base_stack_name_alb_ws + env_hash[3..8]) if stack_exists?(@base_stack_name_alb_ws + env_hash[3..8])
|
585
|
-
`git checkout master && git push origin --delete ${DRONE_BRANCH}`
|
586
|
-
output "Cancello il record DNS utilizzato da Lighthouse"
|
587
|
-
delete_lighthouse_dns()
|
588
|
-
output "Finito!".green
|
741
|
+
output "\nStack #{stack_name} pronto!\n".green
|
589
742
|
end
|
590
743
|
|
591
|
-
def
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
744
|
+
def stack_list
|
745
|
+
resp = @cf.describe_stacks
|
746
|
+
stacks = resp.stacks
|
747
|
+
stacks.keep_if { |stack| stack.stack_name.include? '-qa-' }
|
748
|
+
stacks
|
596
749
|
end
|
597
750
|
|
598
|
-
def
|
599
|
-
|
600
|
-
|
601
|
-
drone_yml = drone_yml.gsub(/#{key}@.+\n/, "#{key}@#{project['revision']}\n")
|
602
|
-
end
|
603
|
-
File.open(".drone.yml", "w") do |f|
|
604
|
-
f.write(drone_yml)
|
605
|
-
end
|
751
|
+
def delete_stack(stack_name)
|
752
|
+
@cf.delete_stack({stack_name: stack_name})
|
753
|
+
output "Stack #{stack_name} spenta con successo\n".green
|
606
754
|
end
|
607
755
|
|
608
|
-
def
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
@deploy_id
|
614
|
-
end
|
756
|
+
def stack_ready?(stack_name)
|
757
|
+
resp = @cf.describe_stacks({
|
758
|
+
stack_name: stack_name
|
759
|
+
})
|
760
|
+
['CREATE_COMPLETE', 'UPDATE_COMPLETE', 'UPDATE_ROLLBACK_COMPLETE'].include? resp.stacks[0].stack_status
|
615
761
|
end
|
616
762
|
|
617
|
-
def
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
|
622
|
-
|
623
|
-
|
624
|
-
|
625
|
-
|
626
|
-
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
|
632
|
-
|
633
|
-
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
646
|
-
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
763
|
+
def create_asg_stack(stack_name, tags = [])
|
764
|
+
stack_body = IO.read('cloudformation/stacks/asg/ecs-asg-allinone.yml')
|
765
|
+
parameters = [
|
766
|
+
{
|
767
|
+
parameter_key: "Environment",
|
768
|
+
parameter_value: "qa"
|
769
|
+
},
|
770
|
+
{
|
771
|
+
parameter_key: "InstanceType",
|
772
|
+
parameter_value: "t2.large"
|
773
|
+
},
|
774
|
+
{
|
775
|
+
parameter_key: "ECSClusterName",
|
776
|
+
parameter_value: @ecs_cluster_name
|
777
|
+
}
|
778
|
+
]
|
779
|
+
create_stack(stack_name, stack_body, parameters, tags)
|
780
|
+
end
|
781
|
+
|
782
|
+
def create_cluster_stack(stack_name, tags = [])
|
783
|
+
stack_body = IO.read('cloudformation/stacks/ecs-cluster.yml')
|
784
|
+
create_stack(stack_name, stack_body, [], tags)
|
785
|
+
end
|
786
|
+
|
787
|
+
def import_dbs(ip_address)
|
788
|
+
resp = @ecs.run_task({
|
789
|
+
cluster: @ecs_cluster_name,
|
790
|
+
task_definition: @import_db_task,
|
791
|
+
overrides: {
|
792
|
+
container_overrides: [
|
793
|
+
{
|
794
|
+
name: 'dbrestore',
|
795
|
+
environment: [
|
796
|
+
{
|
797
|
+
name: 'EC2_IP_ADDRESS',
|
798
|
+
value: ip_address,
|
799
|
+
}
|
800
|
+
]
|
801
|
+
}
|
802
|
+
]
|
803
|
+
},
|
804
|
+
count: 1
|
805
|
+
})
|
806
|
+
output "Attendo che i DB vengano importati...\n".yellow
|
807
|
+
stopped_at = nil
|
808
|
+
while stopped_at.nil?
|
809
|
+
resp = @ecs.describe_tasks({
|
810
|
+
cluster: @ecs_cluster_name,
|
811
|
+
tasks: [resp.tasks[0].task_arn]
|
812
|
+
})
|
813
|
+
stopped_at = resp.tasks[0].stopped_at
|
814
|
+
sleep_seconds = 10
|
815
|
+
seconds_elapsed = 0
|
816
|
+
while true && stopped_at.nil?
|
817
|
+
break if seconds_elapsed >= sleep_seconds
|
818
|
+
print '.'.yellow; STDOUT.flush
|
819
|
+
sleep 1
|
820
|
+
seconds_elapsed += 1
|
821
|
+
end
|
661
822
|
end
|
662
|
-
|
663
|
-
resp = describe_load_balancers([resp.stack_resource_detail.physical_resource_id])
|
664
|
-
resp.load_balancers[0].dns_name
|
823
|
+
print "\n"
|
665
824
|
end
|
666
825
|
|
667
|
-
def
|
668
|
-
|
669
|
-
@
|
826
|
+
def stack_exists?(stack_name)
|
827
|
+
begin
|
828
|
+
res = @cf.describe_stacks({
|
829
|
+
stack_name: stack_name
|
830
|
+
})
|
831
|
+
rescue Aws::CloudFormation::Errors::ValidationError => e
|
832
|
+
if e.message.include? 'does not exist'
|
833
|
+
false
|
834
|
+
else
|
835
|
+
raise e
|
836
|
+
end
|
670
837
|
else
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
838
|
+
true
|
839
|
+
end
|
840
|
+
end
|
841
|
+
|
842
|
+
def create_stack(stack_name, stack_body, parameters = [], tags = [])
|
843
|
+
@cf.create_stack({
|
844
|
+
stack_name: stack_name,
|
845
|
+
template_body: stack_body,
|
846
|
+
parameters: parameters,
|
847
|
+
tags: tags,
|
848
|
+
capabilities: ["CAPABILITY_IAM"],
|
849
|
+
on_failure: "ROLLBACK"
|
850
|
+
})
|
851
|
+
output "La creazione dello stack #{stack_name} è stata avviata".green
|
852
|
+
end
|
853
|
+
|
854
|
+
def update_stack(stack_name, stack_body, parameters = [])
|
855
|
+
begin
|
856
|
+
@cf.update_stack({
|
857
|
+
stack_name: stack_name,
|
858
|
+
template_body: stack_body,
|
859
|
+
parameters: parameters,
|
860
|
+
capabilities: ["CAPABILITY_IAM"]
|
861
|
+
})
|
862
|
+
rescue Aws::CloudFormation::Errors::ValidationError => e
|
863
|
+
# if e.message.include? 'does not exist'
|
864
|
+
# false
|
865
|
+
# else
|
866
|
+
# raise e
|
867
|
+
# end
|
868
|
+
raise e
|
869
|
+
else
|
870
|
+
output "L'update dello stack #{stack_name} è stato avviato".green
|
677
871
|
end
|
678
872
|
end
|
679
873
|
|
680
|
-
def
|
681
|
-
|
682
|
-
|
874
|
+
def artifact_exists?(bucket, path)
|
875
|
+
resp = @s3.list_objects({
|
876
|
+
bucket: bucket,
|
877
|
+
max_keys: 1,
|
878
|
+
prefix: path
|
879
|
+
})
|
880
|
+
!resp.contents.empty?
|
683
881
|
end
|
684
882
|
|
685
|
-
def choose_branch_to_deploy(project_name
|
883
|
+
def choose_branch_to_deploy(project_name)
|
686
884
|
Dir.chdir "projects/#{project_name}"
|
687
885
|
output "Recupero la lista dei branch del progetto #{project_name}..."
|
688
|
-
`git remote prune origin`
|
689
886
|
out = %x[ git fetch ]
|
690
|
-
branches = %x[ git for-each-ref --sort=-committerdate refs/remotes/ --format='%(refname) %(objectname)
|
691
|
-
.split("\n").delete_if { |b| b.include?('HEAD') }[0..49]
|
692
|
-
|
693
|
-
master_branch = nil
|
694
|
-
|
695
|
-
branches.each do |branch|
|
696
|
-
master_branch = branch if branch.match(/^master\s+/)
|
697
|
-
break unless master_branch.nil?
|
698
|
-
end
|
887
|
+
branches = %x[ git for-each-ref --sort=-committerdate refs/remotes/ --format='%(refname) %(objectname)' | sed 's/refs\\/remotes\\/origin\\///g' ]
|
888
|
+
.split("\n").delete_if { |b| b.include?('HEAD') || b.include?('dev') }[0..49]
|
699
889
|
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
branches.insert(0, branches.delete(master_branch))
|
704
|
-
branch_name = choose do |menu|
|
705
|
-
menu.prompt = "Scegli il branch di #{project_name} da deployare: ".cyan
|
706
|
-
menu.shell = true
|
890
|
+
branch_name = choose do |menu|
|
891
|
+
menu.prompt = "Scegli il branch di #{project_name} da deployare: ".cyan
|
892
|
+
menu.shell = true
|
707
893
|
|
708
|
-
|
894
|
+
branches.each do |branch|
|
709
895
|
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
msg = branch.include?(git_mail) ? msg.on_blue : msg.on_black # i branch aggiornati da chi lancia la creazione sono su sfondo blu
|
714
|
-
menu.choice(msg) { branch }
|
715
|
-
menu.default = branch if branch == master_branch
|
716
|
-
end
|
896
|
+
title = @prima.reduce_size(branch, 100)
|
897
|
+
msg = "#{title}".light_blue
|
898
|
+
menu.choice(msg) { branch }
|
717
899
|
end
|
718
900
|
end
|
719
901
|
|
720
902
|
Dir.chdir "../../"
|
721
903
|
|
722
|
-
name = branch_name.split(' ')
|
723
|
-
revision = branch_name.split(' ')
|
724
|
-
|
725
|
-
{ 'name' => name, 'revision' => revision[0..14], 'committer' => committer_email, 'default_branch' => select_master }
|
726
|
-
end
|
727
|
-
|
728
|
-
def select_branch_to_deploy(project_name, branch_name)
|
729
|
-
Dir.chdir "projects/#{project_name}"
|
730
|
-
output "Recupero il branch #{project_name}:#{branch_name} ..."
|
731
|
-
`git remote prune origin`
|
732
|
-
out = %x[ git fetch ]
|
733
|
-
branch_name = %x[ git for-each-ref --sort=-committerdate refs/remotes/ --format='%(refname) %(objectname) %(committeremail)' | sed 's/refs\\/remotes\\/origin\\///g' ]
|
734
|
-
.split("\n").delete_if { |b| !b.match("^#{Regexp.escape(branch_name)}") }[0..49]
|
735
|
-
.first
|
736
|
-
|
737
|
-
Dir.chdir "../../"
|
738
|
-
name = branch_name.split(' ')[0]
|
739
|
-
revision = branch_name.split(' ')[1]
|
740
|
-
committer_email = branch_name.split(' ')[2].tr('<>', '')
|
741
|
-
{ 'name' => name, 'revision' => revision[0..14], 'committer' => committer_email }
|
742
|
-
end
|
743
|
-
|
744
|
-
def get_stacks()
|
745
|
-
envs = {}
|
746
|
-
stack_list = stack_list()
|
747
|
-
stack_list.each do |stack|
|
748
|
-
unless stack.stack_name.match(/spotfleet-allinone-qa-(\w+)$/)
|
749
|
-
env_hash = stack.stack_name.match(/qa-(\w+)$/)[0]
|
750
|
-
envs[env_hash] = stack.tags unless envs.has_key?(env_hash) || stack.tags.empty?
|
751
|
-
end
|
752
|
-
end
|
753
|
-
return stack_list, envs
|
754
|
-
end
|
755
|
-
|
756
|
-
def get_clusters()
|
757
|
-
envs = {}
|
758
|
-
cluster_list = cluster_list()
|
759
|
-
cluster_list.each do |stack|
|
760
|
-
unless stack.stack_name.match(/spotfleet-allinone-qa-(\w+)$/)
|
761
|
-
env_hash = stack.stack_name.match(/qa-(\w+)$/)[0]
|
762
|
-
envs[env_hash] = stack.tags unless envs.has_key?(env_hash) || stack.tags.empty?
|
763
|
-
end
|
764
|
-
end
|
765
|
-
return cluster_list, envs
|
904
|
+
name = branch_name.split(' ').first
|
905
|
+
revision = branch_name.split(' ').last
|
906
|
+
{ name: name, revision: revision[0..14] }
|
766
907
|
end
|
767
908
|
|
768
|
-
def hostname_pattern_priority()
|
769
|
-
(Time.now.to_i.to_s[-4..-1].to_i + Random.rand(40000)).to_s
|
770
|
-
end
|
771
|
-
|
772
|
-
def select_branches(project_names = nil)
|
773
|
-
output "Deploy feature menu"
|
774
|
-
if project_names.nil?
|
775
|
-
@projects.each{ |key, value| @projects[key] = choose_branch_to_deploy(key) }
|
776
|
-
else
|
777
|
-
project_names.each do |project|
|
778
|
-
@projects[project] = choose_branch_to_deploy(project)
|
779
|
-
end
|
780
|
-
@projects.each_key do |branch_project|
|
781
|
-
@projects[branch_project] = choose_branch_to_deploy(branch_project, true) unless project_names.include? branch_project
|
782
|
-
end
|
783
|
-
end
|
784
|
-
end
|
785
909
|
end
|
786
910
|
|
787
911
|
def help_content
|
@@ -798,24 +922,14 @@ Synopsis
|
|
798
922
|
twig release start
|
799
923
|
twig release finish
|
800
924
|
twig release deploy
|
801
|
-
twig release aggregator
|
802
925
|
|
803
926
|
Description
|
804
927
|
-----------
|
805
928
|
|
806
|
-
start
|
807
|
-
finish
|
808
|
-
|
809
|
-
|
810
|
-
qainit shutdown deletes a specific qa environment
|
811
|
-
|
812
|
-
Available only to devops (from artemide)
|
813
|
-
-----------
|
814
|
-
deploy deploys the feature branch to a temporary AWS Elastic Beanstalk env
|
815
|
-
deploy stop destroys the AWS Elastic Beanstalk env
|
816
|
-
deploy update updates a feature branch with current branches
|
817
|
-
deploy lock protects a qa environment from automatic deletion
|
818
|
-
aggregator enable/disable directs comparator's staging environments to a qa/staging
|
929
|
+
start creates a new feature branch
|
930
|
+
finish finishes the feature by merging to dev and master
|
931
|
+
deploy deploys the feature branch to a temporary AWS Elastic Beanstalk env
|
932
|
+
deploy stop destroys the AWS Elastic Beanstalk env
|
819
933
|
|
820
934
|
Subcommand for Twig: <http://rondevera.github.io/twig/>
|
821
935
|
Author: Andrea Usuelli <https://github.com/andreausu>
|
@@ -830,11 +944,4 @@ if args.include?('--help')
|
|
830
944
|
exit
|
831
945
|
end
|
832
946
|
|
833
|
-
|
834
|
-
if args.include?('no-gem-update')
|
835
|
-
gem_update = false
|
836
|
-
end
|
837
|
-
|
838
|
-
args.delete('no-gem-update')
|
839
|
-
|
840
|
-
Release.new(gem_update).execute!(args)
|
947
|
+
Release.new.execute!(args)
|