prima-twig 0.5.27 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/bin/twig-deploy +99 -125
- data/bin/twig-feature +698 -632
- data/lib/command.rb +24 -37
- data/lib/prima_twig.rb +6 -25
- metadata +27 -174
- data/bin/twig-build +0 -2000
- data/bin/twig-update-ami +0 -197
- data/lib/prima_aws_client.rb +0 -494
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: a05a95e7e21f4213ce9220e57b38cd4ef31042b3
|
|
4
|
+
data.tar.gz: 7bdcac137e2a268778c59ef90e0c9df6b29a1786
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 71773e88e49803d95beb7e1c25a51442cf3c4abc6c5244898ca3e427105f3136576fe7dcb9c57b5f2c37b71bdeeb991b38def8a73e8949620296cc838f5e4b63
|
|
7
|
+
data.tar.gz: 48e615176d7dcd3a0e8cac65adce4f6c72fc078d708f6e7b884481055b44831d07a2c1e66e0bb42b00ce33e19b83211493cfba6a2781b75d1273d9b615017f30
|
data/bin/twig-deploy
CHANGED
|
@@ -2,19 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
require 'rubygems'
|
|
4
4
|
require_relative '../lib/prima_twig.rb'
|
|
5
|
-
require_relative '../lib/prima_aws_client.rb'
|
|
6
5
|
require 'colorize'
|
|
7
6
|
require 'highline/import'
|
|
8
|
-
require 'aws-sdk
|
|
9
|
-
require 'aws-sdk-cloudformation'
|
|
10
|
-
require 'aws-sdk-ecs'
|
|
11
|
-
require 'aws-sdk-s3'
|
|
7
|
+
require 'aws-sdk'
|
|
12
8
|
require 'redcarpet'
|
|
13
9
|
require 'mail'
|
|
14
10
|
require 'erb'
|
|
15
11
|
require 'base64'
|
|
16
|
-
require 'rubyflare'
|
|
17
|
-
require 'pp'
|
|
18
12
|
|
|
19
13
|
def help_content
|
|
20
14
|
<<-HELP
|
|
@@ -49,35 +43,18 @@ end
|
|
|
49
43
|
|
|
50
44
|
class Review
|
|
51
45
|
include Command
|
|
52
|
-
include PrimaAwsClient
|
|
53
46
|
|
|
54
47
|
def initialize
|
|
55
48
|
@prima = Prima.new
|
|
56
|
-
output "Controllo se ci sono aggiornamenti da fare..."
|
|
57
|
-
exec "gem update prima-twig && twig deploy #{ARGV.join ' '}" unless `gem outdated`.lines.grep(/^prima-twig \(.*\)/).empty?
|
|
58
49
|
@cf = Aws::CloudFormation::Client.new
|
|
59
50
|
@ecs = Aws::ECS::Client.new
|
|
60
51
|
@s3 = Aws::S3::Client.new
|
|
61
|
-
@batch = Aws::Batch::Client.new
|
|
62
|
-
@s3_bucket = "prima-artifacts-encrypted"
|
|
63
52
|
end
|
|
64
53
|
|
|
65
|
-
def execute!
|
|
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
|
|
77
|
-
|
|
78
|
-
def deploy_revision!
|
|
54
|
+
def execute!
|
|
79
55
|
stop_if @prima.head_detached?, :detached_head
|
|
80
|
-
|
|
56
|
+
|
|
57
|
+
`git checkout master && git pull`
|
|
81
58
|
|
|
82
59
|
output "Recupero degli artifacts in corso, attendi qualche secondo...".yellow
|
|
83
60
|
artifacts = get_artifacts[0..49]
|
|
@@ -94,10 +71,26 @@ class Review
|
|
|
94
71
|
end
|
|
95
72
|
end
|
|
96
73
|
|
|
97
|
-
user = `git config user.name
|
|
74
|
+
user = `git config user.name`
|
|
98
75
|
artifact = artifacts.select {|v| v[:rev] == artifact_rev}.first
|
|
99
76
|
|
|
100
|
-
|
|
77
|
+
deploy_command = "bin/deploy #{artifact_rev}"
|
|
78
|
+
|
|
79
|
+
output "Il comando per il deploy sara': #{deploy_command}".yellow
|
|
80
|
+
|
|
81
|
+
exit unless @prima.yesno "Sei sicuro di voler effettuare il deploy in produzione?".blue
|
|
82
|
+
|
|
83
|
+
exec_step deploy_command
|
|
84
|
+
|
|
85
|
+
stack_name_web = 'ecs-task-web-production'
|
|
86
|
+
stack_name_consumer = 'ecs-task-consumer-production'
|
|
87
|
+
stack_name_cron = 'ecs-task-consumer-production'
|
|
88
|
+
wait_for_stack_ready(stack_name_web) unless stack_ready?(stack_name_web)
|
|
89
|
+
wait_for_stack_ready(stack_name_consumer) unless stack_ready?(stack_name_consumer)
|
|
90
|
+
wait_for_stack_ready(stack_name_cron) unless stack_ready?(stack_name_cron)
|
|
91
|
+
|
|
92
|
+
output "Avvio paparatzinger per gli screenshot".yellow
|
|
93
|
+
job_name = launch_paparatzinger(artifact[:commit_msg])
|
|
101
94
|
|
|
102
95
|
mail = Mail.new do
|
|
103
96
|
from 'deploy@prima.it'
|
|
@@ -105,14 +98,13 @@ class Review
|
|
|
105
98
|
subject "#{user} ha effettuato il deploy della revision #{artifact[:rev]}"
|
|
106
99
|
end
|
|
107
100
|
|
|
108
|
-
commit_msg = clean_commit_message(artifact[:commit_msg])
|
|
109
|
-
|
|
110
101
|
body = "## Deploy in produzione effettuato con successo\n\n"
|
|
111
102
|
body << "Data: #{Time.now.strftime('%d/%m/%Y %H:%M:%S')}\n\n"
|
|
112
103
|
body << "Utente: #{user}\n\n"
|
|
113
104
|
body << "Revision: [#{artifact[:rev]}](https://github.com/primait/prima/commit/#{artifact[:rev]}) del #{artifact[:created_at].strftime('%d/%m/%Y %H:%M:%S')}\n\n"
|
|
114
105
|
body << "Branch: [#{artifact[:branch]}](https://github.com/primait/prima/tree/#{artifact[:branch]})\n\n"
|
|
115
|
-
body << "Commit: #{commit_msg.gsub(/_/, '\_')}\n\n"
|
|
106
|
+
body << "Commit: #{artifact[:commit_msg].gsub(/_/, '\_')}\n\n"
|
|
107
|
+
body << "Screenshots (tra qualche minuto): [BrowserStack](https://www.browserstack.com/automate) (Filtrare per: \"#{job_name.gsub(/_/, '\_')}\")"
|
|
116
108
|
|
|
117
109
|
htmlBody = Redcarpet::Markdown.new(Redcarpet::Render::HTML.new).render body
|
|
118
110
|
|
|
@@ -127,122 +119,104 @@ class Review
|
|
|
127
119
|
mail.html_part = html_part
|
|
128
120
|
mail.text_part = text_part
|
|
129
121
|
|
|
130
|
-
opts = {address: '
|
|
131
|
-
opts[:user_name] = @prima.
|
|
132
|
-
opts[:password] = @prima.config['
|
|
133
|
-
|
|
134
|
-
exec_step "git checkout master"
|
|
122
|
+
opts = {address: 'smtp.mandrillapp.com', port: '587'}
|
|
123
|
+
opts[:user_name] = 'deploy@prima.it'
|
|
124
|
+
opts[:password] = @prima.config['mandrill']
|
|
135
125
|
|
|
136
126
|
mail.delivery_method(:smtp, opts)
|
|
137
127
|
mail.deliver
|
|
138
128
|
|
|
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)
|
|
198
129
|
end
|
|
199
130
|
|
|
200
131
|
def get_artifacts
|
|
201
132
|
artifacts = []
|
|
202
|
-
resp = @s3.list_objects(bucket:
|
|
133
|
+
resp = @s3.list_objects(bucket: 'prima-artifacts', prefix: 'prima')
|
|
203
134
|
resp.contents.each do |l|
|
|
204
|
-
|
|
205
|
-
rev = l.key.match(/^prima\/(\w{15}).tar.gz$/).captures.first if l.key.match(/^prima\/(\w{15}).tar.gz$/)
|
|
135
|
+
rev = l.key.match(/(\w{15}).tar.gz$/).captures.first if l.key.match(/(\w{15}).tar.gz$/)
|
|
206
136
|
if rev
|
|
207
|
-
object = @s3.head_object(bucket:
|
|
137
|
+
object = @s3.head_object(bucket: 'prima-artifacts', key: l.key)
|
|
208
138
|
commit_msg = ''
|
|
209
139
|
commit_msg = Base64.decode64(object.metadata['commit_msg']).strip if object.metadata.has_key? 'commit_msg'
|
|
210
|
-
artifacts << {rev: rev, created_at: object.last_modified, branch: object.metadata['branch'], commit_msg: commit_msg } if
|
|
140
|
+
artifacts << {rev: rev, created_at: object.last_modified, branch: object.metadata['branch'], commit_msg: commit_msg } if object.metadata.has_key? 'branch'
|
|
211
141
|
end
|
|
212
142
|
end
|
|
213
143
|
artifacts.sort_by { |v| v[:created_at] }.reverse
|
|
214
144
|
end
|
|
215
145
|
|
|
216
|
-
def
|
|
217
|
-
|
|
146
|
+
def wait_for_stack_ready(stack_name)
|
|
147
|
+
ready = false
|
|
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
|
|
218
160
|
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
job_queue: "tools-production", # required
|
|
222
|
-
job_definition: resp.stack_resource_detail.physical_resource_id # required
|
|
223
|
-
})
|
|
161
|
+
output "\nStack #{stack_name} deployato con successo!\n".green
|
|
162
|
+
end
|
|
224
163
|
|
|
225
|
-
|
|
164
|
+
def stack_ready?(stack_name)
|
|
165
|
+
resp = @cf.describe_stacks({
|
|
166
|
+
stack_name: stack_name
|
|
167
|
+
})
|
|
168
|
+
['CREATE_COMPLETE', 'UPDATE_COMPLETE'].include? resp.stacks[0].stack_status
|
|
226
169
|
end
|
|
227
170
|
|
|
228
|
-
|
|
171
|
+
def launch_paparatzinger(job_name)
|
|
172
|
+
@s3.get_object(
|
|
173
|
+
response_target: '/tmp/paparatzinger_twig.yml',
|
|
174
|
+
bucket: 'prima-deploy',
|
|
175
|
+
key: 'paparatzinger_twig.yml')
|
|
229
176
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
177
|
+
paparatzinger_config = YAML.load_file '/tmp/paparatzinger_twig.yml'
|
|
178
|
+
|
|
179
|
+
job_name.gsub! /Merge pull request /i, ''
|
|
180
|
+
job_name.gsub! /from primait\/feature\//i, ''
|
|
181
|
+
job_name[0..99].gsub! /[^0-9a-z]/i, '\_'
|
|
182
|
+
|
|
183
|
+
logical_resource_id = 'TaskDefinitionPaparatzinger'
|
|
184
|
+
resp = @cf.describe_stack_resource({
|
|
185
|
+
stack_name: 'ecs-task-paparatzinger-production',
|
|
186
|
+
logical_resource_id: logical_resource_id
|
|
187
|
+
})
|
|
236
188
|
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
189
|
+
resp = @ecs.run_task({
|
|
190
|
+
cluster: 'ecs-cluster-microservices-production-ECSCluster-N4APBU860IA1',
|
|
191
|
+
task_definition: resp.stack_resource_detail.physical_resource_id,
|
|
192
|
+
overrides: {
|
|
193
|
+
container_overrides: [
|
|
194
|
+
{
|
|
195
|
+
name: 'paparatzinger',
|
|
196
|
+
environment: [
|
|
197
|
+
{
|
|
198
|
+
name: 'JOB_NAME',
|
|
199
|
+
value: job_name,
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
name: 'VERSION',
|
|
203
|
+
value: paparatzinger_config['version'],
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
name: 'URL_GARANZIE',
|
|
207
|
+
value: paparatzinger_config['url_garanzie']
|
|
208
|
+
}
|
|
209
|
+
]
|
|
210
|
+
}
|
|
211
|
+
]
|
|
212
|
+
},
|
|
213
|
+
count: 1
|
|
214
|
+
})
|
|
215
|
+
output "paparatzinger lanciato con successo\n".green
|
|
216
|
+
|
|
217
|
+
job_name
|
|
244
218
|
end
|
|
245
|
-
|
|
219
|
+
|
|
246
220
|
end
|
|
247
221
|
|
|
248
|
-
Review.new.execute!
|
|
222
|
+
Review.new.execute!
|
data/bin/twig-feature
CHANGED
|
@@ -2,110 +2,53 @@
|
|
|
2
2
|
|
|
3
3
|
require 'rubygems'
|
|
4
4
|
require_relative '../lib/prima_twig.rb'
|
|
5
|
-
require_relative '../lib/prima_aws_client.rb'
|
|
6
|
-
require 'digest'
|
|
7
|
-
require 'json'
|
|
8
5
|
require 'launchy'
|
|
6
|
+
require 'digest'
|
|
9
7
|
require 'pp'
|
|
10
|
-
require 'redis'
|
|
11
8
|
|
|
12
9
|
class Release
|
|
13
10
|
include Command
|
|
14
|
-
include PrimaAwsClient
|
|
15
11
|
|
|
16
|
-
def initialize
|
|
12
|
+
def initialize
|
|
17
13
|
@prima = Prima.new
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
14
|
+
@cf = Aws::CloudFormation::Client.new
|
|
15
|
+
@elb = Aws::ElasticLoadBalancing::Client.new
|
|
16
|
+
@ec2 = Aws::EC2::Client.new
|
|
17
|
+
@ecs = Aws::ECS::Client.new
|
|
18
|
+
@s3 = Aws::S3::Client.new
|
|
19
|
+
@asg = Aws::AutoScaling::Client.new
|
|
20
|
+
@s3_bucket = 'prima-artifacts'
|
|
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
|
|
25
28
|
@dns_record_identifier = nil
|
|
26
29
|
@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'])
|
|
55
30
|
end
|
|
56
31
|
|
|
57
|
-
def execute!
|
|
32
|
+
def execute! args
|
|
58
33
|
case args[0]
|
|
59
|
-
when
|
|
34
|
+
when "start"
|
|
60
35
|
start_feature!
|
|
61
|
-
when
|
|
36
|
+
when "finish"
|
|
62
37
|
finish_feature!
|
|
63
|
-
when
|
|
64
|
-
abort('Non sei nella cartella di qainit') unless Dir.pwd.match 'qainit$' or Dir.pwd.match '/drone/src'
|
|
38
|
+
when "deploy"
|
|
65
39
|
if ['terminate', 'stop', 'shutdown', 'halt', 'destroy'].include? args[1]
|
|
66
|
-
|
|
67
|
-
elsif 'update' == args[1]
|
|
68
|
-
qainit_deploy_update!
|
|
40
|
+
deploy_shutdown!
|
|
69
41
|
else
|
|
70
|
-
|
|
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
|
|
42
|
+
deploy_feature!
|
|
95
43
|
end
|
|
96
44
|
else
|
|
97
|
-
|
|
45
|
+
stop_if true, [:wrong_args, ['start', 'finish', 'deploy', 'deploy stop']]
|
|
98
46
|
end
|
|
99
47
|
end
|
|
100
48
|
|
|
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
|
-
|
|
106
49
|
def start_feature!
|
|
107
50
|
branch_name = @prima.clean_branch_name(ask('Inserisci il nome del branch (puoi omettere feature/): '.cyan))
|
|
108
|
-
stop_unless
|
|
51
|
+
stop_unless branch_name.length > 0, 'Devi inserire il nome del branch'
|
|
109
52
|
branch_name.prepend 'feature/' unless branch_name.include? 'feature'
|
|
110
53
|
|
|
111
54
|
output "Il nome del branch sarà " + branch_name.yellow
|
|
@@ -115,135 +58,6 @@ class Release
|
|
|
115
58
|
exec_step "git checkout -b " + branch_name
|
|
116
59
|
end
|
|
117
60
|
|
|
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
|
-
|
|
247
61
|
def finish_feature!
|
|
248
62
|
current_branch_name = @prima.twig.current_branch_name
|
|
249
63
|
stop_unless (current_branch_name =~ /^feature\//), "Non sei su un branch di feature, non posso mergiare nulla"
|
|
@@ -264,8 +78,11 @@ class Release
|
|
|
264
78
|
end
|
|
265
79
|
|
|
266
80
|
def deploy_shutdown!
|
|
267
|
-
|
|
268
|
-
stack_list
|
|
81
|
+
envs = {}
|
|
82
|
+
stack_list.each do |stack|
|
|
83
|
+
env_hash = stack.stack_name.match(/qa-(\w+)$/)[0]
|
|
84
|
+
envs[env_hash] = stack.tags unless envs.has_key?(env_hash)
|
|
85
|
+
end
|
|
269
86
|
|
|
270
87
|
env_hash = nil
|
|
271
88
|
unless envs.empty?
|
|
@@ -274,509 +91,775 @@ class Release
|
|
|
274
91
|
menu.shell = true
|
|
275
92
|
|
|
276
93
|
envs.each do |key, env|
|
|
277
|
-
title =
|
|
278
|
-
|
|
279
|
-
title << "\n#{e.key}: #{e.value} "
|
|
280
|
-
end
|
|
281
|
-
msg = @prima.reduce_size(title, 1000).to_s.light_blue
|
|
94
|
+
title = @prima.reduce_size("#{env[0].key}: #{env[0].value} #{env[1].key}: #{env[1].value} #{env[2].key}: #{env[2].value} #{env[3].key}: #{env[3].value}", 100)
|
|
95
|
+
msg = "#{title}".light_blue
|
|
282
96
|
menu.choice(msg) { key }
|
|
283
97
|
end
|
|
284
98
|
end
|
|
285
99
|
else
|
|
286
|
-
output
|
|
100
|
+
output "Nessun environment trovato".red
|
|
287
101
|
exit
|
|
288
102
|
end
|
|
289
103
|
|
|
290
104
|
cluster_stack_name = nil
|
|
291
|
-
stacks_to_delete = []
|
|
292
105
|
stack_list.each do |stack|
|
|
293
106
|
if stack.stack_name.match(/#{env_hash}$/)
|
|
294
107
|
if stack.stack_name.match(/ecs-cluster/)
|
|
295
108
|
cluster_stack_name = stack.stack_name
|
|
296
109
|
else
|
|
297
|
-
|
|
298
|
-
stacks_to_delete.push(stack.stack_name)
|
|
299
|
-
delete_stack(stack.stack_name)
|
|
110
|
+
delete_stack(stack.stack_name) if stack.stack_name.match(/#{env_hash}$/)
|
|
300
111
|
end
|
|
301
112
|
end
|
|
302
113
|
end
|
|
303
114
|
|
|
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
|
-
|
|
313
115
|
# Se non ha finito di cancellare le altre non si puo' cancellare il cluster
|
|
314
|
-
output "Attendo
|
|
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
|
+
output "Attendo 60 secondi per poter eliminare il cluster ECS"
|
|
117
|
+
sleep 60
|
|
324
118
|
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])
|
|
327
119
|
output "Finito!".green
|
|
328
120
|
end
|
|
329
121
|
|
|
330
|
-
def
|
|
331
|
-
|
|
122
|
+
def deploy_feature!
|
|
123
|
+
`sudo true` # cosi' non chiede la password dopo
|
|
332
124
|
`git pull && git submodule init && git submodule update`
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
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
|
|
353
217
|
else
|
|
354
|
-
|
|
355
|
-
|
|
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)
|
|
356
346
|
end
|
|
357
347
|
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
348
|
+
wait_for_stack_ready(stack_name_web) unless stack_ready?(stack_name_web)
|
|
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"
|
|
363
413
|
end
|
|
364
|
-
|
|
365
|
-
update_cluster_stack(cluster_stack_name, tags)
|
|
366
|
-
|
|
367
|
-
output "Finito!".green
|
|
414
|
+
host
|
|
368
415
|
end
|
|
369
416
|
|
|
370
|
-
def
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
417
|
+
def ec2_ip_address(asg_stack_name)
|
|
418
|
+
resp = @cf.describe_stack_resource({
|
|
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
|
|
378
430
|
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
msg = "#{@prima.reduce_size(title, 1000)}".light_blue
|
|
390
|
-
menu.choice(msg) { key }
|
|
391
|
-
end
|
|
392
|
-
end
|
|
393
|
-
else
|
|
394
|
-
output "Nessun QA trovato".red
|
|
395
|
-
exit
|
|
431
|
+
def get_elb_host(stack_name)
|
|
432
|
+
case
|
|
433
|
+
when stack_name.include?('web')
|
|
434
|
+
logical_resource_id = 'EcsElasticLoadBalancerPublic'
|
|
435
|
+
when stack_name.include?('urania')
|
|
436
|
+
logical_resource_id = 'EcsElasticLoadBalancerInternal'
|
|
437
|
+
when stack_name.include?('backoffice')
|
|
438
|
+
logical_resource_id = 'EcsElasticLoadBalancerPublic'
|
|
439
|
+
when stack_name.include?('bburago')
|
|
440
|
+
logical_resource_id = 'EcsElasticLoadBalancerInternal'
|
|
396
441
|
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
|
|
397
452
|
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
453
|
+
def update_service_defaults(stack_name)
|
|
454
|
+
case
|
|
455
|
+
when stack_name.include?('web')
|
|
456
|
+
logical_resource_id = 'ECSServiceWeb'
|
|
457
|
+
when stack_name.include?('consumer')
|
|
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'
|
|
401
506
|
end
|
|
507
|
+
output res.send color
|
|
508
|
+
stop_if (color == 'red'), "Errore durante la build dell'artifact".red
|
|
402
509
|
end
|
|
403
|
-
deploy_feature!
|
|
404
510
|
|
|
405
|
-
|
|
406
|
-
|
|
511
|
+
artifact_path = Dir.glob("rel/urania/releases/*/urania.tar.gz").first
|
|
512
|
+
upload_artifact(artifact_path, "microservices/urania/#{revision}-qa.tar.gz")
|
|
407
513
|
|
|
408
|
-
|
|
409
|
-
projects.each_key do |project|
|
|
410
|
-
return projects[project]['name'] if not projects[project]['default_branch']
|
|
411
|
-
end
|
|
514
|
+
Dir.chdir '../../'
|
|
412
515
|
end
|
|
413
516
|
|
|
414
|
-
def
|
|
415
|
-
|
|
517
|
+
def create_ermes_artifact(revision)
|
|
518
|
+
@ermes_built = true
|
|
519
|
+
output "Preparo l'artifact .zip\n".yellow
|
|
520
|
+
|
|
521
|
+
git_checkout_version('ermes', revision)
|
|
416
522
|
|
|
417
|
-
|
|
523
|
+
Dir.chdir 'projects/ermes'
|
|
418
524
|
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
525
|
+
[
|
|
526
|
+
"docker-compose build app",
|
|
527
|
+
"docker run -v $PWD:/code -w /code -e MIX_ENV=qa --entrypoint /bin/sh ermes_app \
|
|
528
|
+
'-c' 'mix local.hex --force && mix hex.info && \
|
|
529
|
+
mix deps.get && mix compile && mix deps.compile && \
|
|
530
|
+
mix release.clean --implode --no-confirm && mix release'",
|
|
531
|
+
"sudo chown -R `whoami` ."
|
|
532
|
+
].each do |cmd|
|
|
533
|
+
output "Eseguo #{cmd}".yellow
|
|
534
|
+
res = %x[ #{cmd} ]
|
|
535
|
+
if $?.exitstatus != 0
|
|
536
|
+
color = 'red'
|
|
537
|
+
else
|
|
538
|
+
color = 'green'
|
|
422
539
|
end
|
|
540
|
+
output res.send color
|
|
541
|
+
stop_if (color == 'red'), "Errore durante la build dell'artifact".red
|
|
423
542
|
end
|
|
424
|
-
end
|
|
425
543
|
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
end
|
|
544
|
+
artifact_path = Dir.glob("rel/ermes/releases/*/ermes.tar.gz").first
|
|
545
|
+
upload_artifact(artifact_path, "microservices/ermes/ermes_#{revision}.tar.gz")
|
|
429
546
|
|
|
430
|
-
|
|
431
|
-
`git config user.email`.gsub("\n", '')
|
|
547
|
+
Dir.chdir '../../'
|
|
432
548
|
end
|
|
433
549
|
|
|
434
|
-
def
|
|
435
|
-
|
|
550
|
+
def create_bburago_artifact(revision)
|
|
551
|
+
@bburago_built = true
|
|
552
|
+
output "Preparo l'artifact .zip\n".yellow
|
|
436
553
|
|
|
437
|
-
|
|
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
|
|
554
|
+
git_checkout_version('bburago', revision)
|
|
445
555
|
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
556
|
+
Dir.chdir 'projects/bburago'
|
|
557
|
+
|
|
558
|
+
[
|
|
559
|
+
"docker-compose build web",
|
|
560
|
+
"docker run -v $PWD:/code -w /code -e MIX_ENV=qa --entrypoint /bin/sh bburago_web \
|
|
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'
|
|
572
|
+
end
|
|
573
|
+
output res.send color
|
|
574
|
+
stop_if (color == 'red'), "Errore durante la build dell'artifact".red
|
|
450
575
|
end
|
|
451
576
|
|
|
452
|
-
|
|
577
|
+
artifact_path = Dir.glob("rel/bburago/releases/*/bburago.tar.gz").first
|
|
578
|
+
upload_artifact(artifact_path, "microservices/bburago/bburago_#{revision}.tar.gz")
|
|
453
579
|
|
|
454
|
-
|
|
580
|
+
Dir.chdir '../../'
|
|
581
|
+
end
|
|
455
582
|
|
|
456
|
-
|
|
583
|
+
def create_backoffice_artifact(revision, deploy_id)
|
|
584
|
+
@backoffice_built = true
|
|
585
|
+
output "Preparo l'artifact .zip\n".yellow
|
|
457
586
|
|
|
458
|
-
|
|
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
|
|
587
|
+
git_checkout_version('backoffice', revision)
|
|
464
588
|
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
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 }
|
|
589
|
+
Dir.chdir 'projects/backoffice'
|
|
590
|
+
|
|
591
|
+
['node_modules'].each do |dir|
|
|
592
|
+
unless File.directory?(dir)
|
|
593
|
+
if File.directory?("../../../backoffice/#{dir}")
|
|
594
|
+
exec_step "rsync -a ../../../backoffice/#{dir} ."
|
|
595
|
+
end
|
|
481
596
|
end
|
|
482
597
|
end
|
|
483
|
-
# checkout master, checkout branch, pull branch
|
|
484
|
-
`git checkout master && git checkout #{chosen_branch} && git pull`
|
|
485
598
|
|
|
486
|
-
|
|
599
|
+
stack_name_web = "ecs-task-web-qa-notneeded"
|
|
600
|
+
web_qa_host = get_route53_hostname(stack_name_web)
|
|
487
601
|
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
602
|
+
[
|
|
603
|
+
"docker-compose build workers",
|
|
604
|
+
"cd ../../ && docker run -e GIT_DIR=$PWD -v $PWD:/usr/app/src -w /usr/app/src/projects/backoffice blinkmobile/bower install --allow-root",
|
|
605
|
+
"docker run -v $PWD:/code -w /code -e PHANTOMJS_BIN=/code/node_modules/grunt-selenium-webdriver/node_modules/phantomjs/bin/phantomjs --entrypoint /bin/bash backoffice_workers '-c' 'sed -i \"s/web-qa-url/#{web_qa_host}/g\" Gruntfile.js && npm install && grunt qa'",
|
|
606
|
+
"sudo chown -R `whoami` ."
|
|
607
|
+
].each do |cmd|
|
|
608
|
+
output "Eseguo #{cmd}".yellow
|
|
609
|
+
res = %x[ #{cmd} ]
|
|
610
|
+
if $?.exitstatus != 0
|
|
611
|
+
color = 'red'
|
|
612
|
+
else
|
|
613
|
+
color = 'green'
|
|
493
614
|
end
|
|
615
|
+
output res.send color
|
|
616
|
+
stop_if (color == 'red'), "Errore durante la build dell'artifact".red
|
|
494
617
|
end
|
|
495
618
|
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
end
|
|
500
|
-
|
|
501
|
-
File.open('branch_names', 'w') { |file| file.write(JSON.generate(@projects)) }
|
|
619
|
+
artifact_path = '/tmp/backoffice.zip'
|
|
620
|
+
exec_step "rm -f #{artifact_path} && zip -9 -r #{artifact_path} bin/"
|
|
621
|
+
upload_artifact(artifact_path, "backoffice/#{revision}-#{deploy_id}.zip")
|
|
502
622
|
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
`git add branch_names .drone.yml`
|
|
506
|
-
`git commit -m 'update'`
|
|
507
|
-
`git push && git checkout master`
|
|
623
|
+
Dir.chdir '../../'
|
|
508
624
|
end
|
|
509
625
|
|
|
510
|
-
def
|
|
511
|
-
|
|
512
|
-
|
|
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
|
|
626
|
+
def create_prima_artifact(revision, branch_name)
|
|
627
|
+
@prima_built = true
|
|
628
|
+
output "Preparo l'artifact .zip\n".yellow
|
|
534
629
|
|
|
535
|
-
|
|
536
|
-
output "Recupero le informazioni sui QA attivi..."
|
|
537
|
-
stack_list, envs = get_stacks
|
|
630
|
+
git_checkout_version('prima', revision)
|
|
538
631
|
|
|
539
|
-
|
|
632
|
+
Dir.chdir 'projects/prima'
|
|
540
633
|
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
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)
|
|
634
|
+
['vendor'].each do |dir|
|
|
635
|
+
unless File.directory?(dir)
|
|
636
|
+
if File.directory?("../../../prima/#{dir}")
|
|
637
|
+
exec_step "rsync -a ../../../prima/#{dir} ."
|
|
551
638
|
end
|
|
552
639
|
end
|
|
553
640
|
end
|
|
554
641
|
|
|
555
|
-
|
|
556
|
-
|
|
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
|
-
|
|
561
|
-
if aggregator_enabled
|
|
562
|
-
dns_to_staging(env_hash)
|
|
563
|
-
end
|
|
564
|
-
end
|
|
565
|
-
|
|
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"
|
|
642
|
+
stack_name_backoffice = "ecs-task-backoffice-qa-notneeded"
|
|
643
|
+
backoffice_qa_host = get_route53_hostname(stack_name_backoffice)
|
|
568
644
|
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
645
|
+
[
|
|
646
|
+
"bin/local_build_artifact.sh #{branch_name}"
|
|
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'
|
|
573
654
|
end
|
|
574
|
-
output
|
|
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
|
|
575
658
|
end
|
|
576
659
|
|
|
577
|
-
|
|
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
|
|
660
|
+
Dir.chdir "../../"
|
|
584
661
|
end
|
|
585
662
|
|
|
586
|
-
def
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
output "#{output_message} #{qa_file_name}".green
|
|
663
|
+
def git_checkout_version(project, revision)
|
|
664
|
+
Dir.chdir "projects/#{project}"
|
|
665
|
+
exec_step "git checkout -- . && git clean -f -d && git checkout #{revision}"
|
|
666
|
+
Dir.chdir "../../"
|
|
591
667
|
end
|
|
592
668
|
|
|
593
|
-
def
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
end
|
|
669
|
+
def upload_artifact(source_path, destination_path)
|
|
670
|
+
output "Upload dell'artifact in corso (#{(File.size(source_path).to_f / 2**20).round(2)} MiB)\n".yellow
|
|
671
|
+
s3 = Aws::S3::Resource.new
|
|
672
|
+
obj = s3.bucket(@s3_bucket).object(destination_path)
|
|
673
|
+
obj.upload_file(source_path)
|
|
674
|
+
|
|
675
|
+
output "#{@s3_bucket}/#{destination_path} uploadato con successo!\n".green
|
|
601
676
|
end
|
|
602
677
|
|
|
603
|
-
def
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
678
|
+
def wait_for_stack_ready(stack_name)
|
|
679
|
+
ready = false
|
|
680
|
+
sleep_seconds = 10
|
|
681
|
+
output "Attendo che lo stack #{stack_name} finisca di essere inizializzato...\n".yellow
|
|
682
|
+
while !ready
|
|
683
|
+
ready = true if stack_ready?(stack_name)
|
|
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
|
|
609
691
|
end
|
|
610
|
-
end
|
|
611
692
|
|
|
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
|
-
|
|
654
|
-
|
|
655
|
-
|
|
693
|
+
output "\nStack #{stack_name} pronto!\n".green
|
|
694
|
+
end
|
|
695
|
+
|
|
696
|
+
def stack_list
|
|
697
|
+
resp = @cf.describe_stacks
|
|
698
|
+
stacks = resp.stacks
|
|
699
|
+
stacks.keep_if { |stack| stack.stack_name.include? '-qa-' }
|
|
700
|
+
stacks
|
|
701
|
+
end
|
|
702
|
+
|
|
703
|
+
def delete_stack(stack_name)
|
|
704
|
+
@cf.delete_stack({stack_name: stack_name})
|
|
705
|
+
output "Stack #{stack_name} spenta con successo\n".green
|
|
706
|
+
end
|
|
707
|
+
|
|
708
|
+
def stack_ready?(stack_name)
|
|
709
|
+
resp = @cf.describe_stacks({
|
|
710
|
+
stack_name: stack_name
|
|
711
|
+
})
|
|
712
|
+
['CREATE_COMPLETE', 'UPDATE_COMPLETE'].include? resp.stacks[0].stack_status
|
|
713
|
+
end
|
|
714
|
+
|
|
715
|
+
def create_asg_stack(stack_name, tags = [])
|
|
716
|
+
pp @ecs_cluster_name
|
|
717
|
+
|
|
718
|
+
stack_body = IO.read('cloudformation/stacks/asg/ecs-asg-allinone.json')
|
|
719
|
+
parameters = [
|
|
720
|
+
{
|
|
721
|
+
parameter_key: "Environment",
|
|
722
|
+
parameter_value: "qa"
|
|
723
|
+
},
|
|
724
|
+
{
|
|
725
|
+
parameter_key: "InstanceType",
|
|
726
|
+
parameter_value: "t2.large"
|
|
727
|
+
},
|
|
728
|
+
{
|
|
729
|
+
parameter_key: "ECSClusterName",
|
|
730
|
+
parameter_value: @ecs_cluster_name
|
|
731
|
+
}
|
|
732
|
+
]
|
|
733
|
+
create_stack(stack_name, stack_body, parameters, tags)
|
|
734
|
+
end
|
|
735
|
+
|
|
736
|
+
def create_cluster_stack(stack_name, tags = [])
|
|
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
|
|
656
776
|
end
|
|
657
|
-
|
|
658
|
-
resp = describe_load_balancers([resp.stack_resource_detail.physical_resource_id])
|
|
659
|
-
resp.load_balancers[0].dns_name
|
|
777
|
+
print "\n"
|
|
660
778
|
end
|
|
661
779
|
|
|
662
|
-
def
|
|
663
|
-
|
|
664
|
-
@
|
|
780
|
+
def stack_exists?(stack_name)
|
|
781
|
+
begin
|
|
782
|
+
res = @cf.describe_stacks({
|
|
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
|
|
665
791
|
else
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
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
|
|
823
|
+
else
|
|
824
|
+
output "L'update dello stack #{stack_name} è stato avviato".green
|
|
672
825
|
end
|
|
673
826
|
end
|
|
674
827
|
|
|
675
|
-
def
|
|
676
|
-
|
|
677
|
-
|
|
828
|
+
def artifact_exists?(bucket, path)
|
|
829
|
+
resp = @s3.list_objects({
|
|
830
|
+
bucket: bucket,
|
|
831
|
+
max_keys: 1,
|
|
832
|
+
prefix: path
|
|
833
|
+
})
|
|
834
|
+
!resp.contents.empty?
|
|
678
835
|
end
|
|
679
836
|
|
|
680
|
-
def choose_branch_to_deploy(project_name
|
|
837
|
+
def choose_branch_to_deploy(project_name)
|
|
681
838
|
Dir.chdir "projects/#{project_name}"
|
|
682
839
|
output "Recupero la lista dei branch del progetto #{project_name}..."
|
|
683
|
-
`git remote prune origin`
|
|
684
840
|
out = %x[ git fetch ]
|
|
685
|
-
branches = %x[ git for-each-ref --sort=-committerdate refs/remotes/ --format='%(refname) %(objectname)
|
|
686
|
-
.split("\n").delete_if { |b| b.include?('HEAD') }[0..49]
|
|
687
|
-
|
|
688
|
-
master_branch = nil
|
|
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') || b.include?('dev') }[0..49]
|
|
689
843
|
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
end
|
|
694
|
-
|
|
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
|
|
844
|
+
branch_name = choose do |menu|
|
|
845
|
+
menu.prompt = "Scegli il branch di #{project_name} da deployare: ".cyan
|
|
846
|
+
menu.shell = true
|
|
702
847
|
|
|
703
|
-
|
|
848
|
+
branches.each do |branch|
|
|
704
849
|
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
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
|
|
850
|
+
title = @prima.reduce_size(branch, 100)
|
|
851
|
+
msg = "#{title}".light_blue
|
|
852
|
+
menu.choice(msg) { branch }
|
|
712
853
|
end
|
|
713
854
|
end
|
|
714
855
|
|
|
715
856
|
Dir.chdir "../../"
|
|
716
857
|
|
|
717
|
-
name = branch_name.split(' ')
|
|
718
|
-
revision = branch_name.split(' ')
|
|
719
|
-
|
|
720
|
-
{ 'name' => name, 'revision' => revision[0..14], 'committer' => committer_email, 'default_branch' => select_master }
|
|
858
|
+
name = branch_name.split(' ').first
|
|
859
|
+
revision = branch_name.split(' ').last
|
|
860
|
+
{ name: name, revision: revision[0..14] }
|
|
721
861
|
end
|
|
722
862
|
|
|
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
|
|
780
863
|
end
|
|
781
864
|
|
|
782
865
|
def help_content
|
|
@@ -793,24 +876,14 @@ Synopsis
|
|
|
793
876
|
twig release start
|
|
794
877
|
twig release finish
|
|
795
878
|
twig release deploy
|
|
796
|
-
twig release aggregator
|
|
797
879
|
|
|
798
880
|
Description
|
|
799
881
|
-----------
|
|
800
882
|
|
|
801
|
-
start
|
|
802
|
-
finish
|
|
803
|
-
|
|
804
|
-
|
|
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
|
|
883
|
+
start creates a new feature branch
|
|
884
|
+
finish finishes the feature by merging to dev and master
|
|
885
|
+
deploy deploys the feature branch to a temporary AWS Elastic Beanstalk env
|
|
886
|
+
deploy stop destroys the AWS Elastic Beanstalk env
|
|
814
887
|
|
|
815
888
|
Subcommand for Twig: <http://rondevera.github.io/twig/>
|
|
816
889
|
Author: Andrea Usuelli <https://github.com/andreausu>
|
|
@@ -825,11 +898,4 @@ if args.include?('--help')
|
|
|
825
898
|
exit
|
|
826
899
|
end
|
|
827
900
|
|
|
828
|
-
|
|
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)
|
|
901
|
+
Release.new.execute!(args)
|