prima-twig 0.10.4 → 0.13.37

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