prima-twig 0.5.0 → 0.5.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/bin/twig-build +2000 -0
- data/bin/twig-deploy +126 -89
- data/bin/twig-feature +632 -698
- 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,53 +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-8A9N41PAYMJ2:1'
|
23
|
-
@prima_built = false
|
24
|
-
@urania_built = false
|
25
|
-
@ermes_built = false
|
26
|
-
@bburago_built = false
|
27
|
-
@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
|
28
25
|
@dns_record_identifier = nil
|
29
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'])
|
30
55
|
end
|
31
56
|
|
32
|
-
def execute!
|
57
|
+
def execute!(args)
|
33
58
|
case args[0]
|
34
|
-
when
|
59
|
+
when 'start'
|
35
60
|
start_feature!
|
36
|
-
when
|
61
|
+
when 'finish'
|
37
62
|
finish_feature!
|
38
|
-
when
|
63
|
+
when 'qainit'
|
64
|
+
abort('Non sei nella cartella di qainit') unless Dir.pwd.match 'qainit$' or Dir.pwd.match '/drone/src'
|
39
65
|
if ['terminate', 'stop', 'shutdown', 'halt', 'destroy'].include? args[1]
|
40
|
-
|
66
|
+
qainit_deploy_shutdown!
|
67
|
+
elsif 'update' == args[1]
|
68
|
+
qainit_deploy_update!
|
41
69
|
else
|
42
|
-
|
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!
|
93
|
+
else
|
94
|
+
stop_for_wrong_args
|
43
95
|
end
|
44
96
|
else
|
45
|
-
|
97
|
+
stop_for_wrong_args
|
46
98
|
end
|
47
99
|
end
|
48
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
|
+
|
49
106
|
def start_feature!
|
50
107
|
branch_name = @prima.clean_branch_name(ask('Inserisci il nome del branch (puoi omettere feature/): '.cyan))
|
51
|
-
stop_unless branch_name.
|
108
|
+
stop_unless !branch_name.empty?, 'Devi inserire il nome del branch'
|
52
109
|
branch_name.prepend 'feature/' unless branch_name.include? 'feature'
|
53
110
|
|
54
111
|
output "Il nome del branch sarà " + branch_name.yellow
|
@@ -58,6 +115,135 @@ class Release
|
|
58
115
|
exec_step "git checkout -b " + branch_name
|
59
116
|
end
|
60
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
|
+
|
61
247
|
def finish_feature!
|
62
248
|
current_branch_name = @prima.twig.current_branch_name
|
63
249
|
stop_unless (current_branch_name =~ /^feature\//), "Non sei su un branch di feature, non posso mergiare nulla"
|
@@ -78,11 +264,8 @@ class Release
|
|
78
264
|
end
|
79
265
|
|
80
266
|
def deploy_shutdown!
|
81
|
-
|
82
|
-
stack_list
|
83
|
-
env_hash = stack.stack_name.match(/qa-(\w+)$/)[0]
|
84
|
-
envs[env_hash] = stack.tags unless envs.has_key?(env_hash)
|
85
|
-
end
|
267
|
+
output "Recupero le informazioni sui QA attivi..."
|
268
|
+
stack_list, envs = get_stacks
|
86
269
|
|
87
270
|
env_hash = nil
|
88
271
|
unless envs.empty?
|
@@ -91,775 +274,509 @@ class Release
|
|
91
274
|
menu.shell = true
|
92
275
|
|
93
276
|
envs.each do |key, env|
|
94
|
-
title =
|
95
|
-
|
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
|
96
282
|
menu.choice(msg) { key }
|
97
283
|
end
|
98
284
|
end
|
99
285
|
else
|
100
|
-
output
|
286
|
+
output 'Nessun environment trovato'.red
|
101
287
|
exit
|
102
288
|
end
|
103
289
|
|
104
290
|
cluster_stack_name = nil
|
291
|
+
stacks_to_delete = []
|
105
292
|
stack_list.each do |stack|
|
106
293
|
if stack.stack_name.match(/#{env_hash}$/)
|
107
294
|
if stack.stack_name.match(/ecs-cluster/)
|
108
295
|
cluster_stack_name = stack.stack_name
|
109
296
|
else
|
110
|
-
|
297
|
+
break unless stack.stack_name.match(/#{env_hash}$/)
|
298
|
+
stacks_to_delete.push(stack.stack_name)
|
299
|
+
delete_stack(stack.stack_name)
|
111
300
|
end
|
112
301
|
end
|
113
302
|
end
|
114
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
|
+
|
115
313
|
# Se non ha finito di cancellare le altre non si puo' cancellare il cluster
|
116
|
-
output "Attendo
|
117
|
-
|
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
|
+
|
118
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])
|
119
327
|
output "Finito!".green
|
120
328
|
end
|
121
329
|
|
122
|
-
def
|
123
|
-
|
330
|
+
def deploy_lock!
|
331
|
+
output "Deploy update menu"
|
124
332
|
`git pull && git submodule init && git submodule update`
|
125
|
-
prima_branch = choose_branch_to_deploy('prima')
|
126
|
-
backoffice_branch = choose_branch_to_deploy('backoffice')
|
127
|
-
urania_branch = choose_branch_to_deploy('urania')
|
128
|
-
ermes_branch = choose_branch_to_deploy('ermes')
|
129
|
-
bburago_branch = choose_branch_to_deploy('bburago')
|
130
|
-
socket_branch = {name: "master"}
|
131
|
-
pamela_branch = {name: "master"}
|
132
|
-
|
133
|
-
@dns_record_identifier = "#{@prima.clean_branch_name(prima_branch[:name])}-#{@prima.clean_branch_name(backoffice_branch[:name])}-#{@prima.clean_branch_name(urania_branch[:name])}-#{@prima.clean_branch_name(ermes_branch[:name])}-#{@prima.clean_branch_name(bburago_branch[:name])}".gsub(/feature./, '')[0..35].gsub(/(-+$)/, '')
|
134
|
-
|
135
|
-
tags = [
|
136
|
-
{
|
137
|
-
key: "prima",
|
138
|
-
value: prima_branch[:name]
|
139
|
-
},
|
140
|
-
{
|
141
|
-
key: "urania",
|
142
|
-
value: urania_branch[:name]
|
143
|
-
},
|
144
|
-
{
|
145
|
-
key: "backoffice",
|
146
|
-
value: backoffice_branch[:name]
|
147
|
-
},
|
148
|
-
{
|
149
|
-
key: "ermes",
|
150
|
-
value: ermes_branch[:name]
|
151
|
-
},
|
152
|
-
{
|
153
|
-
key: "bburago",
|
154
|
-
value: bburago_branch[:name]
|
155
|
-
}
|
156
|
-
]
|
157
|
-
|
158
|
-
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])
|
159
|
-
|
160
|
-
cluster_stack_name = "ecs-cluster-qa-#{deploy_id}"
|
161
|
-
create_cluster_stack(cluster_stack_name, tags) unless stack_exists?(cluster_stack_name)
|
162
|
-
wait_for_stack_ready(cluster_stack_name) unless stack_ready?(cluster_stack_name)
|
163
|
-
|
164
|
-
resp = @cf.describe_stack_resource({stack_name: cluster_stack_name, logical_resource_id: 'ECSCluster'})
|
165
|
-
@ecs_cluster_name = resp.stack_resource_detail.physical_resource_id
|
166
|
-
|
167
|
-
asg_stack_name = "ecs-asg-allinone-qa-#{deploy_id}"
|
168
|
-
create_asg_stack(asg_stack_name, tags) unless stack_exists?(asg_stack_name)
|
169
|
-
|
170
|
-
stack_name_db = "ecs-task-db-qa-#{deploy_id}"
|
171
|
-
stack_body = IO.read('cloudformation/stacks/task/db.json')
|
172
|
-
parameters = [
|
173
|
-
{
|
174
|
-
parameter_key: "Environment",
|
175
|
-
parameter_value: "qa"
|
176
|
-
},
|
177
|
-
{
|
178
|
-
parameter_key: "ECSClusterName",
|
179
|
-
parameter_value: @ecs_cluster_name
|
180
|
-
}
|
181
|
-
]
|
182
|
-
create_stack(stack_name_db, stack_body, parameters, tags) unless stack_exists?(stack_name_db)
|
183
|
-
|
184
|
-
create_prima_artifact(prima_branch[:revision], prima_branch[:name]) unless artifact_exists?('prima-artifacts', "prima/#{prima_branch[:revision]}")
|
185
|
-
create_urania_artifact(urania_branch[:revision]) unless artifact_exists?('prima-artifacts', "microservices/urania/#{urania_branch[:revision]}-qa.tar.gz")
|
186
|
-
create_ermes_artifact(ermes_branch[:revision]) unless artifact_exists?('prima-artifacts', "microservices/ermes/ermes_#{ermes_branch[:revision]}.tar.gz")
|
187
|
-
create_bburago_artifact(bburago_branch[:revision]) unless artifact_exists?('prima-artifacts', "microservices/bburago/bburago_#{bburago_branch[:revision]}.tar.gz")
|
188
|
-
create_backoffice_artifact(backoffice_branch[:revision], deploy_id) unless artifact_exists?('prima-artifacts', "backoffice/#{backoffice_branch[:revision]}-#{deploy_id}.zip")
|
189
|
-
|
190
|
-
wait_for_stack_ready(stack_name_db) unless stack_ready?(stack_name_db)
|
191
|
-
|
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.json')
|
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
|
-
if stack_exists?(stack_name_web)
|
216
|
-
update_stack(stack_name_web, stack_body, parameters) if @prima_built
|
217
|
-
else
|
218
|
-
create_stack(stack_name_web, stack_body, parameters, tags)
|
219
|
-
end
|
220
|
-
|
221
|
-
stack_name_consumer = "ecs-task-consumer-qa-#{deploy_id}"
|
222
|
-
git_checkout_version('prima', prima_branch[:revision])
|
223
|
-
stack_body = IO.read('projects/prima/app/cloudformation/tasks/consumer.json')
|
224
|
-
parameters = [
|
225
|
-
{
|
226
|
-
parameter_key: "Environment",
|
227
|
-
parameter_value: "qa"
|
228
|
-
},
|
229
|
-
{
|
230
|
-
parameter_key: "ReleaseVersion",
|
231
|
-
parameter_value: prima_branch[:revision]
|
232
|
-
},
|
233
|
-
{
|
234
|
-
parameter_key: "ECSClusterName",
|
235
|
-
parameter_value: @ecs_cluster_name
|
236
|
-
}
|
237
|
-
]
|
238
|
-
if stack_exists?(stack_name_consumer)
|
239
|
-
update_stack(stack_name_consumer, stack_body, parameters) if @prima_built
|
240
|
-
else
|
241
|
-
create_stack(stack_name_consumer, stack_body, parameters, tags)
|
242
|
-
end
|
243
|
-
|
244
|
-
stack_name_urania = "ecs-task-urania-qa-#{deploy_id}"
|
245
|
-
git_checkout_version('urania', urania_branch[:revision])
|
246
|
-
stack_body = IO.read('projects/urania/deploy/task.json')
|
247
|
-
parameters = [
|
248
|
-
{
|
249
|
-
parameter_key: "Environment",
|
250
|
-
parameter_value: "qa"
|
251
|
-
},
|
252
|
-
{
|
253
|
-
parameter_key: "ReleaseVersion",
|
254
|
-
parameter_value: urania_branch[:revision]
|
255
|
-
},
|
256
|
-
{
|
257
|
-
parameter_key: "TaskDesiredCount",
|
258
|
-
parameter_value: "1"
|
259
|
-
},
|
260
|
-
{
|
261
|
-
parameter_key: "ECSClusterName",
|
262
|
-
parameter_value: @ecs_cluster_name
|
263
|
-
}
|
264
|
-
]
|
265
|
-
if stack_exists?(stack_name_urania)
|
266
|
-
update_stack(stack_name_urania, stack_body, parameters) if @urania_built
|
267
|
-
else
|
268
|
-
create_stack(stack_name_urania, stack_body, parameters, tags)
|
269
|
-
end
|
270
|
-
|
271
|
-
stack_name_ermes = "ecs-task-ermes-qa-#{deploy_id}"
|
272
|
-
git_checkout_version('ermes', ermes_branch[:revision])
|
273
|
-
stack_body = IO.read('projects/ermes/deploy/task.json')
|
274
|
-
parameters = [
|
275
|
-
{
|
276
|
-
parameter_key: "Environment",
|
277
|
-
parameter_value: "qa"
|
278
|
-
},
|
279
|
-
{
|
280
|
-
parameter_key: "ReleaseVersion",
|
281
|
-
parameter_value: ermes_branch[:revision]
|
282
|
-
},
|
283
|
-
{
|
284
|
-
parameter_key: "ECSClusterName",
|
285
|
-
parameter_value: @ecs_cluster_name
|
286
|
-
}
|
287
|
-
]
|
288
|
-
if stack_exists?(stack_name_ermes)
|
289
|
-
update_stack(stack_name_ermes, stack_body, parameters) if @ermes_built
|
290
|
-
else
|
291
|
-
create_stack(stack_name_ermes, stack_body, parameters, tags)
|
292
|
-
end
|
293
|
-
|
294
|
-
stack_name_bburago = "ecs-task-bburago-qa-#{deploy_id}"
|
295
|
-
git_checkout_version('bburago', bburago_branch[:revision])
|
296
|
-
stack_body = IO.read('projects/bburago/deploy/task.json')
|
297
|
-
parameters = [
|
298
|
-
{
|
299
|
-
parameter_key: "Environment",
|
300
|
-
parameter_value: "qa"
|
301
|
-
},
|
302
|
-
{
|
303
|
-
parameter_key: "ReleaseVersion",
|
304
|
-
parameter_value: bburago_branch[:revision]
|
305
|
-
},
|
306
|
-
{
|
307
|
-
parameter_key: "ECSClusterName",
|
308
|
-
parameter_value: @ecs_cluster_name
|
309
|
-
},
|
310
|
-
{
|
311
|
-
parameter_key: "TaskDesiredCount",
|
312
|
-
parameter_value: "1"
|
313
|
-
}
|
314
|
-
]
|
315
|
-
if stack_exists?(stack_name_bburago)
|
316
|
-
update_stack(stack_name_bburago, stack_body, parameters) if @bburago_built
|
317
|
-
else
|
318
|
-
create_stack(stack_name_bburago, stack_body, parameters, tags)
|
319
|
-
end
|
320
|
-
|
321
|
-
git_checkout_version('backoffice', backoffice_branch[:revision])
|
322
|
-
stack_name_backoffice = "ecs-task-backoffice-qa-#{deploy_id}"
|
323
|
-
stack_body = IO.read('projects/backoffice/deploy/task.json')
|
324
|
-
parameters = [
|
325
|
-
{
|
326
|
-
parameter_key: "Environment",
|
327
|
-
parameter_value: "qa"
|
328
|
-
},
|
329
|
-
{
|
330
|
-
parameter_key: "ReleaseVersion",
|
331
|
-
parameter_value: "#{backoffice_branch[:revision]}-#{deploy_id}"
|
332
|
-
},
|
333
|
-
{
|
334
|
-
parameter_key: "TaskDesiredCount",
|
335
|
-
parameter_value: "1"
|
336
|
-
},
|
337
|
-
{
|
338
|
-
parameter_key: "ECSClusterName",
|
339
|
-
parameter_value: @ecs_cluster_name
|
340
|
-
}
|
341
|
-
]
|
342
|
-
if stack_exists?(stack_name_backoffice)
|
343
|
-
update_stack(stack_name_backoffice, stack_body, parameters) if @backoffice_built
|
344
|
-
else
|
345
|
-
create_stack(stack_name_backoffice, stack_body, parameters, tags)
|
346
|
-
end
|
347
333
|
|
348
|
-
|
349
|
-
wait_for_stack_ready(stack_name_consumer) unless stack_ready?(stack_name_consumer)
|
350
|
-
wait_for_stack_ready(stack_name_urania) unless stack_ready?(stack_name_urania)
|
351
|
-
wait_for_stack_ready(stack_name_backoffice) unless stack_ready?(stack_name_backoffice)
|
352
|
-
wait_for_stack_ready(stack_name_ermes) unless stack_ready?(stack_name_ermes)
|
353
|
-
wait_for_stack_ready(stack_name_bburago) unless stack_ready?(stack_name_bburago)
|
354
|
-
|
355
|
-
update_service_defaults(stack_name_web)
|
356
|
-
update_service_defaults(stack_name_consumer)
|
357
|
-
update_service_defaults(stack_name_urania)
|
358
|
-
update_service_defaults(stack_name_backoffice)
|
359
|
-
update_service_defaults(stack_name_ermes)
|
360
|
-
update_service_defaults(stack_name_bburago)
|
361
|
-
|
362
|
-
stack_name_route53 = "ecs-route53-qa-#{deploy_id}"
|
363
|
-
stack_body = IO.read('cloudformation/stacks/route53/qa.json')
|
364
|
-
parameters = [
|
365
|
-
{
|
366
|
-
parameter_key: "DnsRecordIdentifier",
|
367
|
-
parameter_value: @dns_record_identifier
|
368
|
-
},
|
369
|
-
{
|
370
|
-
parameter_key: "PrimaElbHostname",
|
371
|
-
parameter_value: get_elb_host(stack_name_web)
|
372
|
-
},
|
373
|
-
{
|
374
|
-
parameter_key: "BackofficeElbHostname",
|
375
|
-
parameter_value: get_elb_host(stack_name_backoffice)
|
376
|
-
},
|
377
|
-
{
|
378
|
-
parameter_key: "UraniaElbHostname",
|
379
|
-
parameter_value: get_elb_host(stack_name_urania)
|
380
|
-
},
|
381
|
-
{
|
382
|
-
parameter_key: "BburagoElbHostname",
|
383
|
-
parameter_value: get_elb_host(stack_name_bburago)
|
384
|
-
}
|
385
|
-
]
|
386
|
-
create_stack(stack_name_route53, stack_body, parameters, tags) unless stack_exists?(stack_name_route53)
|
387
|
-
|
388
|
-
prima_hostname = get_route53_hostname(stack_name_web)
|
389
|
-
urania_hostname = get_route53_hostname(stack_name_urania)
|
390
|
-
bburago_hostname = get_route53_hostname(stack_name_bburago)
|
391
|
-
backoffice_hostname = get_route53_hostname(stack_name_backoffice)
|
392
|
-
|
393
|
-
wait_for_stack_ready(stack_name_route53) unless stack_ready?(stack_name_route53)
|
394
|
-
|
395
|
-
output "Prima url: #{prima_hostname}\n".cyan
|
396
|
-
output "Urania url: #{urania_hostname}\n".cyan
|
397
|
-
output "Backoffice url: #{backoffice_hostname}\n".cyan
|
398
|
-
output "Bburago url: #{bburago_hostname}\n".cyan
|
399
|
-
output "SSH connection: ssh ec2-user@#{ec2_ip_address(asg_stack_name)} -i ~/.ssh/ecs-cluster-qa.pem".cyan
|
400
|
-
output "Deploy effettuato, everything is awesome!\n".green
|
401
|
-
end
|
402
|
-
|
403
|
-
def get_route53_hostname(stack_name)
|
404
|
-
case
|
405
|
-
when stack_name.include?('web')
|
406
|
-
host = "www.#{@dns_record_identifier}.qa.colaster.com"
|
407
|
-
when stack_name.include?('urania')
|
408
|
-
host = "urania.#{@dns_record_identifier}.qa.colaster.com"
|
409
|
-
when stack_name.include?('backoffice')
|
410
|
-
host = "backoffice.#{@dns_record_identifier}.qa.colaster.com"
|
411
|
-
when stack_name.include?('bburago')
|
412
|
-
host = "bburago.#{@dns_record_identifier}.qa.colaster.com"
|
413
|
-
end
|
414
|
-
host
|
415
|
-
end
|
334
|
+
@deploy_update = true
|
416
335
|
|
417
|
-
|
418
|
-
|
419
|
-
stack_name: asg_stack_name,
|
420
|
-
logical_resource_id: 'ECSAutoScalingGroup'
|
421
|
-
})
|
422
|
-
resp = @asg.describe_auto_scaling_groups({
|
423
|
-
auto_scaling_group_names: [resp.stack_resource_detail.physical_resource_id],
|
424
|
-
max_records: 1
|
425
|
-
})
|
426
|
-
instance_id = resp.auto_scaling_groups[0].instances[0].instance_id
|
427
|
-
resp = @ec2.describe_instances({instance_ids: [instance_id]})
|
428
|
-
resp.reservations[0].instances[0].private_ip_address
|
429
|
-
end
|
336
|
+
output "Recupero le informazioni sui QA attivi..."
|
337
|
+
stack_list, envs = get_clusters()
|
430
338
|
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
|
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
|
353
|
+
else
|
354
|
+
output "Nessun QA trovato".red
|
355
|
+
exit
|
441
356
|
end
|
442
|
-
resp = @cf.describe_stack_resource({
|
443
|
-
stack_name: stack_name,
|
444
|
-
logical_resource_id: logical_resource_id
|
445
|
-
})
|
446
|
-
resp = @elb.describe_load_balancers({
|
447
|
-
load_balancer_names: [resp.stack_resource_detail.physical_resource_id],
|
448
|
-
page_size: 1
|
449
|
-
})
|
450
|
-
resp.load_balancer_descriptions[0].dns_name
|
451
|
-
end
|
452
357
|
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
logical_resource_id = 'ECSServiceConsumer'
|
459
|
-
when stack_name.include?('urania')
|
460
|
-
logical_resource_id = 'ECSServiceUrania'
|
461
|
-
when stack_name.include?('backoffice')
|
462
|
-
logical_resource_id = 'ECSServiceBackoffice'
|
463
|
-
when stack_name.include?('ermes')
|
464
|
-
logical_resource_id = 'ECSServiceErmes'
|
465
|
-
when stack_name.include?('bburago')
|
466
|
-
logical_resource_id = 'ECSServiceBburago'
|
467
|
-
else
|
468
|
-
raise "Service name non gestito per lo stack #{stack_name}"
|
469
|
-
end
|
470
|
-
resp = @cf.describe_stack_resource({
|
471
|
-
stack_name: stack_name,
|
472
|
-
logical_resource_id: logical_resource_id
|
473
|
-
})
|
474
|
-
resp = @ecs.update_service({
|
475
|
-
cluster: @ecs_cluster_name,
|
476
|
-
service: resp.stack_resource_detail.physical_resource_id,
|
477
|
-
deployment_configuration: {
|
478
|
-
minimum_healthy_percent: 0,
|
479
|
-
maximum_percent: 100
|
480
|
-
}
|
481
|
-
})
|
482
|
-
end
|
483
|
-
|
484
|
-
def create_urania_artifact(revision)
|
485
|
-
@urania_built = true
|
486
|
-
output "Preparo l'artifact .zip\n".yellow
|
487
|
-
|
488
|
-
git_checkout_version('urania', revision)
|
489
|
-
|
490
|
-
Dir.chdir 'projects/urania'
|
491
|
-
|
492
|
-
[
|
493
|
-
"docker-compose build web",
|
494
|
-
"docker run -v $PWD:/code -w /code -e MIX_ENV=qa --entrypoint /bin/sh urania_web \
|
495
|
-
'-c' 'mix local.hex --force && mix hex.info && \
|
496
|
-
mix deps.get && mix compile && mix deps.compile && \
|
497
|
-
mix release.clean --implode --no-confirm && mix release'",
|
498
|
-
"sudo chown -R `whoami` ."
|
499
|
-
].each do |cmd|
|
500
|
-
output "Eseguo #{cmd}".yellow
|
501
|
-
res = %x[ #{cmd} ]
|
502
|
-
if $?.exitstatus != 0
|
503
|
-
color = 'red'
|
504
|
-
else
|
505
|
-
color = 'green'
|
506
|
-
end
|
507
|
-
output res.send color
|
508
|
-
stop_if (color == 'red'), "Errore durante la build dell'artifact".red
|
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
|
509
363
|
end
|
510
364
|
|
511
|
-
|
512
|
-
upload_artifact(artifact_path, "microservices/urania/#{revision}-qa.tar.gz")
|
365
|
+
update_cluster_stack(cluster_stack_name, tags)
|
513
366
|
|
514
|
-
|
367
|
+
output "Finito!".green
|
515
368
|
end
|
516
369
|
|
517
|
-
def
|
518
|
-
|
519
|
-
|
370
|
+
def deploy_update!
|
371
|
+
output "Deploy update menu"
|
372
|
+
`git pull && git submodule init && git submodule update`
|
520
373
|
|
521
|
-
|
374
|
+
@deploy_update = true
|
522
375
|
|
523
|
-
|
376
|
+
output "Recupero le informazioni sui QA attivi..."
|
377
|
+
stack_list, envs = get_stacks()
|
524
378
|
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
532
|
-
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
color = 'green'
|
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
|
539
392
|
end
|
540
|
-
|
541
|
-
|
393
|
+
else
|
394
|
+
output "Nessun QA trovato".red
|
395
|
+
exit
|
542
396
|
end
|
543
397
|
|
544
|
-
|
545
|
-
|
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!
|
546
404
|
|
547
|
-
|
405
|
+
output "Finito!".green
|
548
406
|
end
|
549
407
|
|
550
|
-
def
|
551
|
-
|
552
|
-
|
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
|
553
413
|
|
554
|
-
|
414
|
+
def suite_py_branches(args_json)
|
415
|
+
arg_projects = JSON.parse(args_json)
|
555
416
|
|
556
|
-
|
417
|
+
@projects.merge!(arg_projects)
|
557
418
|
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
'-c' 'mix local.hex --force && mix hex.info && \
|
562
|
-
mix deps.get && mix compile && mix deps.compile && \
|
563
|
-
mix release.clean --implode --no-confirm && mix release'",
|
564
|
-
"sudo chown -R `whoami` ."
|
565
|
-
].each do |cmd|
|
566
|
-
output "Eseguo #{cmd}".yellow
|
567
|
-
res = %x[ #{cmd} ]
|
568
|
-
if $?.exitstatus != 0
|
569
|
-
color = 'red'
|
570
|
-
else
|
571
|
-
color = 'green'
|
419
|
+
@projects.each_key do |project|
|
420
|
+
if @projects[project].empty?
|
421
|
+
@projects[project] = choose_branch_to_deploy(project, true)
|
572
422
|
end
|
573
|
-
output res.send color
|
574
|
-
stop_if (color == 'red'), "Errore durante la build dell'artifact".red
|
575
423
|
end
|
424
|
+
end
|
576
425
|
|
577
|
-
|
578
|
-
|
426
|
+
def get_git_user()
|
427
|
+
`git config user.name`.gsub(/[^A-Za-z]/, '').gsub("\n", '')
|
428
|
+
end
|
579
429
|
|
580
|
-
|
430
|
+
def get_git_mail()
|
431
|
+
`git config user.email`.gsub("\n", '')
|
581
432
|
end
|
582
433
|
|
583
|
-
def
|
584
|
-
|
585
|
-
output "Preparo l'artifact .zip\n".yellow
|
434
|
+
def qainit_deploy!(quiet = false)
|
435
|
+
`git checkout master && git pull && git submodule update --init --recursive && git remote prune origin`
|
586
436
|
|
587
|
-
|
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
|
588
445
|
|
589
|
-
|
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
|
590
451
|
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
452
|
+
@git_branch = branch_name
|
453
|
+
|
454
|
+
File.open('branch_names', 'w') { |file| file.write(JSON.generate(@projects)) }
|
455
|
+
|
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 }
|
596
481
|
end
|
597
482
|
end
|
483
|
+
# checkout master, checkout branch, pull branch
|
484
|
+
`git checkout master && git checkout #{chosen_branch} && git pull`
|
598
485
|
|
599
|
-
|
600
|
-
web_qa_host = get_route53_hostname(stack_name_web)
|
486
|
+
# aggiornare il commit (revision a cui fa riferimento)
|
601
487
|
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
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'
|
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)
|
614
493
|
end
|
615
|
-
output res.send color
|
616
|
-
stop_if (color == 'red'), "Errore durante la build dell'artifact".red
|
617
494
|
end
|
618
495
|
|
619
|
-
|
620
|
-
|
621
|
-
|
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)) }
|
622
502
|
|
623
|
-
|
503
|
+
update_drone_yml!
|
504
|
+
|
505
|
+
`git add branch_names .drone.yml`
|
506
|
+
`git commit -m 'update'`
|
507
|
+
`git push && git checkout master`
|
624
508
|
end
|
625
509
|
|
626
|
-
def
|
627
|
-
|
628
|
-
|
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
|
629
534
|
|
630
|
-
|
535
|
+
def qainit_drone_shutdown!
|
536
|
+
output "Recupero le informazioni sui QA attivi..."
|
537
|
+
stack_list, envs = get_stacks
|
631
538
|
|
632
|
-
|
539
|
+
env_hash = "qa-" + get_deploy_id
|
633
540
|
|
634
|
-
|
635
|
-
|
636
|
-
|
637
|
-
|
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)
|
638
551
|
end
|
639
552
|
end
|
640
553
|
end
|
641
554
|
|
642
|
-
|
643
|
-
|
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)
|
644
560
|
|
645
|
-
|
646
|
-
|
647
|
-
].each do |cmd|
|
648
|
-
output "Eseguo #{cmd}".yellow
|
649
|
-
res = %x[ #{cmd} ]
|
650
|
-
if $?.exitstatus != 0
|
651
|
-
color = 'red'
|
652
|
-
else
|
653
|
-
color = 'green'
|
561
|
+
if aggregator_enabled
|
562
|
+
dns_to_staging(env_hash)
|
654
563
|
end
|
655
|
-
output res.send color
|
656
|
-
exec_step "docker stop redis" if color == 'red'
|
657
|
-
stop_if (color == 'red'), "Errore durante la build dell'artifact".red
|
658
564
|
end
|
659
565
|
|
660
|
-
|
661
|
-
|
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"
|
662
568
|
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
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
|
667
584
|
end
|
668
585
|
|
669
|
-
def
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
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
|
674
592
|
|
675
|
-
|
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
|
676
601
|
end
|
677
602
|
|
678
|
-
def
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
seconds_elapsed = 0
|
685
|
-
while true
|
686
|
-
break if seconds_elapsed >= sleep_seconds
|
687
|
-
print '.'.yellow; STDOUT.flush
|
688
|
-
sleep 1
|
689
|
-
seconds_elapsed += 1
|
690
|
-
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
|
691
609
|
end
|
610
|
+
end
|
692
611
|
|
693
|
-
|
694
|
-
|
695
|
-
|
696
|
-
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
|
708
|
-
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
|
715
|
-
|
716
|
-
|
717
|
-
|
718
|
-
|
719
|
-
|
720
|
-
|
721
|
-
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
|
731
|
-
|
732
|
-
|
733
|
-
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
stack_body = IO.read('cloudformation/stacks/ecs-cluster.json')
|
738
|
-
create_stack(stack_name, stack_body, [], tags)
|
739
|
-
end
|
740
|
-
|
741
|
-
def import_dbs(ip_address)
|
742
|
-
resp = @ecs.run_task({
|
743
|
-
cluster: @ecs_cluster_name,
|
744
|
-
task_definition: @import_db_task,
|
745
|
-
overrides: {
|
746
|
-
container_overrides: [
|
747
|
-
{
|
748
|
-
name: 'dbrestore',
|
749
|
-
environment: [
|
750
|
-
{
|
751
|
-
name: 'EC2_IP_ADDRESS',
|
752
|
-
value: ip_address,
|
753
|
-
}
|
754
|
-
]
|
755
|
-
}
|
756
|
-
]
|
757
|
-
},
|
758
|
-
count: 1
|
759
|
-
})
|
760
|
-
output "Attendo che i DB vengano importati...\n".yellow
|
761
|
-
stopped_at = nil
|
762
|
-
while stopped_at.nil?
|
763
|
-
resp = @ecs.describe_tasks({
|
764
|
-
cluster: @ecs_cluster_name,
|
765
|
-
tasks: [resp.tasks[0].task_arn]
|
766
|
-
})
|
767
|
-
stopped_at = resp.tasks[0].stopped_at
|
768
|
-
sleep_seconds = 10
|
769
|
-
seconds_elapsed = 0
|
770
|
-
while true && stopped_at.nil?
|
771
|
-
break if seconds_elapsed >= sleep_seconds
|
772
|
-
print '.'.yellow; STDOUT.flush
|
773
|
-
sleep 1
|
774
|
-
seconds_elapsed += 1
|
775
|
-
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'
|
776
656
|
end
|
777
|
-
|
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
|
778
660
|
end
|
779
661
|
|
780
|
-
def
|
781
|
-
|
782
|
-
|
783
|
-
stack_name: stack_name
|
784
|
-
})
|
785
|
-
rescue Aws::CloudFormation::Errors::ValidationError => e
|
786
|
-
if e.message.include? 'does not exist'
|
787
|
-
false
|
788
|
-
else
|
789
|
-
raise e
|
790
|
-
end
|
791
|
-
else
|
792
|
-
true
|
793
|
-
end
|
794
|
-
end
|
795
|
-
|
796
|
-
def create_stack(stack_name, stack_body, parameters = [], tags = [])
|
797
|
-
@cf.create_stack({
|
798
|
-
stack_name: stack_name,
|
799
|
-
template_body: stack_body,
|
800
|
-
parameters: parameters,
|
801
|
-
tags: tags,
|
802
|
-
capabilities: ["CAPABILITY_IAM"],
|
803
|
-
on_failure: "ROLLBACK"
|
804
|
-
})
|
805
|
-
output "La creazione dello stack #{stack_name} è stata avviata".green
|
806
|
-
end
|
807
|
-
|
808
|
-
def update_stack(stack_name, stack_body, parameters = [])
|
809
|
-
begin
|
810
|
-
@cf.update_stack({
|
811
|
-
stack_name: stack_name,
|
812
|
-
template_body: stack_body,
|
813
|
-
parameters: parameters,
|
814
|
-
capabilities: ["CAPABILITY_IAM"]
|
815
|
-
})
|
816
|
-
rescue Aws::CloudFormation::Errors::ValidationError => e
|
817
|
-
# if e.message.include? 'does not exist'
|
818
|
-
# false
|
819
|
-
# else
|
820
|
-
# raise e
|
821
|
-
# end
|
822
|
-
raise e
|
662
|
+
def deploy_pyxis?
|
663
|
+
if defined? @deploy_pyxis
|
664
|
+
@deploy_pyxis
|
823
665
|
else
|
824
|
-
|
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
|
825
672
|
end
|
826
673
|
end
|
827
674
|
|
828
|
-
def
|
829
|
-
|
830
|
-
|
831
|
-
max_keys: 1,
|
832
|
-
prefix: path
|
833
|
-
})
|
834
|
-
!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)
|
835
678
|
end
|
836
679
|
|
837
|
-
def choose_branch_to_deploy(project_name)
|
680
|
+
def choose_branch_to_deploy(project_name, select_master = false)
|
838
681
|
Dir.chdir "projects/#{project_name}"
|
839
682
|
output "Recupero la lista dei branch del progetto #{project_name}..."
|
683
|
+
`git remote prune origin`
|
840
684
|
out = %x[ git fetch ]
|
841
|
-
branches = %x[ git for-each-ref --sort=-committerdate refs/remotes/ --format='%(refname) %(objectname)' | sed 's/refs\\/remotes\\/origin\\///g' ]
|
842
|
-
.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]
|
687
|
+
|
688
|
+
master_branch = nil
|
843
689
|
|
844
|
-
|
845
|
-
|
846
|
-
|
690
|
+
branches.each do |branch|
|
691
|
+
master_branch = branch if branch.match(/^master\s+/)
|
692
|
+
break unless master_branch.nil?
|
693
|
+
end
|
847
694
|
|
848
|
-
|
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
|
849
702
|
|
850
|
-
|
851
|
-
|
852
|
-
|
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
|
853
712
|
end
|
854
713
|
end
|
855
714
|
|
856
715
|
Dir.chdir "../../"
|
857
716
|
|
858
|
-
name = branch_name.split(' ')
|
859
|
-
revision = branch_name.split(' ')
|
860
|
-
|
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 }
|
861
721
|
end
|
862
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
|
863
780
|
end
|
864
781
|
|
865
782
|
def help_content
|
@@ -876,14 +793,24 @@ Synopsis
|
|
876
793
|
twig release start
|
877
794
|
twig release finish
|
878
795
|
twig release deploy
|
796
|
+
twig release aggregator
|
879
797
|
|
880
798
|
Description
|
881
799
|
-----------
|
882
800
|
|
883
|
-
start
|
884
|
-
finish
|
885
|
-
|
886
|
-
|
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
|
887
814
|
|
888
815
|
Subcommand for Twig: <http://rondevera.github.io/twig/>
|
889
816
|
Author: Andrea Usuelli <https://github.com/andreausu>
|
@@ -898,4 +825,11 @@ if args.include?('--help')
|
|
898
825
|
exit
|
899
826
|
end
|
900
827
|
|
901
|
-
|
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)
|