prima-twig 0.4.6 → 0.5.27
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 +2000 -0
- data/bin/twig-deploy +126 -89
- data/bin/twig-feature +638 -620
- 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 +25 -6
- metadata +174 -27
data/bin/twig-deploy
CHANGED
@@ -2,13 +2,19 @@
|
|
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'
|
11
15
|
require 'base64'
|
16
|
+
require 'rubyflare'
|
17
|
+
require 'pp'
|
12
18
|
|
13
19
|
def help_content
|
14
20
|
<<-HELP
|
@@ -43,17 +49,35 @@ end
|
|
43
49
|
|
44
50
|
class Review
|
45
51
|
include Command
|
52
|
+
include PrimaAwsClient
|
46
53
|
|
47
54
|
def initialize
|
48
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?
|
49
58
|
@cf = Aws::CloudFormation::Client.new
|
50
59
|
@ecs = Aws::ECS::Client.new
|
60
|
+
@s3 = Aws::S3::Client.new
|
61
|
+
@batch = Aws::Batch::Client.new
|
62
|
+
@s3_bucket = "prima-artifacts-encrypted"
|
51
63
|
end
|
52
64
|
|
53
|
-
def execute!
|
54
|
-
|
65
|
+
def execute! args
|
66
|
+
unless args.empty?
|
67
|
+
case args[0]
|
68
|
+
when "parameters"
|
69
|
+
reload_parameters!
|
70
|
+
else
|
71
|
+
stop_if true, [:wrong_args, ['parameters']]
|
72
|
+
end
|
73
|
+
else
|
74
|
+
deploy_revision!
|
75
|
+
end
|
76
|
+
end
|
55
77
|
|
56
|
-
|
78
|
+
def deploy_revision!
|
79
|
+
stop_if @prima.head_detached?, :detached_head
|
80
|
+
stop_if @prima.repo_has_modified_files?, "Non posso deployare con file non commitati"
|
57
81
|
|
58
82
|
output "Recupero degli artifacts in corso, attendi qualche secondo...".yellow
|
59
83
|
artifacts = get_artifacts[0..49]
|
@@ -70,26 +94,10 @@ class Review
|
|
70
94
|
end
|
71
95
|
end
|
72
96
|
|
73
|
-
user = `git config user.name
|
97
|
+
user = `git config user.name`.delete "\n"
|
74
98
|
artifact = artifacts.select {|v| v[:rev] == artifact_rev}.first
|
75
99
|
|
76
|
-
|
77
|
-
|
78
|
-
output "Il comando per il deploy sara': #{deploy_command}".yellow
|
79
|
-
|
80
|
-
exit unless @prima.yesno "Sei sicuro di voler effettuare il deploy in produzione?".blue
|
81
|
-
|
82
|
-
exec_step deploy_command
|
83
|
-
|
84
|
-
stack_name_web = 'ecs-task-web-production'
|
85
|
-
stack_name_consumer = 'ecs-task-consumer-production'
|
86
|
-
stack_name_cron = 'ecs-task-consumer-production'
|
87
|
-
wait_for_stack_ready(stack_name_web) unless stack_ready?(stack_name_web)
|
88
|
-
wait_for_stack_ready(stack_name_consumer) unless stack_ready?(stack_name_consumer)
|
89
|
-
wait_for_stack_ready(stack_name_cron) unless stack_ready?(stack_name_cron)
|
90
|
-
|
91
|
-
output "Avvio paparatzinger per gli screenshot".yellow
|
92
|
-
job_name = launch_paparatzinger(artifact[:commit_msg])
|
100
|
+
do_deploy! artifact_rev
|
93
101
|
|
94
102
|
mail = Mail.new do
|
95
103
|
from 'deploy@prima.it'
|
@@ -97,13 +105,14 @@ class Review
|
|
97
105
|
subject "#{user} ha effettuato il deploy della revision #{artifact[:rev]}"
|
98
106
|
end
|
99
107
|
|
108
|
+
commit_msg = clean_commit_message(artifact[:commit_msg])
|
109
|
+
|
100
110
|
body = "## Deploy in produzione effettuato con successo\n\n"
|
101
111
|
body << "Data: #{Time.now.strftime('%d/%m/%Y %H:%M:%S')}\n\n"
|
102
112
|
body << "Utente: #{user}\n\n"
|
103
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"
|
104
114
|
body << "Branch: [#{artifact[:branch]}](https://github.com/primait/prima/tree/#{artifact[:branch]})\n\n"
|
105
|
-
body << "Commit: #{
|
106
|
-
body << "Screenshots (tra qualche minuto): [BrowserStack](https://www.browserstack.com/automate) (Filtrare per: \"#{job_name.gsub(/_/, '\_')}\")"
|
115
|
+
body << "Commit: #{commit_msg.gsub(/_/, '\_')}\n\n"
|
107
116
|
|
108
117
|
htmlBody = Redcarpet::Markdown.new(Redcarpet::Render::HTML.new).render body
|
109
118
|
|
@@ -118,94 +127,122 @@ class Review
|
|
118
127
|
mail.html_part = html_part
|
119
128
|
mail.text_part = text_part
|
120
129
|
|
121
|
-
opts = {address: 'smtp.
|
122
|
-
opts[:user_name] =
|
123
|
-
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"
|
124
135
|
|
125
136
|
mail.delivery_method(:smtp, opts)
|
126
137
|
mail.deliver
|
127
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
|
156
|
+
end
|
157
|
+
|
158
|
+
def reload_parameters!
|
159
|
+
artifact_rev = ''
|
160
|
+
resp = @cf.describe_stacks({
|
161
|
+
stack_name: "ecs-task-web-vpc-production"
|
162
|
+
})
|
163
|
+
resp.stacks[0].parameters.each do |param|
|
164
|
+
if param.parameter_key == 'ReleaseVersion'
|
165
|
+
artifact_rev = param.parameter_value
|
166
|
+
break
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
do_deploy!(artifact_rev, true)
|
171
|
+
|
172
|
+
output "\nFinito di aggiornare i parameters.yml\n".green
|
173
|
+
end
|
174
|
+
|
175
|
+
def do_deploy!(artifact_rev, reload_parameters=false)
|
176
|
+
deploy_command = "bin/deploy #{artifact_rev}"
|
177
|
+
deploy_command << " reloadparameters" if reload_parameters
|
178
|
+
|
179
|
+
output "Il comando per il deploy sara': #{deploy_command}".yellow
|
180
|
+
confirm_message = "Sei sicuro di voler effettuare "
|
181
|
+
reload_parameters ? (confirm_message << "il reload dei parameters ") : (confirm_message << " il deploy ")
|
182
|
+
confirm_message << "in produzione?"
|
183
|
+
|
184
|
+
exit unless @prima.yesno confirm_message.blue
|
185
|
+
|
186
|
+
exec_step "git fetch"
|
187
|
+
exec_step "git checkout #{artifact_rev}"
|
188
|
+
exec_step deploy_command
|
189
|
+
|
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'
|
194
|
+
wait_for_stack_ready(stack_name_web) unless stack_ready?(stack_name_web)
|
195
|
+
wait_for_stack_ready(stack_name_consumer) unless stack_ready?(stack_name_consumer)
|
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)
|
128
198
|
end
|
129
199
|
|
130
200
|
def get_artifacts
|
131
201
|
artifacts = []
|
132
|
-
|
133
|
-
resp = s3.list_objects(bucket: 'prima-artifacts', prefix: 'prima')
|
202
|
+
resp = @s3.list_objects(bucket: @s3_bucket, prefix: 'prima')
|
134
203
|
resp.contents.each do |l|
|
135
|
-
|
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$/)
|
136
206
|
if rev
|
137
|
-
object = s3.head_object(bucket:
|
207
|
+
object = @s3.head_object(bucket: @s3_bucket, key: l.key)
|
138
208
|
commit_msg = ''
|
139
209
|
commit_msg = Base64.decode64(object.metadata['commit_msg']).strip if object.metadata.has_key? 'commit_msg'
|
140
|
-
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')
|
141
211
|
end
|
142
212
|
end
|
143
213
|
artifacts.sort_by { |v| v[:created_at] }.reverse
|
144
214
|
end
|
145
215
|
|
146
|
-
def
|
147
|
-
|
148
|
-
sleep_seconds = 5
|
149
|
-
output "Attendo che lo stack #{stack_name} finisca di essere deployato...\n".yellow
|
150
|
-
while !ready
|
151
|
-
ready = true if stack_ready?(stack_name)
|
152
|
-
seconds_elapsed = 0
|
153
|
-
while true
|
154
|
-
break if seconds_elapsed >= sleep_seconds
|
155
|
-
print '.'.yellow; STDOUT.flush
|
156
|
-
sleep 1
|
157
|
-
seconds_elapsed += 1
|
158
|
-
end
|
159
|
-
end
|
216
|
+
def launch_crawler()
|
217
|
+
resp = describe_stack_resource('batch-job-crawler-production', 'JobDefinition')
|
160
218
|
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
resp = @cf.describe_stacks({
|
166
|
-
stack_name: stack_name
|
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
|
167
223
|
})
|
168
|
-
['CREATE_COMPLETE', 'UPDATE_COMPLETE'].include? resp.stacks[0].stack_status
|
169
|
-
end
|
170
224
|
|
171
|
-
|
172
|
-
|
173
|
-
job_name.gsub! /from primait\/feature\//i, ''
|
174
|
-
job_name[0..99].gsub! /[^0-9a-z]/i, '\_'
|
225
|
+
output "Crawler lanciato con successo!\n".green
|
226
|
+
end
|
175
227
|
|
176
|
-
|
177
|
-
resp = @cf.describe_stack_resource({
|
178
|
-
stack_name: 'ecs-task-paparatzinger-production',
|
179
|
-
logical_resource_id: logical_resource_id
|
180
|
-
})
|
228
|
+
end
|
181
229
|
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
name: 'paparatzinger',
|
189
|
-
environment: [
|
190
|
-
{
|
191
|
-
name: 'JOB_NAME',
|
192
|
-
value: job_name,
|
193
|
-
},
|
194
|
-
{
|
195
|
-
name: 'VERSION',
|
196
|
-
value: '1.0.6',
|
197
|
-
}
|
198
|
-
]
|
199
|
-
}
|
200
|
-
]
|
201
|
-
},
|
202
|
-
count: 1
|
203
|
-
})
|
204
|
-
output "paparatzinger lanciato con successo\n".green
|
230
|
+
def clean_commit_message(commit_msg)
|
231
|
+
commit_msg.gsub! /Merge pull request /i, ''
|
232
|
+
commit_msg.gsub! /from primait\/feature\//i, ''
|
233
|
+
commit_msg = commit_msg[/.+?\(#\d+\)/m] unless commit_msg[/.+?\(#\d+\)/m].nil? # rimuove tutto quello che sta dopo la fine del numero di issue
|
234
|
+
commit_msg[0..99]
|
235
|
+
end
|
205
236
|
|
206
|
-
|
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
|
+
}
|
207
244
|
end
|
208
|
-
|
245
|
+
return nil
|
209
246
|
end
|
210
247
|
|
211
|
-
Review.new.execute!
|
248
|
+
Review.new.execute! args
|
data/bin/twig-feature
CHANGED
@@ -2,51 +2,110 @@
|
|
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
|
-
@artifact_path = '/tmp/prima-artifact.zip'
|
22
|
-
@import_db_task = 'arn:aws:ecs:eu-west-1:001575623345:task-definition/ecs-task-db-restore-TaskDefinitionDbRestore-1ON8T3XFRV72W:1'
|
23
|
-
@prima_built = false
|
24
|
-
@urania_built = false
|
25
|
-
@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
|
26
25
|
@dns_record_identifier = nil
|
27
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
|
+
}
|
51
|
+
@base_stack_name_alb = 'ecs-alb-http-public-qa-'
|
52
|
+
@base_stack_name_alb_ws = 'ecs-alb-ws-public-qa-'
|
53
|
+
@git_branch = ''
|
54
|
+
@cloudflare = Rubyflare.connect_with(ENV['CLOUDFLARE_EMAIL'], ENV['CLOUDFLARE_APIKEY'])
|
28
55
|
end
|
29
56
|
|
30
|
-
def execute!
|
57
|
+
def execute!(args)
|
31
58
|
case args[0]
|
32
|
-
when
|
59
|
+
when 'start'
|
33
60
|
start_feature!
|
34
|
-
when
|
61
|
+
when 'finish'
|
35
62
|
finish_feature!
|
36
|
-
when
|
63
|
+
when 'qainit'
|
64
|
+
abort('Non sei nella cartella di qainit') unless Dir.pwd.match 'qainit$' or Dir.pwd.match '/drone/src'
|
37
65
|
if ['terminate', 'stop', 'shutdown', 'halt', 'destroy'].include? args[1]
|
38
|
-
|
66
|
+
qainit_deploy_shutdown!
|
67
|
+
elsif 'update' == args[1]
|
68
|
+
qainit_deploy_update!
|
69
|
+
else
|
70
|
+
if args[1]
|
71
|
+
select_branches(args[1..-1])
|
72
|
+
else
|
73
|
+
select_branches
|
74
|
+
end
|
75
|
+
qainit_deploy!
|
76
|
+
end
|
77
|
+
when 'suite'
|
78
|
+
abort('Non sei nella cartella di qainit') unless Dir.pwd.match 'qainit$'
|
79
|
+
if 'deploy' == args[1]
|
80
|
+
suite_py_branches(args[2])
|
81
|
+
qainit_deploy!(true)
|
82
|
+
end
|
83
|
+
when 'deploy'
|
84
|
+
abort('Non sei nella cartella di artemide') unless Dir.pwd.match 'artemide$'
|
85
|
+
if 'lock' == args[1]
|
86
|
+
deploy_lock!
|
87
|
+
end
|
88
|
+
when 'aggregator'
|
89
|
+
if 'enable' == args[1]
|
90
|
+
aggregator_enable!
|
91
|
+
elsif 'disable' == args[1]
|
92
|
+
aggregator_disable!
|
39
93
|
else
|
40
|
-
|
94
|
+
stop_for_wrong_args
|
41
95
|
end
|
42
96
|
else
|
43
|
-
|
97
|
+
stop_for_wrong_args
|
44
98
|
end
|
45
99
|
end
|
46
100
|
|
101
|
+
def stop_for_wrong_args
|
102
|
+
puts help_content
|
103
|
+
stop_if true, [:wrong_args, ['start', 'finish', 'deploy', 'deploy project_name', 'deploy stop', 'deploy update', 'aggregator enable', 'aggregator disable']]
|
104
|
+
end
|
105
|
+
|
47
106
|
def start_feature!
|
48
107
|
branch_name = @prima.clean_branch_name(ask('Inserisci il nome del branch (puoi omettere feature/): '.cyan))
|
49
|
-
stop_unless branch_name.
|
108
|
+
stop_unless !branch_name.empty?, 'Devi inserire il nome del branch'
|
50
109
|
branch_name.prepend 'feature/' unless branch_name.include? 'feature'
|
51
110
|
|
52
111
|
output "Il nome del branch sarà " + branch_name.yellow
|
@@ -56,6 +115,135 @@ class Release
|
|
56
115
|
exec_step "git checkout -b " + branch_name
|
57
116
|
end
|
58
117
|
|
118
|
+
def aggregator_disable!
|
119
|
+
output 'Disable aggregator'
|
120
|
+
|
121
|
+
output "Recupero le informazioni relative al puntamento dei record DNS..."
|
122
|
+
output "Recupero le informazioni sui QA attivi..."
|
123
|
+
stack_list, envs = get_stacks()
|
124
|
+
|
125
|
+
env_hash = nil
|
126
|
+
unless envs.empty?
|
127
|
+
env_hash = envs.detect do |key, tags|
|
128
|
+
aggregator_enabled = tags.detect do |tag|
|
129
|
+
tag.key === "hostname_pattern_priority" and tag.value === "1"
|
130
|
+
end.is_a?(Aws::CloudFormation::Types::Tag)
|
131
|
+
aggregator_enabled
|
132
|
+
end[0]
|
133
|
+
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])})
|
134
|
+
stop_if dns_records.body[:result].empty?, "I record DNS degli aggregatori non stanno puntando ad un QA".red
|
135
|
+
change_hostname_priority(env_hash, hostname_pattern_priority())
|
136
|
+
dns_to_staging(env_hash)
|
137
|
+
else
|
138
|
+
output 'Nessun QA trovato'.red
|
139
|
+
exit
|
140
|
+
end
|
141
|
+
|
142
|
+
output 'Finito!'.green
|
143
|
+
end
|
144
|
+
|
145
|
+
def aggregator_enable!
|
146
|
+
output 'Enable aggregator'
|
147
|
+
|
148
|
+
output 'Recupero le informazioni relative al puntamento dei record DNS...'
|
149
|
+
dns_records = @cloudflare.get('zones/1fb634f19c43dfb0162cc4cb91915da2/dns_records', { per_page: 100, type: 'CNAME', content: 'staging.prima.it' })
|
150
|
+
stop_if dns_records.body[:result].empty?, "I record DNS degli aggregatori stanno gia' puntando ad un QA".red
|
151
|
+
|
152
|
+
output "Recupero le informazioni sui QA attivi..."
|
153
|
+
stack_list, envs = get_stacks()
|
154
|
+
|
155
|
+
env_hash = nil
|
156
|
+
unless envs.empty?
|
157
|
+
env_hash = choose do |menu|
|
158
|
+
menu.prompt = "Scegli il QA al quale vuoi far puntare gli ambienti di staging dei comparatori: ".cyan
|
159
|
+
menu.shell = true
|
160
|
+
envs.each do |key, env|
|
161
|
+
title = ""
|
162
|
+
env.each do |e|
|
163
|
+
title << "\n#{e.key.upcase}: #{e.value}"
|
164
|
+
end
|
165
|
+
msg = "#{@prima.reduce_size(title, 1000)}".light_blue
|
166
|
+
menu.choice(msg) { key }
|
167
|
+
end
|
168
|
+
end
|
169
|
+
else
|
170
|
+
output "Nessun QA trovato".red
|
171
|
+
exit
|
172
|
+
end
|
173
|
+
|
174
|
+
change_hostname_priority(env_hash, "1")
|
175
|
+
|
176
|
+
dns_records.body[:result].each do |dns|
|
177
|
+
if dns[:name] =~ /^\w+\-\w+\-staging\.prima\.it$/
|
178
|
+
output "Changing #{dns[:name]} DNS record"
|
179
|
+
@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})
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
output "Finito!".green
|
184
|
+
end
|
185
|
+
|
186
|
+
def change_hostname_priority(env_hash, hostname_pattern_priority)
|
187
|
+
cluster_stack_name = "ecs-cluster-#{env_hash}"
|
188
|
+
tags = get_stack_tags(cluster_stack_name).map do |tag|
|
189
|
+
if tag.key === "hostname_pattern_priority"
|
190
|
+
{
|
191
|
+
key: "hostname_pattern_priority",
|
192
|
+
value: hostname_pattern_priority
|
193
|
+
}
|
194
|
+
else
|
195
|
+
tag
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
stack_list = stack_list()
|
200
|
+
|
201
|
+
stack_list.each do |stack|
|
202
|
+
if stack.stack_name.match(/#{env_hash}$/)
|
203
|
+
stack_name = stack.stack_name
|
204
|
+
update_stack(stack_name, get_stack_template(stack_name), get_stack_parameters(stack_name), tags)
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
stack_list.each do |stack|
|
209
|
+
if stack.stack_name.match(/#{env_hash}$/)
|
210
|
+
wait_for_stack_ready(stack.stack_name) unless stack_ready?(stack.stack_name)
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
stack_name_web = "ecs-task-web-#{env_hash}"
|
215
|
+
parameters = get_stack_parameters(stack_name_web).map do |param|
|
216
|
+
if param.parameter_key === "HostnamePatternPriority"
|
217
|
+
{
|
218
|
+
parameter_key: "HostnamePatternPriority",
|
219
|
+
parameter_value: hostname_pattern_priority
|
220
|
+
}
|
221
|
+
elsif param.parameter_key === "HostnamePatternAggregatorPriority"
|
222
|
+
{
|
223
|
+
parameter_key: "HostnamePatternAggregatorPriority",
|
224
|
+
parameter_value: (hostname_pattern_priority.to_i + 1).to_s
|
225
|
+
}
|
226
|
+
else
|
227
|
+
param
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
update_stack(stack_name_web, get_stack_template(stack_name_web), parameters)
|
232
|
+
|
233
|
+
wait_for_stack_ready(stack_name_web) unless stack_ready?(stack_name_web)
|
234
|
+
end
|
235
|
+
|
236
|
+
def dns_to_staging(env_hash)
|
237
|
+
output "Recupero le informazioni relative al puntamento dei record DNS..."
|
238
|
+
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])})
|
239
|
+
dns_records.body[:result].each do |dns|
|
240
|
+
if dns[:name] =~ /^\w+\-\w+\-staging\.prima\.it$/
|
241
|
+
output "Changing #{dns[:name]} DNS record"
|
242
|
+
@cloudflare.put("zones/1fb634f19c43dfb0162cc4cb91915da2/dns_records/#{dns[:id]}", {type: 'CNAME', name: dns[:name], content: 'staging.prima.it', proxied: true, ttl: 1})
|
243
|
+
end
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
59
247
|
def finish_feature!
|
60
248
|
current_branch_name = @prima.twig.current_branch_name
|
61
249
|
stop_unless (current_branch_name =~ /^feature\//), "Non sei su un branch di feature, non posso mergiare nulla"
|
@@ -76,11 +264,8 @@ class Release
|
|
76
264
|
end
|
77
265
|
|
78
266
|
def deploy_shutdown!
|
79
|
-
|
80
|
-
stack_list
|
81
|
-
env_hash = stack.stack_name.match(/qa-(\w+)$/)[0]
|
82
|
-
envs[env_hash] = stack.tags unless envs.has_key?(env_hash)
|
83
|
-
end
|
267
|
+
output "Recupero le informazioni sui QA attivi..."
|
268
|
+
stack_list, envs = get_stacks
|
84
269
|
|
85
270
|
env_hash = nil
|
86
271
|
unless envs.empty?
|
@@ -89,693 +274,509 @@ class Release
|
|
89
274
|
menu.shell = true
|
90
275
|
|
91
276
|
envs.each do |key, env|
|
92
|
-
title =
|
93
|
-
|
277
|
+
title = ''
|
278
|
+
env.each do |e|
|
279
|
+
title << "\n#{e.key}: #{e.value} "
|
280
|
+
end
|
281
|
+
msg = @prima.reduce_size(title, 1000).to_s.light_blue
|
94
282
|
menu.choice(msg) { key }
|
95
283
|
end
|
96
284
|
end
|
97
285
|
else
|
98
|
-
output
|
286
|
+
output 'Nessun environment trovato'.red
|
99
287
|
exit
|
100
288
|
end
|
101
289
|
|
102
290
|
cluster_stack_name = nil
|
291
|
+
stacks_to_delete = []
|
103
292
|
stack_list.each do |stack|
|
104
293
|
if stack.stack_name.match(/#{env_hash}$/)
|
105
294
|
if stack.stack_name.match(/ecs-cluster/)
|
106
295
|
cluster_stack_name = stack.stack_name
|
107
296
|
else
|
108
|
-
|
297
|
+
break unless stack.stack_name.match(/#{env_hash}$/)
|
298
|
+
stacks_to_delete.push(stack.stack_name)
|
299
|
+
delete_stack(stack.stack_name)
|
109
300
|
end
|
110
301
|
end
|
111
302
|
end
|
112
303
|
|
304
|
+
cluster_stack_name = "ecs-cluster-#{env_hash}"
|
305
|
+
aggregator_enabled = get_stack_tags(cluster_stack_name).detect do |tag|
|
306
|
+
tag.key === "hostname_pattern_priority" and tag.value === "1"
|
307
|
+
end.is_a?(Aws::CloudFormation::Types::Tag)
|
308
|
+
|
309
|
+
if aggregator_enabled
|
310
|
+
dns_to_staging(env_hash)
|
311
|
+
end
|
312
|
+
|
113
313
|
# Se non ha finito di cancellare le altre non si puo' cancellare il cluster
|
114
|
-
output "Attendo
|
115
|
-
|
314
|
+
output "Attendo 10 secondi per poter eliminare il cluster ECS"
|
315
|
+
|
316
|
+
while stacks_to_delete.length > 0
|
317
|
+
sleep 13
|
318
|
+
stacks_to_delete.each do |stack_name|
|
319
|
+
stacks_to_delete = stacks_to_delete - [stack_name] unless stack_exists?(stack_name)
|
320
|
+
end
|
321
|
+
output "Stack ancora attivi: #{stacks_to_delete.length.to_s}. Attendo altri 10 secondi per eliminare il cluster ECS"
|
322
|
+
end
|
323
|
+
|
116
324
|
delete_stack(cluster_stack_name)
|
325
|
+
delete_stack(@base_stack_name_alb + env_hash[3..8])
|
326
|
+
delete_stack(@base_stack_name_alb_ws + env_hash[3..8])
|
117
327
|
output "Finito!".green
|
118
328
|
end
|
119
329
|
|
120
|
-
def
|
121
|
-
|
122
|
-
`git pull`
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
key
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
value: backoffice_branch[:name]
|
144
|
-
},
|
145
|
-
{
|
146
|
-
key: "ermes",
|
147
|
-
value: ermes_branch[:name]
|
148
|
-
}
|
149
|
-
]
|
150
|
-
|
151
|
-
deploy_id = Digest::MD5.hexdigest(prima_branch[:name] + backoffice_branch[:name] + urania_branch[:name] + socket_branch[:name] + pamela_branch[:name] + ermes_branch[:name])
|
152
|
-
|
153
|
-
cluster_stack_name = "ecs-cluster-qa-#{deploy_id}"
|
154
|
-
create_cluster_stack(cluster_stack_name, tags) unless stack_exists?(cluster_stack_name)
|
155
|
-
wait_for_stack_ready(cluster_stack_name) unless stack_ready?(cluster_stack_name)
|
156
|
-
|
157
|
-
resp = @cf.describe_stack_resource({stack_name: cluster_stack_name, logical_resource_id: 'ECSCluster'})
|
158
|
-
@ecs_cluster_name = resp.stack_resource_detail.physical_resource_id
|
159
|
-
|
160
|
-
asg_stack_name = "ecs-asg-allinone-qa-#{deploy_id}"
|
161
|
-
create_asg_stack(asg_stack_name, tags) unless stack_exists?(asg_stack_name)
|
162
|
-
|
163
|
-
stack_name_db = "ecs-task-db-qa-#{deploy_id}"
|
164
|
-
stack_body = IO.read('cloudformation/stacks/task/db.json')
|
165
|
-
parameters = [
|
166
|
-
{
|
167
|
-
parameter_key: "Environment",
|
168
|
-
parameter_value: "qa"
|
169
|
-
},
|
170
|
-
{
|
171
|
-
parameter_key: "ECSClusterName",
|
172
|
-
parameter_value: @ecs_cluster_name
|
173
|
-
}
|
174
|
-
]
|
175
|
-
create_stack(stack_name_db, stack_body, parameters, tags) unless stack_exists?(stack_name_db)
|
176
|
-
|
177
|
-
create_prima_artifact(prima_branch[:revision], prima_branch[:name]) unless artifact_exists?('prima-artifacts', "prima/#{prima_branch[:revision]}")
|
178
|
-
create_urania_artifact(urania_branch[:revision]) unless artifact_exists?('prima-artifacts', "microservices/urania/#{urania_branch[:revision]}-qa.tar.gz")
|
179
|
-
create_ermes_artifact(ermes_branch[:revision]) unless artifact_exists?('prima-artifacts', "microservices/ermes/ermes_#{ermes_branch[:revision]}.tar.gz")
|
180
|
-
create_backoffice_artifact(backoffice_branch[:revision], deploy_id) unless artifact_exists?('prima-artifacts', "backoffice/#{backoffice_branch[:revision]}-#{deploy_id}.zip")
|
181
|
-
|
182
|
-
wait_for_stack_ready(stack_name_db) unless stack_ready?(stack_name_db)
|
183
|
-
|
184
|
-
import_dbs(ec2_ip_address(asg_stack_name)) unless stack_exists?("ecs-task-web-qa-#{deploy_id}")
|
185
|
-
|
186
|
-
stack_name_web = "ecs-task-web-qa-#{deploy_id}"
|
187
|
-
git_checkout_version('prima', prima_branch[:revision])
|
188
|
-
stack_body = IO.read('projects/prima/app/cloudformation/tasks/web.json')
|
189
|
-
parameters = [
|
190
|
-
{
|
191
|
-
parameter_key: "Environment",
|
192
|
-
parameter_value: "qa"
|
193
|
-
},
|
194
|
-
{
|
195
|
-
parameter_key: "ReleaseVersion",
|
196
|
-
parameter_value: prima_branch[:revision]
|
197
|
-
},
|
198
|
-
{
|
199
|
-
parameter_key: "TaskDesiredCount",
|
200
|
-
parameter_value: "1"
|
201
|
-
},
|
202
|
-
{
|
203
|
-
parameter_key: "ECSClusterName",
|
204
|
-
parameter_value: @ecs_cluster_name
|
205
|
-
}
|
206
|
-
]
|
207
|
-
if stack_exists?(stack_name_web)
|
208
|
-
update_stack(stack_name_web, stack_body, parameters) if @prima_built
|
209
|
-
else
|
210
|
-
create_stack(stack_name_web, stack_body, parameters, tags)
|
211
|
-
end
|
212
|
-
|
213
|
-
stack_name_consumer = "ecs-task-consumer-qa-#{deploy_id}"
|
214
|
-
git_checkout_version('prima', prima_branch[:revision])
|
215
|
-
stack_body = IO.read('projects/prima/app/cloudformation/tasks/consumer.json')
|
216
|
-
parameters = [
|
217
|
-
{
|
218
|
-
parameter_key: "Environment",
|
219
|
-
parameter_value: "qa"
|
220
|
-
},
|
221
|
-
{
|
222
|
-
parameter_key: "ReleaseVersion",
|
223
|
-
parameter_value: prima_branch[:revision]
|
224
|
-
},
|
225
|
-
{
|
226
|
-
parameter_key: "ECSClusterName",
|
227
|
-
parameter_value: @ecs_cluster_name
|
228
|
-
}
|
229
|
-
]
|
230
|
-
if stack_exists?(stack_name_consumer)
|
231
|
-
update_stack(stack_name_consumer, stack_body, parameters) if @prima_built
|
232
|
-
else
|
233
|
-
create_stack(stack_name_consumer, stack_body, parameters, tags)
|
234
|
-
end
|
235
|
-
|
236
|
-
stack_name_urania = "ecs-task-urania-qa-#{deploy_id}"
|
237
|
-
git_checkout_version('urania', urania_branch[:revision])
|
238
|
-
stack_body = IO.read('projects/urania/deploy/task.json')
|
239
|
-
parameters = [
|
240
|
-
{
|
241
|
-
parameter_key: "Environment",
|
242
|
-
parameter_value: "qa"
|
243
|
-
},
|
244
|
-
{
|
245
|
-
parameter_key: "ReleaseVersion",
|
246
|
-
parameter_value: urania_branch[:revision]
|
247
|
-
},
|
248
|
-
{
|
249
|
-
parameter_key: "TaskDesiredCount",
|
250
|
-
parameter_value: "1"
|
251
|
-
},
|
252
|
-
{
|
253
|
-
parameter_key: "ECSClusterName",
|
254
|
-
parameter_value: @ecs_cluster_name
|
255
|
-
}
|
256
|
-
]
|
257
|
-
if stack_exists?(stack_name_urania)
|
258
|
-
update_stack(stack_name_urania, stack_body, parameters) if @urania_built
|
259
|
-
else
|
260
|
-
create_stack(stack_name_urania, stack_body, parameters, tags)
|
261
|
-
end
|
262
|
-
|
263
|
-
stack_name_ermes = "ecs-task-ermes-qa-#{deploy_id}"
|
264
|
-
git_checkout_version('ermes', ermes_branch[:revision])
|
265
|
-
stack_body = IO.read('projects/ermes/deploy/task.json')
|
266
|
-
parameters = [
|
267
|
-
{
|
268
|
-
parameter_key: "Environment",
|
269
|
-
parameter_value: "qa"
|
270
|
-
},
|
271
|
-
{
|
272
|
-
parameter_key: "ReleaseVersion",
|
273
|
-
parameter_value: ermes_branch[:revision]
|
274
|
-
},
|
275
|
-
{
|
276
|
-
parameter_key: "ECSClusterName",
|
277
|
-
parameter_value: @ecs_cluster_name
|
278
|
-
}
|
279
|
-
]
|
280
|
-
if stack_exists?(stack_name_ermes)
|
281
|
-
update_stack(stack_name_ermes, stack_body, parameters) if @ermes_built
|
282
|
-
else
|
283
|
-
create_stack(stack_name_ermes, stack_body, parameters, tags)
|
284
|
-
end
|
285
|
-
|
286
|
-
git_checkout_version('backoffice', backoffice_branch[:revision])
|
287
|
-
stack_name_backoffice = "ecs-task-backoffice-qa-#{deploy_id}"
|
288
|
-
stack_body = IO.read('projects/backoffice/deploy/task.json')
|
289
|
-
parameters = [
|
290
|
-
{
|
291
|
-
parameter_key: "Environment",
|
292
|
-
parameter_value: "qa"
|
293
|
-
},
|
294
|
-
{
|
295
|
-
parameter_key: "ReleaseVersion",
|
296
|
-
parameter_value: "#{backoffice_branch[:revision]}-#{deploy_id}"
|
297
|
-
},
|
298
|
-
{
|
299
|
-
parameter_key: "TaskDesiredCount",
|
300
|
-
parameter_value: "1"
|
301
|
-
},
|
302
|
-
{
|
303
|
-
parameter_key: "ECSClusterName",
|
304
|
-
parameter_value: @ecs_cluster_name
|
305
|
-
}
|
306
|
-
]
|
307
|
-
if stack_exists?(stack_name_backoffice)
|
308
|
-
update_stack(stack_name_backoffice, stack_body, parameters) if @backoffice_built
|
330
|
+
def deploy_lock!
|
331
|
+
output "Deploy update menu"
|
332
|
+
`git pull && git submodule init && git submodule update`
|
333
|
+
|
334
|
+
@deploy_update = true
|
335
|
+
|
336
|
+
output "Recupero le informazioni sui QA attivi..."
|
337
|
+
stack_list, envs = get_clusters()
|
338
|
+
|
339
|
+
env_hash = nil
|
340
|
+
unless envs.empty?
|
341
|
+
env_hash = choose do |menu|
|
342
|
+
menu.prompt = "Scegli il QA che vuoi proteggere dallo spegnimento automatico: ".cyan
|
343
|
+
menu.shell = true
|
344
|
+
envs.each do |key, env|
|
345
|
+
title = ""
|
346
|
+
env.each do |e|
|
347
|
+
title << "#{e.value}" if e.key == 'qainit'
|
348
|
+
end
|
349
|
+
msg = "#{@prima.reduce_size(title, 1000)}".light_blue
|
350
|
+
menu.choice(msg) { key }
|
351
|
+
end
|
352
|
+
end
|
309
353
|
else
|
310
|
-
|
354
|
+
output "Nessun QA trovato".red
|
355
|
+
exit
|
311
356
|
end
|
312
357
|
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
update_service_defaults(stack_name_web)
|
320
|
-
update_service_defaults(stack_name_consumer)
|
321
|
-
update_service_defaults(stack_name_urania)
|
322
|
-
update_service_defaults(stack_name_backoffice)
|
323
|
-
update_service_defaults(stack_name_ermes)
|
324
|
-
|
325
|
-
stack_name_route53 = "ecs-route53-qa-#{deploy_id}"
|
326
|
-
stack_body = IO.read('cloudformation/stacks/route53/qa.json')
|
327
|
-
parameters = [
|
328
|
-
{
|
329
|
-
parameter_key: "DnsRecordIdentifier",
|
330
|
-
parameter_value: @dns_record_identifier
|
331
|
-
},
|
332
|
-
{
|
333
|
-
parameter_key: "PrimaElbHostname",
|
334
|
-
parameter_value: get_elb_host(stack_name_web)
|
335
|
-
},
|
336
|
-
{
|
337
|
-
parameter_key: "BackofficeElbHostname",
|
338
|
-
parameter_value: get_elb_host(stack_name_backoffice)
|
339
|
-
},
|
340
|
-
{
|
341
|
-
parameter_key: "UraniaElbHostname",
|
342
|
-
parameter_value: get_elb_host(stack_name_urania)
|
343
|
-
}
|
344
|
-
]
|
345
|
-
create_stack(stack_name_route53, stack_body, parameters, tags) unless stack_exists?(stack_name_route53)
|
346
|
-
|
347
|
-
prima_hostname = get_route53_hostname(stack_name_web)
|
348
|
-
urania_hostname = get_route53_hostname(stack_name_urania)
|
349
|
-
backoffice_hostname = get_route53_hostname(stack_name_backoffice)
|
350
|
-
|
351
|
-
wait_for_stack_ready(stack_name_route53) unless stack_ready?(stack_name_route53)
|
352
|
-
|
353
|
-
output "Prima url: #{prima_hostname}\n".cyan
|
354
|
-
output "Urania url: #{urania_hostname}\n".cyan
|
355
|
-
output "Backoffice url: #{backoffice_hostname}\n".cyan
|
356
|
-
output "SSH connection: ssh ec2-user@#{ec2_ip_address(asg_stack_name)} -i ~/.ssh/ecs-cluster-qa.pem".cyan
|
357
|
-
output "Deploy effettuato, everything is awesome!\n".green
|
358
|
-
end
|
359
|
-
|
360
|
-
def get_route53_hostname(stack_name)
|
361
|
-
case
|
362
|
-
when stack_name.include?('web')
|
363
|
-
host = "www.#{@dns_record_identifier}.qa.colaster.com"
|
364
|
-
when stack_name.include?('urania')
|
365
|
-
host = "urania.#{@dns_record_identifier}.qa.colaster.com"
|
366
|
-
when stack_name.include?('backoffice')
|
367
|
-
host = "backoffice.#{@dns_record_identifier}.qa.colaster.com"
|
358
|
+
cluster_stack_name = "ecs-cluster-#{env_hash}"
|
359
|
+
if stack_exists?(cluster_stack_name)
|
360
|
+
tags = get_stack_tags(cluster_stack_name)
|
361
|
+
tag_keep_data = Aws::CloudFormation::Types::Tag.new({key:'AUTOMATIC_DELETION_PROTECTION', value:'true'})
|
362
|
+
tags.push tag_keep_data
|
368
363
|
end
|
369
|
-
host
|
370
|
-
end
|
371
364
|
|
372
|
-
|
373
|
-
resp = @cf.describe_stack_resource({
|
374
|
-
stack_name: asg_stack_name,
|
375
|
-
logical_resource_id: 'ECSAutoScalingGroup'
|
376
|
-
})
|
377
|
-
resp = @asg.describe_auto_scaling_groups({
|
378
|
-
auto_scaling_group_names: [resp.stack_resource_detail.physical_resource_id],
|
379
|
-
max_records: 1
|
380
|
-
})
|
381
|
-
instance_id = resp.auto_scaling_groups[0].instances[0].instance_id
|
382
|
-
resp = @ec2.describe_instances({instance_ids: [instance_id]})
|
383
|
-
resp.reservations[0].instances[0].private_ip_address
|
384
|
-
end
|
365
|
+
update_cluster_stack(cluster_stack_name, tags)
|
385
366
|
|
386
|
-
|
387
|
-
case
|
388
|
-
when stack_name.include?('web')
|
389
|
-
logical_resource_id = 'EcsElasticLoadBalancerPublic'
|
390
|
-
when stack_name.include?('urania')
|
391
|
-
logical_resource_id = 'EcsElasticLoadBalancerInternal'
|
392
|
-
when stack_name.include?('backoffice')
|
393
|
-
logical_resource_id = 'EcsElasticLoadBalancerPublic'
|
394
|
-
end
|
395
|
-
resp = @cf.describe_stack_resource({
|
396
|
-
stack_name: stack_name,
|
397
|
-
logical_resource_id: logical_resource_id
|
398
|
-
})
|
399
|
-
resp = @elb.describe_load_balancers({
|
400
|
-
load_balancer_names: [resp.stack_resource_detail.physical_resource_id],
|
401
|
-
page_size: 1
|
402
|
-
})
|
403
|
-
resp.load_balancer_descriptions[0].dns_name
|
367
|
+
output "Finito!".green
|
404
368
|
end
|
405
369
|
|
406
|
-
def
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
415
|
-
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
|
425
|
-
|
426
|
-
|
427
|
-
|
428
|
-
deployment_configuration: {
|
429
|
-
minimum_healthy_percent: 0,
|
430
|
-
maximum_percent: 100
|
431
|
-
}
|
432
|
-
})
|
433
|
-
end
|
434
|
-
|
435
|
-
def create_urania_artifact(revision)
|
436
|
-
@urania_built = true
|
437
|
-
output "Preparo l'artifact .zip\n".yellow
|
438
|
-
|
439
|
-
git_checkout_version('urania', revision)
|
440
|
-
|
441
|
-
Dir.chdir 'projects/urania'
|
442
|
-
|
443
|
-
[
|
444
|
-
"docker run -v $PWD:/code -w /code -e MIX_ENV=qa prima/urania:1.0.2 \
|
445
|
-
'mix local.hex --force && mix hex.info && \
|
446
|
-
mix deps.get && mix compile && mix deps.compile && \
|
447
|
-
mix release.clean --implode --no-confirm && mix release'",
|
448
|
-
"sudo chown -R `whoami` ."
|
449
|
-
].each do |cmd|
|
450
|
-
output "Eseguo #{cmd}".yellow
|
451
|
-
res = %x[ #{cmd} ]
|
452
|
-
if $?.exitstatus != 0
|
453
|
-
color = 'red'
|
454
|
-
else
|
455
|
-
color = 'green'
|
370
|
+
def deploy_update!
|
371
|
+
output "Deploy update menu"
|
372
|
+
`git pull && git submodule init && git submodule update`
|
373
|
+
|
374
|
+
@deploy_update = true
|
375
|
+
|
376
|
+
output "Recupero le informazioni sui QA attivi..."
|
377
|
+
stack_list, envs = get_stacks()
|
378
|
+
|
379
|
+
env_hash = nil
|
380
|
+
unless envs.empty?
|
381
|
+
env_hash = choose do |menu|
|
382
|
+
menu.prompt = "Scegli il QA che vuoi aggiornare: ".cyan
|
383
|
+
menu.shell = true
|
384
|
+
envs.each do |key, env|
|
385
|
+
title = ""
|
386
|
+
env.each do |e|
|
387
|
+
title << "\n#{e.key.upcase}: #{e.value}"
|
388
|
+
end
|
389
|
+
msg = "#{@prima.reduce_size(title, 1000)}".light_blue
|
390
|
+
menu.choice(msg) { key }
|
391
|
+
end
|
456
392
|
end
|
457
|
-
|
458
|
-
|
393
|
+
else
|
394
|
+
output "Nessun QA trovato".red
|
395
|
+
exit
|
459
396
|
end
|
460
397
|
|
461
|
-
|
462
|
-
|
398
|
+
envs[env_hash].each do |env|
|
399
|
+
unless ['hostname_pattern_priority', 'AUTOMATIC_DELETION_PROTECTION'].include? env.key
|
400
|
+
@projects[env.key] = select_branch_to_deploy(env.key, env.value)
|
401
|
+
end
|
402
|
+
end
|
403
|
+
deploy_feature!
|
463
404
|
|
464
|
-
|
405
|
+
output "Finito!".green
|
465
406
|
end
|
466
407
|
|
467
|
-
def
|
468
|
-
|
469
|
-
|
408
|
+
def get_default_branch_name(projects)
|
409
|
+
projects.each_key do |project|
|
410
|
+
return projects[project]['name'] if not projects[project]['default_branch']
|
411
|
+
end
|
412
|
+
end
|
470
413
|
|
471
|
-
|
414
|
+
def suite_py_branches(args_json)
|
415
|
+
arg_projects = JSON.parse(args_json)
|
472
416
|
|
473
|
-
|
417
|
+
@projects.merge!(arg_projects)
|
474
418
|
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
mix deps.get && mix compile && mix deps.compile && \
|
479
|
-
mix release.clean --implode --no-confirm && mix release'",
|
480
|
-
"sudo chown -R `whoami` ."
|
481
|
-
].each do |cmd|
|
482
|
-
output "Eseguo #{cmd}".yellow
|
483
|
-
res = %x[ #{cmd} ]
|
484
|
-
if $?.exitstatus != 0
|
485
|
-
color = 'red'
|
486
|
-
else
|
487
|
-
color = 'green'
|
419
|
+
@projects.each_key do |project|
|
420
|
+
if @projects[project].empty?
|
421
|
+
@projects[project] = choose_branch_to_deploy(project, true)
|
488
422
|
end
|
489
|
-
output res.send color
|
490
|
-
stop_if (color == 'red'), "Errore durante la build dell'artifact".red
|
491
423
|
end
|
424
|
+
end
|
492
425
|
|
493
|
-
|
494
|
-
|
426
|
+
def get_git_user()
|
427
|
+
`git config user.name`.gsub(/[^A-Za-z]/, '').gsub("\n", '')
|
428
|
+
end
|
495
429
|
|
496
|
-
|
430
|
+
def get_git_mail()
|
431
|
+
`git config user.email`.gsub("\n", '')
|
497
432
|
end
|
498
433
|
|
499
|
-
def
|
500
|
-
|
501
|
-
|
434
|
+
def qainit_deploy!(quiet = false)
|
435
|
+
`git checkout master && git pull && git submodule update --init --recursive && git remote prune origin`
|
436
|
+
|
437
|
+
default_name = get_default_branch_name @projects
|
438
|
+
feature_number = ''
|
439
|
+
unless quiet
|
440
|
+
output "Inserisci la feature a cui si riferisce il QA: [#{default_name}]".cyan
|
441
|
+
feature_number = String(STDIN.gets.chomp)
|
442
|
+
end
|
443
|
+
feature_number = default_name if feature_number.empty?
|
444
|
+
branch_name = get_git_user + '_' + feature_number
|
445
|
+
|
446
|
+
if `git branch -l | grep #{branch_name}`.size > 0
|
447
|
+
`git checkout #{branch_name} && git pull`
|
448
|
+
else
|
449
|
+
`git checkout -b #{branch_name}`
|
450
|
+
end
|
502
451
|
|
503
|
-
|
452
|
+
@git_branch = branch_name
|
504
453
|
|
505
|
-
|
454
|
+
File.open('branch_names', 'w') { |file| file.write(JSON.generate(@projects)) }
|
506
455
|
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
456
|
+
update_drone_yml!
|
457
|
+
|
458
|
+
`git add projects && \
|
459
|
+
git add branch_names .drone.yml && \
|
460
|
+
git commit -m '#{branch_name}' && \
|
461
|
+
git push -f --set-upstream origin #{branch_name} && \
|
462
|
+
git checkout master`
|
463
|
+
end
|
464
|
+
|
465
|
+
def qainit_deploy_update!
|
466
|
+
`git checkout master && git pull`
|
467
|
+
# cancelliamo tutti i branch che non sono più sul repo remoto
|
468
|
+
`git fetch -p && for branch in \`git branch -vv | grep ': gone]' | awk '{print $1}'\`; do git branch -D $branch; done`
|
469
|
+
# leggiamo i nomi dei branch superstiti
|
470
|
+
former_branches = `git branch -a | grep remotes/ | grep -v HEAD | sed 's/ remotes\\/origin\\///g'`.split "\n"
|
471
|
+
git_user = get_git_user
|
472
|
+
# stampiamo la lista
|
473
|
+
chosen_branch = choose do |menu|
|
474
|
+
menu.prompt = "Scegli il QA che vuoi aggiornare: ".cyan
|
475
|
+
menu.shell = true
|
476
|
+
former_branches.delete('master')
|
477
|
+
former_branches.each_with_index do |branch, index|
|
478
|
+
msg = index.odd? ? branch.white : branch.light_yellow # uno bianco e uno giallo alternati
|
479
|
+
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
|
480
|
+
menu.choice(msg) { branch }
|
512
481
|
end
|
513
482
|
end
|
483
|
+
# checkout master, checkout branch, pull branch
|
484
|
+
`git checkout master && git checkout #{chosen_branch} && git pull`
|
514
485
|
|
515
|
-
|
516
|
-
web_qa_host = get_route53_hostname(stack_name_web)
|
486
|
+
# aggiornare il commit (revision a cui fa riferimento)
|
517
487
|
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
].each do |cmd|
|
524
|
-
output "Eseguo #{cmd}".yellow
|
525
|
-
res = %x[ #{cmd} ]
|
526
|
-
if $?.exitstatus != 0
|
527
|
-
color = 'red'
|
528
|
-
else
|
529
|
-
color = 'green'
|
488
|
+
# leggo il file branch_names / recupero i nomi dei branch / riscrivo tutto
|
489
|
+
projects = ''
|
490
|
+
File.open('branch_names', 'r') do |file|
|
491
|
+
file.each_line do |line|
|
492
|
+
projects = JSON.parse(line)
|
530
493
|
end
|
531
|
-
output res.send color
|
532
|
-
stop_if (color == 'red'), "Errore durante la build dell'artifact".red
|
533
494
|
end
|
534
495
|
|
535
|
-
|
536
|
-
|
537
|
-
|
496
|
+
projects.each do |key, project|
|
497
|
+
@projects[key] = select_branch_to_deploy(key, project['name'])
|
498
|
+
@projects[key]['default_branch'] = project['default_branch']
|
499
|
+
end
|
500
|
+
|
501
|
+
File.open('branch_names', 'w') { |file| file.write(JSON.generate(@projects)) }
|
502
|
+
|
503
|
+
update_drone_yml!
|
538
504
|
|
539
|
-
|
505
|
+
`git add branch_names .drone.yml`
|
506
|
+
`git commit -m 'update'`
|
507
|
+
`git push && git checkout master`
|
540
508
|
end
|
541
509
|
|
542
|
-
def
|
543
|
-
|
544
|
-
|
510
|
+
def qainit_deploy_shutdown!(selection = nil)
|
511
|
+
`git checkout master && git pull && git remote prune origin`
|
512
|
+
# leggiamo i nomi dei branch
|
513
|
+
former_branches = `git branch -a | grep remotes/ | grep -v HEAD | sed 's/ remotes\\/origin\\///g'`.split "\n"
|
514
|
+
if selection.nil?
|
515
|
+
# stampiamo la lista
|
516
|
+
chosen_branch = choose do |menu|
|
517
|
+
menu.prompt = "Scegli il QA che vuoi spegnere: ".cyan
|
518
|
+
menu.shell = true
|
519
|
+
git_user = get_git_user
|
520
|
+
former_branches.delete('master')
|
521
|
+
former_branches.each_with_index do |branch, index|
|
522
|
+
msg = index.odd? ? branch.white : branch.light_yellow # uno bianco e uno giallo alternati
|
523
|
+
msg = branch.start_with?(git_user) ? msg.on_blue : msg.on_black # i branch creati da chi lancia l'update sono su sfondo blu
|
524
|
+
menu.choice(msg) { branch }
|
525
|
+
end
|
526
|
+
end
|
527
|
+
else
|
528
|
+
chosen_branch = selection
|
529
|
+
end
|
530
|
+
# checkout master, checkout branch, pull branch, push sul branch con commit vuoto
|
531
|
+
`git checkout master && git checkout #{chosen_branch} && git pull`
|
532
|
+
`git commit --allow-empty -m 'shutdown' && git push && git checkout master`
|
533
|
+
end
|
545
534
|
|
546
|
-
|
535
|
+
def qainit_drone_shutdown!
|
536
|
+
output "Recupero le informazioni sui QA attivi..."
|
537
|
+
stack_list, envs = get_stacks
|
547
538
|
|
548
|
-
|
539
|
+
env_hash = "qa-" + get_deploy_id
|
549
540
|
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
541
|
+
cluster_stack_name = nil
|
542
|
+
stacks_to_delete = []
|
543
|
+
stack_list.each do |stack|
|
544
|
+
if stack.stack_name.match(/#{env_hash}$/)
|
545
|
+
if stack.stack_name.match(/ecs-cluster/)
|
546
|
+
cluster_stack_name = stack.stack_name
|
547
|
+
else
|
548
|
+
break unless stack.stack_name.match(/#{env_hash}$/)
|
549
|
+
stacks_to_delete.push(stack.stack_name)
|
550
|
+
delete_stack(stack.stack_name)
|
554
551
|
end
|
555
552
|
end
|
556
553
|
end
|
557
554
|
|
558
|
-
|
559
|
-
|
555
|
+
cluster_stack_name = "ecs-cluster-#{env_hash}"
|
556
|
+
if stack_exists?(cluster_stack_name)
|
557
|
+
aggregator_enabled = get_stack_tags(cluster_stack_name).detect do |tag|
|
558
|
+
tag.key === "hostname_pattern_priority" and tag.value === "1"
|
559
|
+
end.is_a?(Aws::CloudFormation::Types::Tag)
|
560
560
|
|
561
|
-
|
562
|
-
|
563
|
-
].each do |cmd|
|
564
|
-
output "Eseguo #{cmd}".yellow
|
565
|
-
res = %x[ #{cmd} ]
|
566
|
-
if $?.exitstatus != 0
|
567
|
-
color = 'red'
|
568
|
-
else
|
569
|
-
color = 'green'
|
561
|
+
if aggregator_enabled
|
562
|
+
dns_to_staging(env_hash)
|
570
563
|
end
|
571
|
-
output res.send color
|
572
|
-
exec_step "docker stop redis" if color == 'red'
|
573
|
-
stop_if (color == 'red'), "Errore durante la build dell'artifact".red
|
574
564
|
end
|
575
565
|
|
576
|
-
|
577
|
-
|
566
|
+
# Se non ha finito di cancellare le altre non si puo' cancellare il cluster
|
567
|
+
output "Attendo 10 secondi per poter eliminare il cluster ECS"
|
578
568
|
|
579
|
-
|
580
|
-
|
581
|
-
|
582
|
-
|
569
|
+
while stacks_to_delete.length > 0
|
570
|
+
sleep 13
|
571
|
+
stacks_to_delete.each do |stack_name|
|
572
|
+
stacks_to_delete = stacks_to_delete - [stack_name] unless stack_exists?(stack_name)
|
573
|
+
end
|
574
|
+
output "Stack ancora attivi: #{stacks_to_delete.length.to_s}. Attendo altri 10 secondi per eliminare il cluster ECS"
|
575
|
+
end
|
576
|
+
|
577
|
+
delete_stack(cluster_stack_name) if stack_exists?(cluster_stack_name)
|
578
|
+
delete_stack(@base_stack_name_alb + env_hash[3..8]) if stack_exists?(@base_stack_name_alb + env_hash[3..8])
|
579
|
+
delete_stack(@base_stack_name_alb_ws + env_hash[3..8]) if stack_exists?(@base_stack_name_alb_ws + env_hash[3..8])
|
580
|
+
`git checkout master && git push origin --delete ${DRONE_BRANCH}`
|
581
|
+
output "Cancello il record DNS utilizzato da Lighthouse"
|
582
|
+
delete_lighthouse_dns()
|
583
|
+
output "Finito!".green
|
583
584
|
end
|
584
585
|
|
585
|
-
def
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
586
|
+
def qainit_write_output(file_message, output_message)
|
587
|
+
`mkdir -p /etc/qainit-output`
|
588
|
+
qa_file_name = "/etc/qainit-output/url_qa"
|
589
|
+
File.open(qa_file_name + '.txt', 'w') { |file| file.write(file_message) }
|
590
|
+
output "#{output_message} #{qa_file_name}".green
|
591
|
+
end
|
590
592
|
|
591
|
-
|
593
|
+
def update_drone_yml!()
|
594
|
+
drone_yml = File.read('.drone.yml')
|
595
|
+
@projects.each do |key, project|
|
596
|
+
drone_yml = drone_yml.gsub(/#{key}@.+\n/, "#{key}@#{project['revision']}\n")
|
597
|
+
end
|
598
|
+
File.open(".drone.yml", "w") do |f|
|
599
|
+
f.write(drone_yml)
|
600
|
+
end
|
592
601
|
end
|
593
602
|
|
594
|
-
def
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
seconds_elapsed = 0
|
601
|
-
while true
|
602
|
-
break if seconds_elapsed >= sleep_seconds
|
603
|
-
print '.'.yellow; STDOUT.flush
|
604
|
-
sleep 1
|
605
|
-
seconds_elapsed += 1
|
606
|
-
end
|
603
|
+
def get_deploy_id
|
604
|
+
if @deploy_id
|
605
|
+
@deploy_id
|
606
|
+
else
|
607
|
+
@deploy_id = Digest::MD5.hexdigest(ENV['DRONE_BRANCH'])
|
608
|
+
@deploy_id
|
607
609
|
end
|
610
|
+
end
|
608
611
|
|
609
|
-
|
610
|
-
|
611
|
-
|
612
|
-
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
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
|
-
stack_body = IO.read('cloudformation/stacks/ecs-cluster.json')
|
654
|
-
create_stack(stack_name, stack_body, [], tags)
|
655
|
-
end
|
656
|
-
|
657
|
-
def import_dbs(ip_address)
|
658
|
-
resp = @ecs.run_task({
|
659
|
-
cluster: @ecs_cluster_name,
|
660
|
-
task_definition: @import_db_task,
|
661
|
-
overrides: {
|
662
|
-
container_overrides: [
|
663
|
-
{
|
664
|
-
name: 'dbrestore',
|
665
|
-
environment: [
|
666
|
-
{
|
667
|
-
name: 'EC2_IP_ADDRESS',
|
668
|
-
value: ip_address,
|
669
|
-
}
|
670
|
-
]
|
671
|
-
}
|
672
|
-
]
|
673
|
-
},
|
674
|
-
count: 1
|
675
|
-
})
|
676
|
-
output "Attendo che i DB vengano importati...\n".yellow
|
677
|
-
stopped_at = nil
|
678
|
-
while stopped_at.nil?
|
679
|
-
resp = @ecs.describe_tasks({
|
680
|
-
cluster: @ecs_cluster_name,
|
681
|
-
tasks: [resp.tasks[0].task_arn]
|
682
|
-
})
|
683
|
-
stopped_at = resp.tasks[0].stopped_at
|
684
|
-
sleep_seconds = 10
|
685
|
-
seconds_elapsed = 0
|
686
|
-
while true && stopped_at.nil?
|
687
|
-
break if seconds_elapsed >= sleep_seconds
|
688
|
-
print '.'.yellow; STDOUT.flush
|
689
|
-
sleep 1
|
690
|
-
seconds_elapsed += 1
|
691
|
-
end
|
612
|
+
def get_alb_host(stack_name)
|
613
|
+
case
|
614
|
+
when stack_name.include?('web')
|
615
|
+
logical_resource_id = 'EcsApplicationLoadBalancerPublic'
|
616
|
+
when stack_name.include?('urania')
|
617
|
+
logical_resource_id = 'EcsApplicationLoadBalancerInternal'
|
618
|
+
when stack_name.include?('backoffice')
|
619
|
+
logical_resource_id = 'EcsApplicationLoadBalancerPublic'
|
620
|
+
when stack_name.include?('bburago')
|
621
|
+
logical_resource_id = 'EcsApplicationLoadBalancerInternal'
|
622
|
+
when stack_name.include?('hal9000')
|
623
|
+
logical_resource_id = 'EcsApplicationLoadBalancerInternal'
|
624
|
+
when stack_name.include?('fidaty')
|
625
|
+
logical_resource_id = 'EcsApplicationLoadBalancerInternal'
|
626
|
+
when stack_name.include?('activia')
|
627
|
+
logical_resource_id = 'EcsApplicationLoadBalancerInternal'
|
628
|
+
when stack_name.include?('skynet')
|
629
|
+
logical_resource_id = 'EcsApplicationLoadBalancerInternal'
|
630
|
+
when stack_name.include?('roger')
|
631
|
+
logical_resource_id = 'EcsApplicationLoadBalancerInternal'
|
632
|
+
when stack_name.include?('alb-http-public')
|
633
|
+
logical_resource_id = 'EcsApplicationLoadBalancerPublic'
|
634
|
+
when stack_name.include?('alb-ws-public')
|
635
|
+
logical_resource_id = 'EcsApplicationLoadBalancerPublic'
|
636
|
+
when stack_name.include?('peano')
|
637
|
+
logical_resource_id = 'EcsApplicationLoadBalancerInternal'
|
638
|
+
when stack_name.include?('leftorium')
|
639
|
+
logical_resource_id = 'EcsApplicationLoadBalancerInternal'
|
640
|
+
when stack_name.include?('assange')
|
641
|
+
logical_resource_id = 'EcsApplicationLoadBalancerPublic'
|
642
|
+
when stack_name.include?('borat')
|
643
|
+
logical_resource_id = 'EcsApplicationLoadBalancerPublic'
|
644
|
+
when stack_name.include?('crash')
|
645
|
+
logical_resource_id = 'EcsApplicationLoadBalancerPublic'
|
646
|
+
when stack_name.include?('rachele')
|
647
|
+
logical_resource_id = 'EcsApplicationLoadBalancerInternal'
|
648
|
+
when stack_name.include?('starsky')
|
649
|
+
logical_resource_id = 'EcsApplicationLoadBalancerPublic'
|
650
|
+
when stack_name.include?('hutch')
|
651
|
+
logical_resource_id = 'EcsApplicationLoadBalancerPublic'
|
652
|
+
when stack_name.include?('maia')
|
653
|
+
logical_resource_id = 'EcsApplicationLoadBalancerPublic'
|
654
|
+
when stack_name.include?('legion')
|
655
|
+
logical_resource_id = 'EcsApplicationLoadBalancerInternal'
|
692
656
|
end
|
693
|
-
|
657
|
+
resp = describe_stack_resource(stack_name, logical_resource_id)
|
658
|
+
resp = describe_load_balancers([resp.stack_resource_detail.physical_resource_id])
|
659
|
+
resp.load_balancers[0].dns_name
|
694
660
|
end
|
695
661
|
|
696
|
-
def
|
697
|
-
|
698
|
-
|
699
|
-
stack_name: stack_name
|
700
|
-
})
|
701
|
-
rescue Aws::CloudFormation::Errors::ValidationError => e
|
702
|
-
if e.message.include? 'does not exist'
|
703
|
-
false
|
704
|
-
else
|
705
|
-
raise e
|
706
|
-
end
|
662
|
+
def deploy_pyxis?
|
663
|
+
if defined? @deploy_pyxis
|
664
|
+
@deploy_pyxis
|
707
665
|
else
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
stack_name: stack_name,
|
715
|
-
template_body: stack_body,
|
716
|
-
parameters: parameters,
|
717
|
-
tags: tags,
|
718
|
-
capabilities: ["CAPABILITY_IAM"],
|
719
|
-
on_failure: "ROLLBACK"
|
720
|
-
})
|
721
|
-
output "La creazione dello stack #{stack_name} è stata avviata".green
|
722
|
-
end
|
723
|
-
|
724
|
-
def update_stack(stack_name, stack_body, parameters = [])
|
725
|
-
begin
|
726
|
-
@cf.update_stack({
|
727
|
-
stack_name: stack_name,
|
728
|
-
template_body: stack_body,
|
729
|
-
parameters: parameters,
|
730
|
-
capabilities: ["CAPABILITY_IAM"]
|
731
|
-
})
|
732
|
-
rescue Aws::CloudFormation::Errors::ValidationError => e
|
733
|
-
# if e.message.include? 'does not exist'
|
734
|
-
# false
|
735
|
-
# else
|
736
|
-
# raise e
|
737
|
-
# end
|
738
|
-
raise e
|
739
|
-
else
|
740
|
-
output "L'update dello stack #{stack_name} è stato avviato".green
|
666
|
+
pyxis_updated = `git log -p -1 --unified=0 | grep pyxis-npm:`.length > 0
|
667
|
+
|
668
|
+
update_pyxis = !@projects['pyxis-npm'].empty? && @projects['pyxis-npm']['name'] != 'master' && pyxis_updated
|
669
|
+
|
670
|
+
@deploy_pyxis = update_pyxis
|
671
|
+
return update_pyxis
|
741
672
|
end
|
742
673
|
end
|
743
674
|
|
744
|
-
def
|
745
|
-
|
746
|
-
|
747
|
-
max_keys: 1,
|
748
|
-
prefix: path
|
749
|
-
})
|
750
|
-
!resp.contents.empty?
|
675
|
+
def update_cluster_stack(stack_name, tags = [])
|
676
|
+
stack_body = IO.read('cloudformation/stacks/ecs-cluster.yml')
|
677
|
+
update_stack(stack_name, stack_body, [], tags)
|
751
678
|
end
|
752
679
|
|
753
|
-
def choose_branch_to_deploy(project_name)
|
680
|
+
def choose_branch_to_deploy(project_name, select_master = false)
|
754
681
|
Dir.chdir "projects/#{project_name}"
|
755
682
|
output "Recupero la lista dei branch del progetto #{project_name}..."
|
683
|
+
`git remote prune origin`
|
756
684
|
out = %x[ git fetch ]
|
757
|
-
branches = %x[ git for-each-ref --sort=-committerdate refs/remotes/ --format='%(refname) %(objectname)' | sed 's/refs\\/remotes\\/origin\\///g' ]
|
758
|
-
.split("\n").delete_if { |b| b.include?('HEAD')
|
685
|
+
branches = %x[ git for-each-ref --sort=-committerdate refs/remotes/ --format='%(refname) %(objectname) %(committeremail)' | sed 's/refs\\/remotes\\/origin\\///g' ]
|
686
|
+
.split("\n").delete_if { |b| b.include?('HEAD') }[0..49]
|
759
687
|
|
760
|
-
|
761
|
-
menu.prompt = "Scegli il branch di #{project_name} da deployare: ".cyan
|
762
|
-
menu.shell = true
|
688
|
+
master_branch = nil
|
763
689
|
|
764
|
-
|
690
|
+
branches.each do |branch|
|
691
|
+
master_branch = branch if branch.match(/^master\s+/)
|
692
|
+
break unless master_branch.nil?
|
693
|
+
end
|
765
694
|
|
766
|
-
|
767
|
-
|
768
|
-
|
695
|
+
if select_master || branches.length == 1
|
696
|
+
branch_name = master_branch
|
697
|
+
else
|
698
|
+
branches.insert(0, branches.delete(master_branch))
|
699
|
+
branch_name = choose do |menu|
|
700
|
+
menu.prompt = "Scegli il branch di #{project_name} da deployare: ".cyan
|
701
|
+
menu.shell = true
|
702
|
+
|
703
|
+
git_mail = get_git_mail
|
704
|
+
|
705
|
+
branches.each_with_index do |branch, index|
|
706
|
+
title = @prima.reduce_size(branch, 100)
|
707
|
+
msg = index.odd? ? title.white : title.light_yellow # uno bianco e uno giallo alternati
|
708
|
+
msg = branch.include?(git_mail) ? msg.on_blue : msg.on_black # i branch aggiornati da chi lancia la creazione sono su sfondo blu
|
709
|
+
menu.choice(msg) { branch }
|
710
|
+
menu.default = branch if branch == master_branch
|
711
|
+
end
|
769
712
|
end
|
770
713
|
end
|
771
714
|
|
772
715
|
Dir.chdir "../../"
|
773
716
|
|
774
|
-
name = branch_name.split(' ')
|
775
|
-
revision = branch_name.split(' ')
|
776
|
-
|
717
|
+
name = branch_name.split(' ')[0]
|
718
|
+
revision = branch_name.split(' ')[1]
|
719
|
+
committer_email = branch_name.split(' ')[2].tr('<>', '')
|
720
|
+
{ 'name' => name, 'revision' => revision[0..14], 'committer' => committer_email, 'default_branch' => select_master }
|
777
721
|
end
|
778
722
|
|
723
|
+
def select_branch_to_deploy(project_name, branch_name)
|
724
|
+
Dir.chdir "projects/#{project_name}"
|
725
|
+
output "Recupero il branch #{project_name}:#{branch_name} ..."
|
726
|
+
`git remote prune origin`
|
727
|
+
out = %x[ git fetch ]
|
728
|
+
branch_name = %x[ git for-each-ref --sort=-committerdate refs/remotes/ --format='%(refname) %(objectname) %(committeremail)' | sed 's/refs\\/remotes\\/origin\\///g' ]
|
729
|
+
.split("\n").delete_if { |b| !b.match("^#{Regexp.escape(branch_name)}") }[0..49]
|
730
|
+
.first
|
731
|
+
|
732
|
+
Dir.chdir "../../"
|
733
|
+
name = branch_name.split(' ')[0]
|
734
|
+
revision = branch_name.split(' ')[1]
|
735
|
+
committer_email = branch_name.split(' ')[2].tr('<>', '')
|
736
|
+
{ 'name' => name, 'revision' => revision[0..14], 'committer' => committer_email }
|
737
|
+
end
|
738
|
+
|
739
|
+
def get_stacks()
|
740
|
+
envs = {}
|
741
|
+
stack_list = stack_list()
|
742
|
+
stack_list.each do |stack|
|
743
|
+
unless stack.stack_name.match(/spotfleet-allinone-qa-(\w+)$/)
|
744
|
+
env_hash = stack.stack_name.match(/qa-(\w+)$/)[0]
|
745
|
+
envs[env_hash] = stack.tags unless envs.has_key?(env_hash) || stack.tags.empty?
|
746
|
+
end
|
747
|
+
end
|
748
|
+
return stack_list, envs
|
749
|
+
end
|
750
|
+
|
751
|
+
def get_clusters()
|
752
|
+
envs = {}
|
753
|
+
cluster_list = cluster_list()
|
754
|
+
cluster_list.each do |stack|
|
755
|
+
unless stack.stack_name.match(/spotfleet-allinone-qa-(\w+)$/)
|
756
|
+
env_hash = stack.stack_name.match(/qa-(\w+)$/)[0]
|
757
|
+
envs[env_hash] = stack.tags unless envs.has_key?(env_hash) || stack.tags.empty?
|
758
|
+
end
|
759
|
+
end
|
760
|
+
return cluster_list, envs
|
761
|
+
end
|
762
|
+
|
763
|
+
def hostname_pattern_priority()
|
764
|
+
(Time.now.to_i.to_s[-4..-1].to_i + Random.rand(40000)).to_s
|
765
|
+
end
|
766
|
+
|
767
|
+
def select_branches(project_names = nil)
|
768
|
+
output "Deploy feature menu"
|
769
|
+
if project_names.nil?
|
770
|
+
@projects.each{ |key, value| @projects[key] = choose_branch_to_deploy(key) }
|
771
|
+
else
|
772
|
+
project_names.each do |project|
|
773
|
+
@projects[project] = choose_branch_to_deploy(project)
|
774
|
+
end
|
775
|
+
@projects.each_key do |branch_project|
|
776
|
+
@projects[branch_project] = choose_branch_to_deploy(branch_project, true) unless project_names.include? branch_project
|
777
|
+
end
|
778
|
+
end
|
779
|
+
end
|
779
780
|
end
|
780
781
|
|
781
782
|
def help_content
|
@@ -792,14 +793,24 @@ Synopsis
|
|
792
793
|
twig release start
|
793
794
|
twig release finish
|
794
795
|
twig release deploy
|
796
|
+
twig release aggregator
|
795
797
|
|
796
798
|
Description
|
797
799
|
-----------
|
798
800
|
|
799
|
-
start
|
800
|
-
finish
|
801
|
-
|
802
|
-
|
801
|
+
start creates a new feature branch
|
802
|
+
finish finishes the feature by merging to dev and master
|
803
|
+
qainit deploys a new environment with selected branches from every project
|
804
|
+
qainit $PROJECT_NAME deploys a new environment allowing to selected a branch from the input project (everything else is master)
|
805
|
+
qainit shutdown deletes a specific qa environment
|
806
|
+
|
807
|
+
Available only to devops (from artemide)
|
808
|
+
-----------
|
809
|
+
deploy deploys the feature branch to a temporary AWS Elastic Beanstalk env
|
810
|
+
deploy stop destroys the AWS Elastic Beanstalk env
|
811
|
+
deploy update updates a feature branch with current branches
|
812
|
+
deploy lock protects a qa environment from automatic deletion
|
813
|
+
aggregator enable/disable directs comparator's staging environments to a qa/staging
|
803
814
|
|
804
815
|
Subcommand for Twig: <http://rondevera.github.io/twig/>
|
805
816
|
Author: Andrea Usuelli <https://github.com/andreausu>
|
@@ -814,4 +825,11 @@ if args.include?('--help')
|
|
814
825
|
exit
|
815
826
|
end
|
816
827
|
|
817
|
-
|
828
|
+
gem_update = true
|
829
|
+
if args.include?('no-gem-update')
|
830
|
+
gem_update = false
|
831
|
+
end
|
832
|
+
|
833
|
+
args.delete('no-gem-update')
|
834
|
+
|
835
|
+
Release.new(gem_update).execute!(args)
|