prima-twig 0.5.27 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/bin/twig-deploy +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)
|