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