prima-twig 0.13.1 → 0.13.37

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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,19 +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
- confirm_message = "Vuoi lanciare paparatzinger?"
94
- launch_paparatzinger = @prima.yesno confirm_message.blue
95
-
96
- if launch_paparatzinger
97
- output "Avvio paparatzinger per gli screenshot".yellow
98
- job_name = launch_paparatzinger(artifact[:commit_msg])
99
- end
100
-
101
102
  mail = Mail.new do
102
103
  from 'deploy@prima.it'
103
104
  to 'deploy@prima.it'
@@ -112,7 +113,6 @@ class Review
112
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"
113
114
  body << "Branch: [#{artifact[:branch]}](https://github.com/primait/prima/tree/#{artifact[:branch]})\n\n"
114
115
  body << "Commit: #{commit_msg.gsub(/_/, '\_')}\n\n"
115
- body << "Screenshots (tra qualche minuto): [BrowserStack](https://www.browserstack.com/automate) (Filtrare per: \"#{get_paparatzinger_job_name(commit_msg).gsub(/_/, '\_')}\")" if launch_paparatzinger
116
116
 
117
117
  htmlBody = Redcarpet::Markdown.new(Redcarpet::Render::HTML.new).render body
118
118
 
@@ -127,18 +127,38 @@ class Review
127
127
  mail.html_part = html_part
128
128
  mail.text_part = text_part
129
129
 
130
- opts = {address: 'smtp.mandrillapp.com', port: '587'}
131
- opts[:user_name] = 'deploy@prima.it'
132
- 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"
133
135
 
134
136
  mail.delivery_method(:smtp, opts)
135
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
136
156
  end
137
157
 
138
158
  def reload_parameters!
139
159
  artifact_rev = ''
140
160
  resp = @cf.describe_stacks({
141
- stack_name: "ecs-task-web-production"
161
+ stack_name: "ecs-task-web-vpc-production"
142
162
  })
143
163
  resp.stacks[0].parameters.each do |param|
144
164
  if param.parameter_key == 'ReleaseVersion'
@@ -167,111 +187,42 @@ class Review
167
187
  exec_step "git checkout #{artifact_rev}"
168
188
  exec_step deploy_command
169
189
 
170
- stack_name_web = 'ecs-task-web-production'
171
- stack_name_consumer = 'ecs-task-consumer-production'
172
- 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'
173
194
  wait_for_stack_ready(stack_name_web) unless stack_ready?(stack_name_web)
174
195
  wait_for_stack_ready(stack_name_consumer) unless stack_ready?(stack_name_consumer)
175
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)
176
198
  end
177
199
 
178
200
  def get_artifacts
179
201
  artifacts = []
180
- resp = @s3.list_objects(bucket: 'prima-artifacts', prefix: 'prima')
202
+ resp = @s3.list_objects(bucket: @s3_bucket, prefix: 'prima')
181
203
  resp.contents.each do |l|
182
- 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$/)
183
206
  if rev
184
- object = @s3.head_object(bucket: 'prima-artifacts', key: l.key)
207
+ object = @s3.head_object(bucket: @s3_bucket, key: l.key)
185
208
  commit_msg = ''
186
209
  commit_msg = Base64.decode64(object.metadata['commit_msg']).strip if object.metadata.has_key? 'commit_msg'
187
- 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')
188
211
  end
189
212
  end
190
213
  artifacts.sort_by { |v| v[:created_at] }.reverse
191
214
  end
192
215
 
193
- def wait_for_stack_ready(stack_name)
194
- ready = false
195
- sleep_seconds = 5
196
- output "Attendo che lo stack #{stack_name} finisca di essere deployato...\n".yellow
197
- while !ready
198
- ready = true if stack_ready?(stack_name)
199
- seconds_elapsed = 0
200
- while true
201
- break if seconds_elapsed >= sleep_seconds
202
- print '.'.yellow; STDOUT.flush
203
- sleep 1
204
- seconds_elapsed += 1
205
- end
206
- end
207
-
208
- output "\nStack #{stack_name} deployato con successo!\n".green
209
- end
210
-
211
- def stack_ready?(stack_name)
212
- resp = @cf.describe_stacks({
213
- stack_name: stack_name
214
- })
215
- ['CREATE_COMPLETE', 'UPDATE_COMPLETE'].include? resp.stacks[0].stack_status
216
- end
217
-
218
- def launch_paparatzinger(job_name)
219
- @s3.get_object(
220
- response_target: '/tmp/paparatzinger_twig.yml',
221
- bucket: 'prima-deploy',
222
- key: 'paparatzinger_twig.yml')
223
-
224
- paparatzinger_config = YAML.load_file '/tmp/paparatzinger_twig.yml'
216
+ def launch_crawler()
217
+ resp = describe_stack_resource('batch-job-crawler-production', 'JobDefinition')
225
218
 
226
- uri = URI.parse(paparatzinger_config['prima_api_search_url'])
227
- body = Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') do |http|
228
- req = Net::HTTP::Get.new(uri)
229
- req["x-apikey"] = paparatzinger_config['prima_api_token']
230
- response = http.request req
231
- response.body
232
- end
233
-
234
- saves = JSON.parse body
235
-
236
- unique_identifier = saves.sample["quote"]["unique_identifier"]
237
- url_garanzie = "https://www.prima.it/preventivo/auto/#{unique_identifier}/garanzie?browserstack=true"
238
- job_name = get_paparatzinger_job_name(clean_commit_message(job_name))
239
-
240
- logical_resource_id = 'TaskDefinitionPaparatzinger'
241
- resp = @cf.describe_stack_resource({
242
- stack_name: 'ecs-task-paparatzinger-production',
243
- 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
244
223
  })
245
224
 
246
- resp = @ecs.run_task({
247
- cluster: 'ecs-cluster-tools-ECSCluster-1I4THZHRXOTO5',
248
- task_definition: resp.stack_resource_detail.physical_resource_id,
249
- overrides: {
250
- container_overrides: [
251
- {
252
- name: 'paparatzinger',
253
- environment: [
254
- {
255
- name: 'JOB_NAME',
256
- value: job_name,
257
- },
258
- {
259
- name: 'VERSION',
260
- value: paparatzinger_config['version'],
261
- },
262
- {
263
- name: 'URL_GARANZIE',
264
- value: url_garanzie
265
- }
266
- ]
267
- }
268
- ]
269
- },
270
- count: 1
271
- })
272
- output "Paparatzinger lanciato con successo. URL: #{url_garanzie}\n".green
273
-
274
- job_name
225
+ output "Crawler lanciato con successo!\n".green
275
226
  end
276
227
 
277
228
  end
@@ -283,8 +234,15 @@ def clean_commit_message(commit_msg)
283
234
  commit_msg[0..99]
284
235
  end
285
236
 
286
- def get_paparatzinger_job_name(job_name)
287
- 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
288
246
  end
289
247
 
290
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!
72
+ else
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!
42
96
  else
43
- deploy_feature!
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,13 +267,8 @@ class Release
79
267
  end
80
268
 
81
269
  def deploy_shutdown!
82
- envs = {}
83
- stack_list.each do |stack|
84
- unless stack.stack_name.match(/spotfleet-allinone-qa-(\w+)$/)
85
- env_hash = stack.stack_name.match(/qa-(\w+)$/)[0]
86
- envs[env_hash] = stack.tags unless envs.has_key?(env_hash)
87
- end
88
- end
270
+ output "Recupero le informazioni sui QA attivi..."
271
+ stack_list, envs = get_stacks
89
272
 
90
273
  env_hash = nil
91
274
  unless envs.empty?
@@ -94,818 +277,511 @@ class Release
94
277
  menu.shell = true
95
278
 
96
279
  envs.each do |key, env|
97
- 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)
98
- 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
99
285
  menu.choice(msg) { key }
100
286
  end
101
287
  end
102
288
  else
103
- output "Nessun environment trovato".red
289
+ output 'Nessun environment trovato'.red
104
290
  exit
105
291
  end
106
292
 
107
293
  cluster_stack_name = nil
294
+ stacks_to_delete = []
108
295
  stack_list.each do |stack|
109
296
  if stack.stack_name.match(/#{env_hash}$/)
110
297
  if stack.stack_name.match(/ecs-cluster/)
111
298
  cluster_stack_name = stack.stack_name
112
299
  else
113
- 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)
114
303
  end
115
304
  end
116
305
  end
117
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
+
118
316
  # Se non ha finito di cancellare le altre non si puo' cancellare il cluster
119
- output "Attendo 60 secondi per poter eliminare il cluster ECS"
120
- 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
+
121
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])
122
330
  output "Finito!".green
123
331
  end
124
332
 
125
- def deploy_feature!
126
- `sudo true` # cosi' non chiede la password dopo
333
+ def deploy_lock!
334
+ output "Deploy update menu"
127
335
  `git pull && git submodule init && git submodule update`
128
- prima_branch = choose_branch_to_deploy('prima')
129
- backoffice_branch = choose_branch_to_deploy('backoffice')
130
- urania_branch = choose_branch_to_deploy('urania')
131
- ermes_branch = choose_branch_to_deploy('ermes')
132
- bburago_branch = choose_branch_to_deploy('bburago')
133
- socket_branch = {name: "master"}
134
- pamela_branch = {name: "master"}
135
-
136
- @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(/(-+$)/, '')
137
-
138
- tags = [
139
- {
140
- key: "prima",
141
- value: prima_branch[:name]
142
- },
143
- {
144
- key: "urania",
145
- value: urania_branch[:name]
146
- },
147
- {
148
- key: "backoffice",
149
- value: backoffice_branch[:name]
150
- },
151
- {
152
- key: "ermes",
153
- value: ermes_branch[:name]
154
- },
155
- {
156
- key: "bburago",
157
- value: bburago_branch[:name]
158
- }
159
- ]
160
-
161
- 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])
162
-
163
- cluster_stack_name = "ecs-cluster-qa-#{deploy_id}"
164
- create_cluster_stack(cluster_stack_name, tags) unless stack_exists?(cluster_stack_name)
165
- wait_for_stack_ready(cluster_stack_name) unless stack_ready?(cluster_stack_name)
166
-
167
- resp = @cf.describe_stack_resource({stack_name: cluster_stack_name, logical_resource_id: 'ECSCluster'})
168
- @ecs_cluster_name = resp.stack_resource_detail.physical_resource_id
169
-
170
- asg_stack_name = "ecs-asg-allinone-qa-#{deploy_id}"
171
- create_asg_stack(asg_stack_name, tags) unless stack_exists?(asg_stack_name)
172
-
173
- stack_name_db = "ecs-task-db-qa-#{deploy_id}"
174
- stack_body = IO.read('cloudformation/stacks/task/db.yml')
175
- parameters = [
176
- {
177
- parameter_key: "Environment",
178
- parameter_value: "qa"
179
- },
180
- {
181
- parameter_key: "ECSClusterName",
182
- parameter_value: @ecs_cluster_name
183
- }
184
- ]
185
- create_stack(stack_name_db, stack_body, parameters, tags) unless stack_exists?(stack_name_db)
186
-
187
- create_prima_artifact(prima_branch[:revision], prima_branch[:name]) unless artifact_exists?('prima-artifacts', "prima/#{prima_branch[:revision]}")
188
- create_urania_artifact(urania_branch[:revision]) unless artifact_exists?('prima-artifacts', "microservices/urania/#{urania_branch[:revision]}-qa.tar.gz")
189
- create_ermes_artifact(ermes_branch[:revision]) unless artifact_exists?('prima-artifacts', "microservices/ermes/#{ermes_branch[:revision]}-qa.tar.gz")
190
- create_bburago_artifact(bburago_branch[:revision]) unless artifact_exists?('prima-artifacts', "microservices/bburago/#{bburago_branch[:revision]}-qa.tar.gz")
191
- create_backoffice_artifact(backoffice_branch[:revision], deploy_id) unless artifact_exists?('prima-artifacts', "backoffice/#{backoffice_branch[:revision]}-#{deploy_id}.zip")
192
-
193
- wait_for_stack_ready(stack_name_db) unless stack_ready?(stack_name_db)
194
- import_dbs(ec2_ip_address(asg_stack_name)) unless stack_exists?("ecs-task-web-qa-#{deploy_id}")
195
-
196
- stack_name_web = "ecs-task-web-qa-#{deploy_id}"
197
- git_checkout_version('prima', prima_branch[:revision])
198
- stack_body = IO.read('projects/prima/app/cloudformation/tasks/web.yml')
199
- parameters = [
200
- {
201
- parameter_key: "Environment",
202
- parameter_value: "qa"
203
- },
204
- {
205
- parameter_key: "ReleaseVersion",
206
- parameter_value: prima_branch[:revision]
207
- },
208
- {
209
- parameter_key: "TaskDesiredCount",
210
- parameter_value: "1"
211
- },
212
- {
213
- parameter_key: "ECSClusterName",
214
- parameter_value: @ecs_cluster_name
215
- },
216
- {
217
- parameter_key: "ALBShortName",
218
- parameter_value: "ecs-task-web-qa-#{deploy_id}"[0..31]
219
- },
220
- {
221
- parameter_key: "WebQaBaseHostname",
222
- parameter_value: "#{@dns_record_identifier}.qa.colaster.com"
223
- }
224
- ]
225
- if stack_exists?(stack_name_web)
226
- update_stack(stack_name_web, stack_body, parameters) if @prima_built
227
- else
228
- create_stack(stack_name_web, stack_body, parameters, tags)
229
- end
230
-
231
- stack_name_consumer = "ecs-task-consumer-qa-#{deploy_id}"
232
- git_checkout_version('prima', prima_branch[:revision])
233
- stack_body = IO.read('projects/prima/app/cloudformation/tasks/consumer.yml')
234
- parameters = [
235
- {
236
- parameter_key: "Environment",
237
- parameter_value: "qa"
238
- },
239
- {
240
- parameter_key: "ReleaseVersion",
241
- parameter_value: prima_branch[:revision]
242
- },
243
- {
244
- parameter_key: "ECSClusterName",
245
- parameter_value: @ecs_cluster_name
246
- }
247
- ]
248
- if stack_exists?(stack_name_consumer)
249
- update_stack(stack_name_consumer, stack_body, parameters) if @prima_built
250
- else
251
- create_stack(stack_name_consumer, stack_body, parameters, tags)
252
- end
253
-
254
- stack_name_urania = "ecs-task-urania-qa-#{deploy_id}"
255
- git_checkout_version('urania', urania_branch[:revision])
256
- stack_body = IO.read('projects/urania/deploy/task.yml')
257
- parameters = [
258
- {
259
- parameter_key: "Environment",
260
- parameter_value: "qa"
261
- },
262
- {
263
- parameter_key: "ReleaseVersion",
264
- parameter_value: urania_branch[:revision]
265
- },
266
- {
267
- parameter_key: "TaskDesiredCount",
268
- parameter_value: "1"
269
- },
270
- {
271
- parameter_key: "ECSClusterName",
272
- parameter_value: @ecs_cluster_name
273
- },
274
- {
275
- parameter_key: "ALBShortName",
276
- parameter_value: "ecs-task-urania-qa-#{deploy_id}"[0..31]
277
- }
278
- ]
279
- if stack_exists?(stack_name_urania)
280
- update_stack(stack_name_urania, stack_body, parameters) if @urania_built
281
- else
282
- create_stack(stack_name_urania, stack_body, parameters, tags)
283
- end
284
-
285
- stack_name_ermes = "ecs-task-ermes-qa-#{deploy_id}"
286
- git_checkout_version('ermes', ermes_branch[:revision])
287
- stack_body = IO.read('projects/ermes/deploy/task.yml')
288
- parameters = [
289
- {
290
- parameter_key: "Environment",
291
- parameter_value: "qa"
292
- },
293
- {
294
- parameter_key: "ReleaseVersion",
295
- parameter_value: ermes_branch[:revision]
296
- },
297
- {
298
- parameter_key: "ECSClusterName",
299
- parameter_value: @ecs_cluster_name
300
- }
301
- ]
302
- if stack_exists?(stack_name_ermes)
303
- update_stack(stack_name_ermes, stack_body, parameters) if @ermes_built
304
- else
305
- create_stack(stack_name_ermes, stack_body, parameters, tags)
306
- end
307
-
308
- stack_name_bburago = "ecs-task-bburago-qa-#{deploy_id}"
309
- git_checkout_version('bburago', bburago_branch[:revision])
310
- stack_body = IO.read('projects/bburago/deploy/task.yml')
311
- parameters = [
312
- {
313
- parameter_key: "Environment",
314
- parameter_value: "qa"
315
- },
316
- {
317
- parameter_key: "ReleaseVersion",
318
- parameter_value: bburago_branch[:revision]
319
- },
320
- {
321
- parameter_key: "ECSClusterName",
322
- parameter_value: @ecs_cluster_name
323
- },
324
- {
325
- parameter_key: "TaskDesiredCount",
326
- parameter_value: "1"
327
- },
328
- {
329
- parameter_key: "ALBShortName",
330
- parameter_value: "ecs-task-bburago-qa-#{deploy_id}"[0..31]
331
- }
332
- ]
333
- if stack_exists?(stack_name_bburago)
334
- update_stack(stack_name_bburago, stack_body, parameters) if @bburago_built
335
- else
336
- create_stack(stack_name_bburago, stack_body, parameters, tags)
337
- end
338
-
339
- git_checkout_version('backoffice', backoffice_branch[:revision])
340
- stack_name_backoffice = "ecs-task-backoffice-qa-#{deploy_id}"
341
- stack_body = IO.read('projects/backoffice/deploy/task.yml')
342
- parameters = [
343
- {
344
- parameter_key: "Environment",
345
- parameter_value: "qa"
346
- },
347
- {
348
- parameter_key: "ReleaseVersion",
349
- parameter_value: "#{backoffice_branch[:revision]}-#{deploy_id}"
350
- },
351
- {
352
- parameter_key: "TaskDesiredCount",
353
- parameter_value: "1"
354
- },
355
- {
356
- parameter_key: "ECSClusterName",
357
- parameter_value: @ecs_cluster_name
358
- },
359
- {
360
- parameter_key: "ALBShortName",
361
- parameter_value: "ecs-task-backoffice-qa-#{deploy_id}"[0..31]
362
- }
363
- ]
364
- if stack_exists?(stack_name_backoffice)
365
- 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
366
356
  else
367
- create_stack(stack_name_backoffice, stack_body, parameters, tags)
357
+ output "Nessun QA trovato".red
358
+ exit
368
359
  end
369
360
 
370
- wait_for_stack_ready(stack_name_web) unless stack_ready?(stack_name_web)
371
- wait_for_stack_ready(stack_name_consumer) unless stack_ready?(stack_name_consumer)
372
- wait_for_stack_ready(stack_name_urania) unless stack_ready?(stack_name_urania)
373
- wait_for_stack_ready(stack_name_backoffice) unless stack_ready?(stack_name_backoffice)
374
- wait_for_stack_ready(stack_name_ermes) unless stack_ready?(stack_name_ermes)
375
- wait_for_stack_ready(stack_name_bburago) unless stack_ready?(stack_name_bburago)
376
-
377
- update_service_defaults(stack_name_web)
378
- update_service_defaults(stack_name_consumer)
379
- update_service_defaults(stack_name_urania)
380
- update_service_defaults(stack_name_backoffice)
381
- update_service_defaults(stack_name_ermes)
382
- update_service_defaults(stack_name_bburago)
383
-
384
- stack_name_route53 = "ecs-route53-qa-#{deploy_id}"
385
- stack_body = IO.read('cloudformation/stacks/route53/qa.yml')
386
- parameters = [
387
- {
388
- parameter_key: "DnsRecordIdentifier",
389
- parameter_value: @dns_record_identifier
390
- },
391
- {
392
- parameter_key: "PrimaElbHostname",
393
- parameter_value: get_alb_host(stack_name_web)
394
- },
395
- {
396
- parameter_key: "BackofficeElbHostname",
397
- parameter_value: get_alb_host(stack_name_backoffice)
398
- },
399
- {
400
- parameter_key: "UraniaElbHostname",
401
- parameter_value: get_alb_host(stack_name_urania)
402
- },
403
- {
404
- parameter_key: "BburagoElbHostname",
405
- parameter_value: get_alb_host(stack_name_bburago)
406
- }
407
- ]
408
- create_stack(stack_name_route53, stack_body, parameters, tags) unless stack_exists?(stack_name_route53)
409
-
410
- prima_hostname = get_route53_hostname(stack_name_web)
411
- urania_hostname = get_route53_hostname(stack_name_urania)
412
- bburago_hostname = get_route53_hostname(stack_name_bburago)
413
- backoffice_hostname = get_route53_hostname(stack_name_backoffice)
414
-
415
- wait_for_stack_ready(stack_name_route53) unless stack_ready?(stack_name_route53)
416
-
417
- output "Prima url: #{prima_hostname}\n".cyan
418
- output "Prima RI url: #{prima_hostname.sub("www", "wwwri")}\n".cyan
419
- output "Urania url: #{urania_hostname}\n".cyan
420
- output "Backoffice url: #{backoffice_hostname}\n".cyan
421
- output "Bburago url: #{bburago_hostname}\n".cyan
422
- output "SSH connection: ssh ec2-user@#{ec2_ip_address(asg_stack_name)} -i ~/.ssh/ecs-cluster-qa.pem".cyan
423
- output "Deploy effettuato, everything is awesome!\n".green
424
- end
425
-
426
- def get_route53_hostname(stack_name)
427
- case
428
- when stack_name.include?('web')
429
- host = "www.#{@dns_record_identifier}.qa.colaster.com"
430
- when stack_name.include?('urania')
431
- host = "urania.#{@dns_record_identifier}.qa.colaster.com"
432
- when stack_name.include?('backoffice')
433
- host = "backoffice.#{@dns_record_identifier}.qa.colaster.com"
434
- when stack_name.include?('bburago')
435
- 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
436
366
  end
437
- host
438
- end
439
367
 
440
- def ec2_ip_address(asg_stack_name)
441
- resp = @cf.describe_stack_resource({
442
- stack_name: asg_stack_name,
443
- logical_resource_id: 'ECSAutoScalingGroup'
444
- })
445
- resp = @asg.describe_auto_scaling_groups({
446
- auto_scaling_group_names: [resp.stack_resource_detail.physical_resource_id],
447
- max_records: 1
448
- })
449
- instance_id = resp.auto_scaling_groups[0].instances[0].instance_id
450
- resp = @ec2.describe_instances({instance_ids: [instance_id]})
451
- resp.reservations[0].instances[0].private_ip_address
452
- end
368
+ update_cluster_stack(cluster_stack_name, tags)
453
369
 
454
- def get_alb_host(stack_name)
455
- case
456
- when stack_name.include?('web')
457
- logical_resource_id = 'EcsApplicationLoadBalancerPublic'
458
- when stack_name.include?('urania')
459
- logical_resource_id = 'EcsApplicationLoadBalancerInternal'
460
- when stack_name.include?('backoffice')
461
- logical_resource_id = 'EcsApplicationLoadBalancerPublic'
462
- when stack_name.include?('bburago')
463
- logical_resource_id = 'EcsApplicationLoadBalancerInternal'
464
- end
465
- resp = @cf.describe_stack_resource({
466
- stack_name: stack_name,
467
- logical_resource_id: logical_resource_id
468
- })
469
- resp = @alb.describe_load_balancers({
470
- load_balancer_arns: [resp.stack_resource_detail.physical_resource_id]
471
- })
472
- resp.load_balancers[0].dns_name
370
+ output "Finito!".green
473
371
  end
474
372
 
475
- def get_elb_host(stack_name)
476
- case
477
- when stack_name.include?('web')
478
- logical_resource_id = 'EcsElasticLoadBalancerPublic'
479
- when stack_name.include?('urania')
480
- logical_resource_id = 'EcsElasticLoadBalancerInternal'
481
- when stack_name.include?('backoffice')
482
- logical_resource_id = 'EcsElasticLoadBalancerPublic'
483
- when stack_name.include?('bburago')
484
- logical_resource_id = 'EcsElasticLoadBalancerInternal'
485
- end
486
- resp = @cf.describe_stack_resource({
487
- stack_name: stack_name,
488
- logical_resource_id: logical_resource_id
489
- })
490
- resp = @elb.describe_load_balancers({
491
- load_balancer_names: [resp.stack_resource_detail.physical_resource_id],
492
- page_size: 1
493
- })
494
- resp.load_balancer_descriptions[0].dns_name
495
- end
373
+ def deploy_update!
374
+ output "Deploy update menu"
375
+ `git pull && git submodule init && git submodule update`
496
376
 
497
- def update_service_defaults(stack_name)
498
- case
499
- when stack_name.include?('web')
500
- logical_resource_id = 'ECSServiceWeb'
501
- when stack_name.include?('consumer')
502
- logical_resource_id = 'ECSServiceConsumer'
503
- when stack_name.include?('urania')
504
- logical_resource_id = 'ECSServiceUrania'
505
- when stack_name.include?('backoffice')
506
- logical_resource_id = 'ECSServiceBackoffice'
507
- when stack_name.include?('ermes')
508
- logical_resource_id = 'ECSServiceErmes'
509
- when stack_name.include?('bburago')
510
- logical_resource_id = 'ECSServiceBburago'
511
- else
512
- raise "Service name non gestito per lo stack #{stack_name}"
513
- end
514
- resp = @cf.describe_stack_resource({
515
- stack_name: stack_name,
516
- logical_resource_id: logical_resource_id
517
- })
518
- resp = @ecs.update_service({
519
- cluster: @ecs_cluster_name,
520
- service: resp.stack_resource_detail.physical_resource_id,
521
- deployment_configuration: {
522
- minimum_healthy_percent: 0,
523
- maximum_percent: 100
524
- }
525
- })
526
- end
527
-
528
- def create_urania_artifact(revision)
529
- @urania_built = true
530
- output "Preparo l'artifact .zip\n".yellow
531
-
532
- git_checkout_version('urania', revision)
533
-
534
- Dir.chdir 'projects/urania'
535
-
536
- [
537
- "docker-compose build web",
538
- "docker run -v $PWD:/code -w /code -e MIX_ENV=qa --entrypoint /bin/sh urania_web \
539
- '-c' 'mix local.hex --force && mix hex.info && \
540
- mix deps.get && mix compile && mix deps.compile && \
541
- mv rel/vm.args rel/config.exs /tmp/ && mix release.clean --implode --no-confirm && \
542
- mkdir rel && mv /tmp/vm.args /tmp/config.exs rel/ && mix release --env=qa'",
543
- "sudo chown -R `whoami` ."
544
- ].each do |cmd|
545
- output "Eseguo #{cmd}".yellow
546
- res = %x[ #{cmd} ]
547
- if $?.exitstatus != 0
548
- color = 'red'
549
- else
550
- 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
551
395
  end
552
- output res.send color
553
- stop_if (color == 'red'), "Errore durante la build dell'artifact".red
396
+ else
397
+ output "Nessun QA trovato".red
398
+ exit
554
399
  end
555
400
 
556
- artifact_path = Dir.glob("rel/urania/releases/*/urania.tar.gz").first
557
- 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!
558
407
 
559
- Dir.chdir '../../'
408
+ output "Finito!".green
560
409
  end
561
410
 
562
- def create_ermes_artifact(revision)
563
- @ermes_built = true
564
- 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
565
416
 
566
- git_checkout_version('ermes', revision)
417
+ def suite_py_branches(args_json)
418
+ arg_projects = JSON.parse(args_json)
567
419
 
568
- Dir.chdir 'projects/ermes'
420
+ @projects.merge!(arg_projects)
569
421
 
570
- [
571
- "docker-compose build app",
572
- "docker run -v $PWD:/code -w /code -e MIX_ENV=qa --entrypoint /bin/sh ermes_app \
573
- '-c' 'mix local.hex --force && mix hex.info && \
574
- mix deps.get && mix compile && mix deps.compile && \
575
- mv rel/vm.args rel/config.exs /tmp/ && mix release.clean --implode --no-confirm && \
576
- mkdir rel && mv /tmp/vm.args /tmp/config.exs rel/ && mix release --env=qa'",
577
- "sudo chown -R `whoami` ."
578
- ].each do |cmd|
579
- output "Eseguo #{cmd}".yellow
580
- res = %x[ #{cmd} ]
581
- if $?.exitstatus != 0
582
- color = 'red'
583
- else
584
- color = 'green'
422
+ @projects.each_key do |project|
423
+ if @projects[project].empty?
424
+ @projects[project] = choose_branch_to_deploy(project, true)
585
425
  end
586
- output res.send color
587
- stop_if (color == 'red'), "Errore durante la build dell'artifact".red
588
426
  end
427
+ end
589
428
 
590
- artifact_path = Dir.glob("rel/ermes/releases/*/ermes.tar.gz").first
591
- upload_artifact(artifact_path, "microservices/ermes/#{revision}-qa.tar.gz")
592
-
593
- Dir.chdir '../../'
429
+ def get_git_user()
430
+ `git config user.name`.gsub(/[^A-Za-z]/, '').gsub("\n", '')
594
431
  end
595
432
 
596
- def create_bburago_artifact(revision)
597
- @bburago_built = true
598
- output "Preparo l'artifact .zip\n".yellow
433
+ def get_git_mail()
434
+ `git config user.email`.gsub("\n", '')
435
+ end
599
436
 
600
- 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`
601
439
 
602
- 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`
603
441
 
604
- [
605
- "docker-compose build web",
606
- "docker run -v $PWD:/code -w /code -e MIX_ENV=qa --entrypoint /bin/sh bburago_web \
607
- '-c' 'mix local.hex --force && mix hex.info && \
608
- mix deps.get && mix compile && mix deps.compile && \
609
- mv rel/vm.args rel/config.exs /tmp/ && mix release.clean --implode --no-confirm && \
610
- mkdir rel && mv /tmp/vm.args /tmp/config.exs rel/ && mix release --env=qa'",
611
- "sudo chown -R `whoami` ."
612
- ].each do |cmd|
613
- output "Eseguo #{cmd}".yellow
614
- res = %x[ #{cmd} ]
615
- if $?.exitstatus != 0
616
- color = 'red'
617
- else
618
- color = 'green'
619
- end
620
- output res.send color
621
- 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)
622
447
  end
448
+ feature_number = default_name if feature_number.empty?
449
+ branch_name = get_git_user + '_' + feature_number
623
450
 
624
- artifact_path = Dir.glob("rel/bburago/releases/*/bburago.tar.gz").first
625
- 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
626
456
 
627
- Dir.chdir '../../'
628
- end
457
+ @git_branch = branch_name
629
458
 
630
- def create_backoffice_artifact(revision, deploy_id)
631
- @backoffice_built = true
632
- output "Preparo l'artifact .zip\n".yellow
459
+ File.open('branch_names', 'w') { |file| file.write(JSON.generate(@projects)) }
633
460
 
634
- git_checkout_version('backoffice', revision)
461
+ update_drone_yml!
635
462
 
636
- 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
637
469
 
638
- ['node_modules'].each do |dir|
639
- unless File.directory?(dir)
640
- if File.directory?("../../../backoffice/#{dir}")
641
- exec_step "rsync -a ../../../backoffice/#{dir} ."
642
- 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 }
643
486
  end
644
487
  end
488
+ # checkout master, checkout branch, pull branch
489
+ `git checkout master && git checkout #{chosen_branch} && git pull`
645
490
 
646
- stack_name_web = "ecs-task-web-qa-notneeded"
647
- web_qa_host = get_route53_hostname(stack_name_web)
648
- webri_qa_host = web_qa_host.sub("www", "wwwri")
649
-
650
- [
651
- "docker-compose build workers",
652
- "cd ../../ && docker run -e GIT_DIR=$PWD -v $PWD:/usr/app/src -w /usr/app/src/projects/backoffice blinkmobile/bower install --allow-root",
653
- "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 && sed -i \"s/web-qa-ri-url/#{webri_qa_host}/g\" Gruntfile.js && npm install && grunt qa'",
654
- "sudo chown -R `whoami` ."
655
- ].each do |cmd|
656
- output "Eseguo #{cmd}".yellow
657
- res = %x[ #{cmd} ]
658
- if $?.exitstatus != 0
659
- color = 'red'
660
- else
661
- color = 'green'
491
+ # aggiornare il commit (revision a cui fa riferimento)
492
+
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)
662
498
  end
663
- output res.send color
664
- stop_if (color == 'red'), "Errore durante la build dell'artifact".red
665
499
  end
666
500
 
667
- artifact_path = '/tmp/backoffice.zip'
668
- exec_step "rm -f #{artifact_path} && zip -9 -r #{artifact_path} bin/"
669
- upload_artifact(artifact_path, "backoffice/#{revision}-#{deploy_id}.zip")
670
-
671
- Dir.chdir '../../'
672
- 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
673
505
 
674
- def create_prima_artifact(revision, branch_name)
675
- @prima_built = true
676
- output "Preparo l'artifact .zip\n".yellow
506
+ File.open('branch_names', 'w') { |file| file.write(JSON.generate(@projects)) }
677
507
 
678
- git_checkout_version('prima', revision)
508
+ update_drone_yml!
679
509
 
680
- Dir.chdir 'projects/prima'
510
+ `git add branch_names .drone.yml`
511
+ `git commit -m 'update'`
512
+ `git push && git checkout master`
513
+ end
681
514
 
682
- ['vendor'].each do |dir|
683
- unless File.directory?(dir)
684
- if File.directory?("../../../prima/#{dir}")
685
- 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 }
686
530
  end
687
531
  end
532
+ else
533
+ chosen_branch = selection
688
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
689
539
 
690
- backoffice_qa_host = get_route53_hostname("ecs-task-backoffice-qa-notneeded")
691
- 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
692
543
 
693
- [
694
- "bin/local_build_artifact.sh #{branch_name} #{web_qa_host} #{backoffice_qa_host}"
695
- ].each do |cmd|
696
- output "Eseguo #{cmd}".yellow
697
- res = %x[ #{cmd} ]
698
- if $?.exitstatus != 0
699
- color = 'red'
700
- else
701
- 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
702
557
  end
703
- output res.send color
704
- exec_step "docker stop redis" if color == 'red'
705
- stop_if (color == 'red'), "Errore durante la build dell'artifact".red
706
558
  end
707
559
 
708
- Dir.chdir "../../"
709
- end
710
-
711
- def git_checkout_version(project, revision)
712
- Dir.chdir "projects/#{project}"
713
- exec_step "git checkout -- . && git clean -f -d && git checkout #{revision}"
714
- Dir.chdir "../../"
715
- 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)
716
565
 
717
- def upload_artifact(source_path, destination_path)
718
- output "Upload dell'artifact in corso (#{(File.size(source_path).to_f / 2**20).round(2)} MiB)\n".yellow
719
- s3 = Aws::S3::Resource.new
720
- obj = s3.bucket(@s3_bucket).object(destination_path)
721
- obj.upload_file(source_path)
566
+ if aggregator_enabled
567
+ dns_to_staging(env_hash)
568
+ end
569
+ end
722
570
 
723
- output "#{@s3_bucket}/#{destination_path} uploadato con successo!\n".green
724
- 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"
725
573
 
726
- def wait_for_stack_ready(stack_name)
727
- ready = false
728
- sleep_seconds = 10
729
- output "Attendo che lo stack #{stack_name} finisca di essere inizializzato...\n".yellow
730
- while !ready
731
- ready = true if stack_ready?(stack_name)
732
- seconds_elapsed = 0
733
- while true
734
- break if seconds_elapsed >= sleep_seconds
735
- print '.'.yellow; STDOUT.flush
736
- sleep 1
737
- 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)
738
578
  end
579
+ output "Stack ancora attivi: #{stacks_to_delete.length.to_s}. Attendo altri 10 secondi per eliminare il cluster ECS"
739
580
  end
740
581
 
741
- output "\nStack #{stack_name} pronto!\n".green
742
- end
743
-
744
- def stack_list
745
- resp = @cf.describe_stacks
746
- stacks = resp.stacks
747
- stacks.keep_if { |stack| stack.stack_name.include? '-qa-' }
748
- 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
749
589
  end
750
590
 
751
- def delete_stack(stack_name)
752
- @cf.delete_stack({stack_name: stack_name})
753
- 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
754
596
  end
755
597
 
756
- def stack_ready?(stack_name)
757
- resp = @cf.describe_stacks({
758
- stack_name: stack_name
759
- })
760
- ['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
761
606
  end
762
607
 
763
- def create_asg_stack(stack_name, tags = [])
764
- stack_body = IO.read('cloudformation/stacks/asg/ecs-asg-allinone.yml')
765
- parameters = [
766
- {
767
- parameter_key: "Environment",
768
- parameter_value: "qa"
769
- },
770
- {
771
- parameter_key: "InstanceType",
772
- parameter_value: "t2.large"
773
- },
774
- {
775
- parameter_key: "ECSClusterName",
776
- parameter_value: @ecs_cluster_name
777
- }
778
- ]
779
- 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
780
615
  end
781
616
 
782
- def create_cluster_stack(stack_name, tags = [])
783
- stack_body = IO.read('cloudformation/stacks/ecs-cluster.yml')
784
- create_stack(stack_name, stack_body, [], tags)
785
- end
786
-
787
- def import_dbs(ip_address)
788
- resp = @ecs.run_task({
789
- cluster: @ecs_cluster_name,
790
- task_definition: @import_db_task,
791
- overrides: {
792
- container_overrides: [
793
- {
794
- name: 'dbrestore',
795
- environment: [
796
- {
797
- name: 'EC2_IP_ADDRESS',
798
- value: ip_address,
799
- }
800
- ]
801
- }
802
- ]
803
- },
804
- count: 1
805
- })
806
- output "Attendo che i DB vengano importati...\n".yellow
807
- stopped_at = nil
808
- while stopped_at.nil?
809
- resp = @ecs.describe_tasks({
810
- cluster: @ecs_cluster_name,
811
- tasks: [resp.tasks[0].task_arn]
812
- })
813
- stopped_at = resp.tasks[0].stopped_at
814
- sleep_seconds = 10
815
- seconds_elapsed = 0
816
- while true && stopped_at.nil?
817
- break if seconds_elapsed >= sleep_seconds
818
- print '.'.yellow; STDOUT.flush
819
- sleep 1
820
- seconds_elapsed += 1
821
- 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'
822
661
  end
823
- 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
824
665
  end
825
666
 
826
- def stack_exists?(stack_name)
827
- begin
828
- res = @cf.describe_stacks({
829
- stack_name: stack_name
830
- })
831
- rescue Aws::CloudFormation::Errors::ValidationError => e
832
- if e.message.include? 'does not exist'
833
- false
834
- else
835
- raise e
836
- end
667
+ def deploy_pyxis?
668
+ if defined? @deploy_pyxis
669
+ @deploy_pyxis
837
670
  else
838
- true
839
- end
840
- end
841
-
842
- def create_stack(stack_name, stack_body, parameters = [], tags = [])
843
- @cf.create_stack({
844
- stack_name: stack_name,
845
- template_body: stack_body,
846
- parameters: parameters,
847
- tags: tags,
848
- capabilities: ["CAPABILITY_IAM"],
849
- on_failure: "ROLLBACK"
850
- })
851
- output "La creazione dello stack #{stack_name} è stata avviata".green
852
- end
853
-
854
- def update_stack(stack_name, stack_body, parameters = [])
855
- begin
856
- @cf.update_stack({
857
- stack_name: stack_name,
858
- template_body: stack_body,
859
- parameters: parameters,
860
- capabilities: ["CAPABILITY_IAM"]
861
- })
862
- rescue Aws::CloudFormation::Errors::ValidationError => e
863
- # if e.message.include? 'does not exist'
864
- # false
865
- # else
866
- # raise e
867
- # end
868
- raise e
869
- else
870
- 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
871
677
  end
872
678
  end
873
679
 
874
- def artifact_exists?(bucket, path)
875
- resp = @s3.list_objects({
876
- bucket: bucket,
877
- max_keys: 1,
878
- prefix: path
879
- })
880
- !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)
881
683
  end
882
684
 
883
- def choose_branch_to_deploy(project_name)
685
+ def choose_branch_to_deploy(project_name, select_master = false)
884
686
  Dir.chdir "projects/#{project_name}"
885
687
  output "Recupero la lista dei branch del progetto #{project_name}..."
688
+ `git remote prune origin`
886
689
  out = %x[ git fetch ]
887
- branches = %x[ git for-each-ref --sort=-committerdate refs/remotes/ --format='%(refname) %(objectname)' | sed 's/refs\\/remotes\\/origin\\///g' ]
888
- .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]
889
692
 
890
- branch_name = choose do |menu|
891
- menu.prompt = "Scegli il branch di #{project_name} da deployare: ".cyan
892
- menu.shell = true
693
+ master_branch = nil
893
694
 
894
- 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
895
699
 
896
- title = @prima.reduce_size(branch, 100)
897
- msg = "#{title}".light_blue
898
- 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
899
717
  end
900
718
  end
901
719
 
902
720
  Dir.chdir "../../"
903
721
 
904
- name = branch_name.split(' ').first
905
- revision = branch_name.split(' ').last
906
- { 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 }
726
+ end
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
907
766
  end
908
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
909
785
  end
910
786
 
911
787
  def help_content
@@ -922,14 +798,24 @@ Synopsis
922
798
  twig release start
923
799
  twig release finish
924
800
  twig release deploy
801
+ twig release aggregator
925
802
 
926
803
  Description
927
804
  -----------
928
805
 
929
- start creates a new feature branch
930
- finish finishes the feature by merging to dev and master
931
- deploy deploys the feature branch to a temporary AWS Elastic Beanstalk env
932
- 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
933
819
 
934
820
  Subcommand for Twig: <http://rondevera.github.io/twig/>
935
821
  Author: Andrea Usuelli <https://github.com/andreausu>
@@ -944,4 +830,11 @@ if args.include?('--help')
944
830
  exit
945
831
  end
946
832
 
947
- 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)