prima-twig 1.2.3 → 1.3.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a8d26488e09dd811fb37302eb857d843490d31cb6f4a3661eed8bfdaa3971320
4
- data.tar.gz: 6b851729f8a6215aaee3d092f8378e60a54b2faa905ffea229ac6fcf28c25227
3
+ metadata.gz: '09541078fde402e2d946e124ce853c73c8d15bb991856dec8ab72d4710be3a89'
4
+ data.tar.gz: 8096a9c027734f911ba04522d4b05be02d6b56f85b631a01aadd86e2f0e7efaf
5
5
  SHA512:
6
- metadata.gz: e077ed692aa53693dd06b1658c72feab99c24d4ffbe5a8d050041774ce1d2926ff7379779b5c30ef43131a4b2972cce4cbbf2e459d202b2e92c18b46a9524a38
7
- data.tar.gz: b9f4db60c9a24d2f578ab5cb928021483187a53e1a98f1bce290a599702a51b722d1b4604cbbc9fe04d2aca8c7fd9ba61257c3f0837b4b90b0d5f8c87a70a80d
6
+ metadata.gz: f316f41c7590ec8503b7db4f571bffa1bd16ea9f4ffdededf34cb8b8d24f0a15f925a52f7c8d2c11efffc0dfff109a56c3d8f262946d92e50d53082bb4144091
7
+ data.tar.gz: 703594fdb2419ae16b7cb6ff77dd2f843885610d83c4e29f1424221ab7cd71176db3be9297025079f5e565251fa8827b711d28455a18c5706568a8ac20e68dd8
@@ -47,7 +47,8 @@ class Release
47
47
  'legion' => {},
48
48
  'vianello' => {},
49
49
  'domus' => {},
50
- 'toretto' => {}
50
+ 'toretto' => {},
51
+ 'lira' => {}
51
52
  }
52
53
  @base_stack_name_alb = 'ecs-alb-http-public-qa-'
53
54
  @base_stack_name_alb_ws = 'ecs-alb-ws-public-qa-'
@@ -326,22 +327,7 @@ class Release
326
327
  tags.push tag_keep_data
327
328
  end
328
329
 
329
- parameters = [
330
- {
331
- parameter_key: "Environment",
332
- parameter_value: "qa"
333
- },
334
- {
335
- parameter_key: "Country",
336
- parameter_value: "IT"
337
- },
338
- {
339
- parameter_key: "ClusterRole",
340
- parameter_value: "allinone"
341
- }
342
- ]
343
-
344
- update_cluster_stack(cluster_stack_name, tags, parameters)
330
+ update_cluster_stack(cluster_stack_name, tags, get_stack_parameters(cluster_stack_name))
345
331
 
346
332
  output "Finito!".green
347
333
  end
@@ -0,0 +1,84 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require_relative '../lib/prima_twig'
5
+ require 'launchy'
6
+ require 'yaml'
7
+
8
+ class TwigPackerBuilder
9
+ include Command
10
+
11
+ def initialize
12
+ output 'Checking for new gem releases...'
13
+ unless `gem outdated`.lines.grep(/^prima-twig \(.*\)/).empty?
14
+ exec "gem update prima-twig && twig update-ami #{ARGV.join ' '}"
15
+ end
16
+ @templates_path = "#{Dir.pwd}/amis"
17
+ end
18
+
19
+ def execute!(args)
20
+ @template_name = args[0]
21
+ @env = args[1]
22
+ @country = args[2]
23
+
24
+ File.open("#{Dir.pwd}/ami_state.yml", 'r') do |f|
25
+ @config = YAML.load(f.read)
26
+ end
27
+
28
+ @country_conf = @config['countries'].detect { |country| country['name'] == @country }
29
+ stop_if(@country_conf.nil?, "Cannot find country #{@country} inside ami_state.yml, exiting...".red)
30
+
31
+ @ami_conf = @country_conf['amis'].detect { |ami| ami['template'] == @template_name and ami['env'] == @env }
32
+ stop_if(@ami_conf.nil?, "Cannot find an ami in #{@country} generated from #{@template_name} and env #{@env} inside ami_state.yml, exiting...".red)
33
+
34
+ output "Starting update process with #{@template_name} in env #{@env} in country #{@country}".light_green
35
+ output 'running packer (this could take some time)'.light_green
36
+ new_ami_id = execute_packer
37
+ stop_if(new_ami_id.to_s.empty?, 'Failed to generate AMI!'.red)
38
+
39
+ output "new ami id: #{new_ami_id}".light_green
40
+ output "ami id that can be replaced: #{@ami_conf['id']}".light_green
41
+ output "you can run \"aws-vault exec YOUR_CONTRY_PROFILE -- twig-update-ami #{@ami_conf['id']} #{new_ami_id}\" to update all stacks".light_green
42
+ output 'Done'.light_green
43
+ end
44
+
45
+ private
46
+
47
+ def execute_packer
48
+ execute_command "AWS_MAX_ATTEMPTS=90 AWS_POLL_DELAY_SECONDS=60 packer build -var env=#{@env} -var teams_mapping=#{@ami_conf['teams_mapping']} -var country=#{@country} -var aws_account=#{@country_conf['aws_account']} -machine-readable #{@templates_path}/#{@template_name} | tee build.log"
49
+
50
+ `grep 'artifact,0,id' build.log | cut -d, -f6 | cut -d: -f2`.sub(/\n/, '')
51
+ end
52
+
53
+ def help_content
54
+ <<-HELP
55
+
56
+ twig-packer-builder
57
+ ===========
58
+
59
+ Creates AMIs using umami's templates
60
+
61
+ Synopsis
62
+ --------
63
+
64
+ twig-packer-builder
65
+
66
+ Description
67
+ -----------
68
+
69
+ from umami main folder run
70
+ `aws-vault exec AWS_PROFILE_WITH_ACCESS_TO_COMMON_ACCOUNT -- twig-update-ami ${AMI_TEMPLATE} ${ENV} ${COUNTRY}`
71
+
72
+ Subcommand for Twig: <http://rondevera.github.io/twig/>
73
+ HELP
74
+ end
75
+
76
+ args = ARGV.dup
77
+
78
+ if args.include?('--help')
79
+ puts help_content
80
+ exit
81
+ end
82
+
83
+ TwigPackerBuilder.new.execute!(args)
84
+ end
@@ -1,154 +1,105 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
3
  require 'rubygems'
4
- require_relative '../lib/prima_twig.rb'
5
- require_relative '../lib/prima_aws_client.rb'
4
+ require_relative '../lib/prima_twig'
5
+ require_relative '../lib/prima_aws_client'
6
6
  require 'launchy'
7
- require 'json'
8
- require 'aws-sdk-s3'
7
+ require 'yaml'
9
8
 
10
9
  class TwigUpdateAmi
11
10
  include Command
12
11
  include PrimaAwsClient
12
+
13
13
  def initialize
14
- output 'Controllo se ci sono aggiornamenti da fare...'
15
- exec "gem update prima-twig && twig update-ami #{ARGV.join ' '}" unless `gem outdated`.lines.grep(/^prima-twig \(.*\)/).empty?
16
- @s3 = Aws::S3::Client.new
17
- @s3_bucket = 'prima-deploy'
18
- @templates_base_url = "https://s3-eu-west-1.amazonaws.com"
14
+ output 'Checking for new gem releases...'
15
+ unless `gem outdated`.lines.grep(/^prima-twig \(.*\)/).empty?
16
+ exec "gem update prima-twig && twig update-ami #{ARGV.join ' '}"
17
+ end
18
+ @state_path = "#{Dir.pwd}/ami_state.yml"
19
19
  end
20
20
 
21
21
  def execute!(args)
22
- update_amis(args[0], args[1], args[2], args[3], args[4])
23
- end
24
-
25
- private
22
+ old_ami = args[0]
23
+ new_ami = args[1]
26
24
 
27
- def update_amis(ami_template, ami_id, ami_name, ami_description, env)
28
- output "updating instance definition #{ami_template}".light_green
29
- Dir.chdir 'ami'
30
- update_instance_name(ami_id, ami_name, ami_description, ami_template)
31
- output 'running packer update (this could take some time)'.light_green
32
- new_ami_id = update_packer(ami_template, env)
33
- # new_ami_id = 'ami-0d8488b68731e8756'
34
- Dir.chdir '..'
35
- stop_if(new_ami_id.to_s.empty?, 'Failed to generate AMI!'.red)
36
- output "new ami id: #{new_ami_id}"
37
-
38
- output 'searching for ami to update...'
39
- ami_mappings = JSON.parse(@s3.get_object(bucket: @s3_bucket, key: "ami/ami-mappings.json")["body"].read())
40
- old_amis = update_ami_mappings(ami_mappings, ami_template, env, new_ami_id)
41
- stop_if(old_amis.empty?, "No ami to update! No #{ami_template} in env #{env}, exiting".yellow)
42
-
43
- output "retrieving stacks that uses old ami ids: #{old_amis}"
44
- exports = list_exports()
45
- stacks = get_stacks_from_exports(exports, old_amis)
46
- stop_if(stacks.empty?, "No stack to update found! This means that ami-mapping file is not in sync, please check manually")
25
+ output "retrieving stacks that uses old ami #{old_ami}".light_green
26
+ stacks = get_stacks_from_exports(list_exports, old_ami)
27
+ stop_if(stacks.empty?, 'No stack to update! Please check manually'.red)
47
28
 
48
29
  stacks.each do |stack|
49
- output "processing stack #{stack}"
30
+ output "processing stack #{stack}".light_green
50
31
  if stack.include?('qa')
51
- output "skipping stack #{stack} because is a qa"
32
+ output "skipping stack #{stack} because is a qa".yellow
52
33
  next
53
34
  else
54
35
  stack_parameters = get_stack_parameters(stack)
55
- stack_parameters = update_stack_parameters(stack_parameters, "AMIID", new_ami_id)
56
- if stack.include?('batch')
57
- if stack.include?('offsite-backups')
58
- stack_template = File.read("./cloudformation/stacks/batch/compute-environment-offsite-backups.yml")
59
- else
60
- stack_template = File.read("./cloudformation/stacks/batch/compute-environment.yml")
61
- end
62
- else
63
- stack_parameters = update_stack_parameters(stack_parameters, "DesiredCapacity", get_desired_capacity(stack).to_s)
64
- stack_template = File.read("./cloudformation/stacks/asg/#{stack.to_s.split("/")[1]}.yml")
36
+ stack_parameters = update_stack_parameters(stack_parameters, 'AMIID', new_ami)
37
+ unless stack.include?('batch')
38
+ stack_parameters = update_stack_parameters(stack_parameters, 'DesiredCapacity', get_desired_capacity(stack).to_s)
65
39
  end
66
- update_stack(stack, stack_template, stack_parameters)
40
+
41
+ update_stack_reuse_template(stack, stack_parameters)
67
42
  end
68
43
  end
69
44
 
70
45
  stacks.each do |stack|
71
- if stack.include?('qa')
72
- next
46
+ next if stack.include?('qa')
47
+
48
+ wait_for_stack_ready(stack, %w[CREATE_FAILED ROLLBACK_IN_PROGRESS ROLLBACK_FAILED DELETE_IN_PROGRESS DELETE_FAILED DELETE_COMPLETE UPDATE_ROLLBACK_FAILED UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS UPDATE_ROLLBACK_COMPLETE ROLLBACK_COMPLETE])
49
+ end
50
+
51
+ output 'Saving new ami in ami_state.yml'.light_green
52
+ File.open(@state_path, 'r') do |f|
53
+ @config = YAML.load(f.read)
54
+ end
55
+
56
+ @config['countries'].each do |country|
57
+ country['amis'].each do |ami|
58
+ ami['id'] = new_ami if ami['id'] == old_ami
73
59
  end
74
- wait_for_stack_ready(stack, ['CREATE_FAILED', 'ROLLBACK_IN_PROGRESS', 'ROLLBACK_FAILED', 'DELETE_IN_PROGRESS', 'DELETE_FAILED', 'DELETE_COMPLETE', 'UPDATE_ROLLBACK_FAILED', 'UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS', 'UPDATE_ROLLBACK_COMPLETE', 'ROLLBACK_COMPLETE'])
75
60
  end
76
61
 
77
- output 'writing new ami mapping'
78
- File.open("ami/ami-mappings.json", 'w+') do |f|
79
- mapping_file = JSON.pretty_generate(ami_mappings)
80
- f.write(mapping_file)
81
- @s3.put_object(bucket: @s3_bucket, key: "ami/ami-mappings.json", body: mapping_file)
62
+ File.open(@state_path, 'w+') do |f|
63
+ yaml = YAML.dump(@config)
64
+ f.write(yaml)
82
65
  end
83
66
 
84
- output 'Update finished! ( ͡° ͜ʖ ͡°)'
67
+ output 'Update finished! ( ͡° ͜ʖ ͡°)'.light_green
85
68
  end
86
69
 
87
- def get_stacks_from_exports(exports, old_amis)
70
+ private
71
+
72
+ def get_stacks_from_exports(exports, old_ami)
88
73
  stacks = []
89
- old_amis.each do |old_ami|
90
- exports.each do |export|
91
- if export.value.eql?(old_ami)
92
- stacks.insert(0,export.exporting_stack_id)
93
- end
94
- end
74
+ exports.each do |export|
75
+ stacks.insert(0, export.exporting_stack_id) if export.value.eql?(old_ami)
95
76
  end
96
77
  stacks
97
78
  end
98
79
 
99
- def update_ami_mappings(mappings, ami_template, env, new_ami_id)
100
- old_values = []
101
- mappings.each do |item|
102
- if item['ami_template'].eql?(ami_template) and item['env'].eql?(env)
103
- old_values.insert(0,item['ami_id'])
104
- item['ami_id'] = new_ami_id
105
- end
106
- end
107
- old_values.uniq
108
- end
109
-
110
80
  def update_stack_parameters(stack_parameters, key, value)
111
81
  stack_parameters.each do |param|
112
- if param.parameter_key == key
113
- param.parameter_value = value
114
- end
82
+ param.parameter_value = value if param.parameter_key == key
115
83
  end
116
84
  stack_parameters
117
85
  end
118
86
 
119
- def update_instance_name(ami_id, ami_name, ami_description, ecs_json_path)
120
- ecs_json = JSON.parse File.read(ecs_json_path)
121
-
122
- ecs_json['builders'][0]['source_ami'] = ami_id
123
- ecs_json['builders'][0]['ami_name'] = ami_name
124
- ecs_json['builders'][0]['ami_description'] = ami_description
125
-
126
- File.open ecs_json_path, 'w' do |f|
127
- f.write(JSON.pretty_generate(ecs_json))
128
- end
129
- end
130
-
131
87
  def get_desired_capacity(stack_name)
132
88
  stack_outputs = get_stack_outputs(stack_name)
133
89
  stack_outputs.each do |out|
134
- if out.export_name.include?('EC2Fleet') or out.export_name.include?('AutoScalingGroup') or out.export_name.include?('NodeGroup')
90
+ if out.export_name.include?('EC2Fleet') || out.export_name.include?('AutoScalingGroup') || out.export_name.include?('NodeGroup')
135
91
  return get_autoscaling_capacity(out.output_value)
136
92
  end
137
93
  end
138
94
  end
139
95
 
140
- def update_packer(json_filename, env)
141
- execute_command "AWS_MAX_ATTEMPTS=90 AWS_POLL_DELAY_SECONDS=60 packer build -var datadog_apikey=`biscuit get -f ../configs/secrets/common.yml common_production_apikey_datadog` -var github_token=`biscuit get -f ../configs/secrets/common.yml common_private_repo_github_token` -var drone_key=\"`biscuit get -f ../configs/secrets/common.yml drone_license_key`\" -var env=#{env} -machine-readable ./#{json_filename} | tee build.log"
142
- `grep 'artifact,0,id' build.log | cut -d, -f6 | cut -d: -f2`.sub(/\n/, '')
143
- end
144
-
145
96
  def help_content
146
97
  <<-HELP
147
98
 
148
99
  twig-update-ami
149
100
  ===========
150
101
 
151
- Updates ami version and applies it to stacks on cloudformation
102
+ Updates AutoScalingGroups/BatchComputeEnvs with a new AMI
152
103
 
153
104
  Synopsis
154
105
  --------
@@ -158,8 +109,8 @@ class TwigUpdateAmi
158
109
  Description
159
110
  -----------
160
111
 
161
- from artemide main folder run
162
- `twig-update-ami ${AMI_TEMPLATE} ${AMI_ID} ${AMI_NAME} ${AMI_DESCRIPTION} ${ENV}`
112
+ from tsunami main folder run
113
+ `aws-vault exec AWS_PROFILE_WITH_ACCESS_TO_COUNTRY_ACCOUNT -- twig-update-ami ${OLD_AMI} ${NEW_AMI}`
163
114
 
164
115
  Subcommand for Twig: <http://rondevera.github.io/twig/>
165
116
  Author: Eugenio Laghi <https://github.com/eugeniolaghi>
@@ -167,13 +118,6 @@ class TwigUpdateAmi
167
118
  HELP
168
119
  end
169
120
 
170
- class ::Hash
171
- def deep_merge(second)
172
- merger = proc { |key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : Array === v1 && Array === v2 ? v1 | v2 : [:undefined, nil, :nil].include?(v2) ? v1 : v2 }
173
- self.merge(second.to_h, &merger)
174
- end
175
- end
176
-
177
121
  args = ARGV.dup
178
122
 
179
123
  if args.include?('--help')
@@ -64,10 +64,10 @@ module Command
64
64
 
65
65
  # executes command and returns properly colored output
66
66
  def execute_command(cmd)
67
- output "Eseguo #{cmd}".yellow
67
+ output "Executing #{cmd}".yellow
68
68
  res = `#{cmd}`
69
69
  color = $CHILD_STATUS.exitstatus.zero? ? 'green' : 'red'
70
70
  output res.send color
71
- stop_if (color == 'red'), "Errore durante la build dell'artifact".red
71
+ stop_if (color == 'red'), 'Error'.red
72
72
  end
73
73
  end
@@ -7,7 +7,6 @@ require 'aws-sdk-ecs'
7
7
  require 'aws-sdk-elasticloadbalancingv2'
8
8
  require 'aws-sdk-s3'
9
9
  require 'colorize'
10
- #
11
10
  module PrimaAwsClient
12
11
  def s3_client
13
12
  @s3 ||= Aws::S3::Client.new
@@ -48,6 +47,7 @@ module PrimaAwsClient
48
47
  end
49
48
  stacks += resp.stacks
50
49
  break unless resp.next_token
50
+
51
51
  next_token = resp.next_token
52
52
  end
53
53
  puts '.'.yellow; STDOUT.flush
@@ -70,6 +70,7 @@ module PrimaAwsClient
70
70
  end
71
71
  stacks += resp.stacks
72
72
  break unless resp.next_token
73
+
73
74
  next_token = resp.next_token
74
75
  end
75
76
  puts '.'.yellow; STDOUT.flush
@@ -92,6 +93,7 @@ module PrimaAwsClient
92
93
  end
93
94
  exports += resp.exports
94
95
  break unless resp.next_token
96
+
95
97
  next_token = resp.next_token
96
98
  end
97
99
  puts '.'.yellow; STDOUT.flush
@@ -108,9 +110,7 @@ module PrimaAwsClient
108
110
  on_failure: 'ROLLBACK'
109
111
  }
110
112
 
111
- if role != nil then
112
- cf_args.merge!(role_arn: role)
113
- end
113
+ cf_args.merge!(role_arn: role) unless role.nil?
114
114
 
115
115
  begin
116
116
  cf_client.create_stack(cf_args)
@@ -119,7 +119,7 @@ module PrimaAwsClient
119
119
  sleep 15
120
120
  create_stack(stack_name, stack_body, parameters = [], tags = [])
121
121
  else
122
- output "La creazione dello stack #{stack_name} è stata avviata".green
122
+ output "CloudFormation stack #{stack_name} creation started".green
123
123
  end
124
124
  end
125
125
 
@@ -132,9 +132,7 @@ module PrimaAwsClient
132
132
  capabilities: ['CAPABILITY_IAM']
133
133
  }
134
134
 
135
- if role != nil then
136
- cf_args.merge!(role_arn: role)
137
- end
135
+ cf_args.merge!(role_arn: role) unless role.nil?
138
136
 
139
137
  begin
140
138
  cf_client.update_stack(cf_args)
@@ -145,7 +143,7 @@ module PrimaAwsClient
145
143
  rescue Aws::CloudFormation::Errors::ValidationError => e
146
144
  raise e
147
145
  else
148
- output "L'update dello stack #{stack_name} è stato avviato".green
146
+ output "CloudFormation stack #{stack_name} update started".green
149
147
  end
150
148
  end
151
149
 
@@ -158,9 +156,7 @@ module PrimaAwsClient
158
156
  capabilities: ['CAPABILITY_IAM']
159
157
  }
160
158
 
161
- if role != nil then
162
- cf_args.merge!(role_arn: role)
163
- end
159
+ cf_args.merge!(role_arn: role) unless role.nil?
164
160
 
165
161
  begin
166
162
  cf_client.update_stack(cf_args)
@@ -171,64 +167,87 @@ module PrimaAwsClient
171
167
  rescue Aws::CloudFormation::Errors::ValidationError => e
172
168
  raise e
173
169
  else
174
- output "L'update dello stack #{stack_name} è stato avviato".green
170
+ output "CloudFormation stack #{stack_name} update started".green
175
171
  end
176
172
  end
177
173
 
178
- def stack_exists?(stack_name)
174
+ def update_stack_reuse_template(stack_name, parameters = [], tags = [], role = nil)
175
+ cf_args = {
176
+ stack_name: stack_name,
177
+ use_previous_template: true,
178
+ parameters: parameters,
179
+ tags: tags,
180
+ capabilities: ['CAPABILITY_IAM']
181
+ }
182
+
183
+ cf_args.merge!(role_arn: role) unless role.nil?
184
+
179
185
  begin
180
- cf_client.describe_stacks(stack_name: stack_name)
186
+ cf_client.update_stack(cf_args)
181
187
  rescue Aws::CloudFormation::Errors::Throttling => e
182
188
  output 'Throttling, retrying in 15 seconds'.red
183
189
  sleep 15
184
- stack_exists?(stack_name)
190
+ update_stack(stack_name, template_body, parameters = [], tags = [])
185
191
  rescue Aws::CloudFormation::Errors::ValidationError => e
186
- return false if e.message.include? 'does not exist'
187
192
  raise e
188
193
  else
189
- true
194
+ output "CloudFormation stack #{stack_name} update started".green
190
195
  end
191
196
  end
192
197
 
198
+ def stack_exists?(stack_name)
199
+ cf_client.describe_stacks(stack_name: stack_name)
200
+ rescue Aws::CloudFormation::Errors::Throttling => e
201
+ output 'Throttling, retrying in 15 seconds'.red
202
+ sleep 15
203
+ stack_exists?(stack_name)
204
+ rescue Aws::CloudFormation::Errors::ValidationError => e
205
+ return false if e.message.include? 'does not exist'
206
+
207
+ raise e
208
+ else
209
+ true
210
+ end
211
+
193
212
  def delete_stack(stack_name)
194
- begin
195
- cf_client.delete_stack(stack_name: stack_name)
196
- rescue Aws::CloudFormation::Errors::Throttling => e
197
- output 'Throttling, retrying in 15 seconds'.red
198
- sleep 15
199
- delete_stack(stack_name)
200
- else
201
- output "Stack #{stack_name} spenta con successo\n".green
202
- end
213
+ cf_client.delete_stack(stack_name: stack_name)
214
+ rescue Aws::CloudFormation::Errors::Throttling => e
215
+ output 'Throttling, retrying in 15 seconds'.red
216
+ sleep 15
217
+ delete_stack(stack_name)
218
+ else
219
+ output "Stack #{stack_name} shutdown succesfully\n".green
203
220
  end
204
221
 
205
- def wait_for_stack_ready(stack_name, failed_statuses = ['CREATE_FAILED', 'ROLLBACK_IN_PROGRESS', 'ROLLBACK_FAILED', 'DELETE_IN_PROGRESS', 'DELETE_FAILED', 'DELETE_COMPLETE', 'UPDATE_ROLLBACK_FAILED', 'UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS'])
222
+ def wait_for_stack_ready(stack_name, failed_statuses = %w[CREATE_FAILED ROLLBACK_IN_PROGRESS ROLLBACK_FAILED DELETE_IN_PROGRESS DELETE_FAILED DELETE_COMPLETE UPDATE_ROLLBACK_FAILED UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS])
206
223
  ready = false
207
224
  sleep_seconds = 13
208
- output "Attendo che lo stack #{stack_name} finisca di essere inizializzato...\n".yellow
209
- while !ready
225
+ output "Waiting for stack #{stack_name}...\n".yellow
226
+ until ready
210
227
  ready = true if stack_ready?(stack_name, failed_statuses)
211
228
  seconds_elapsed = 0
212
229
  loop do
213
230
  break if seconds_elapsed >= sleep_seconds
231
+
214
232
  print '.'.yellow; STDOUT.flush
215
233
  sleep 1
216
234
  seconds_elapsed += 1
217
235
  end
218
236
  end
219
- output "\nStack #{stack_name} pronto!\n".green
237
+ output "\nStack #{stack_name} ready!\n".green
220
238
  end
221
239
 
222
240
  def wait_for_stack_removal(stack_name)
223
241
  ready = false
224
242
  sleep_seconds = 13
225
243
  sleep 10
226
- output "Attendo che lo stack #{stack_name} finisca di essere cancellato...\n".yellow
227
- while !ready
244
+ output "Waiting for stack #{stack_name}...\n".yellow
245
+ until ready
228
246
  ready = true if stack_deleted?(stack_name)
229
247
  seconds_elapsed = 0
230
248
  loop do
231
249
  break if seconds_elapsed >= sleep_seconds
250
+
232
251
  print '.'.yellow; STDOUT.flush
233
252
  sleep 1
234
253
  seconds_elapsed += 1
@@ -238,55 +257,46 @@ module PrimaAwsClient
238
257
  end
239
258
 
240
259
  def get_stack_tags(name)
241
- begin
242
- resp = cf_client.describe_stacks(stack_name: name)
243
- rescue Aws::CloudFormation::Errors::Throttling => e
244
- output 'Throttling, retrying in 15 seconds'.red
245
- sleep 15
246
- get_stack_tags(name)
247
- else
248
- resp.stacks[0].tags
249
- end
260
+ resp = cf_client.describe_stacks(stack_name: name)
261
+ rescue Aws::CloudFormation::Errors::Throttling => e
262
+ output 'Throttling, retrying in 15 seconds'.red
263
+ sleep 15
264
+ get_stack_tags(name)
265
+ else
266
+ resp.stacks[0].tags
250
267
  end
251
268
 
252
269
  def get_stack_parameters(name)
253
- begin
254
- resp = cf_client.describe_stacks(stack_name: name)
255
- rescue Aws::CloudFormation::Errors::Throttling => e
256
- output 'Throttling, retrying in 15 seconds'.red
257
- sleep 15
258
- get_stack_parameters(name)
259
- else
260
- resp.stacks[0].parameters
261
- end
270
+ resp = cf_client.describe_stacks(stack_name: name)
271
+ rescue Aws::CloudFormation::Errors::Throttling => e
272
+ output 'Throttling, retrying in 15 seconds'.red
273
+ sleep 15
274
+ get_stack_parameters(name)
275
+ else
276
+ resp.stacks[0].parameters
262
277
  end
263
278
 
264
279
  def get_stack_outputs(name)
265
- begin
266
- resp = cf_client.describe_stacks(stack_name: name)
267
- rescue Aws::CloudFormation::Errors::Throttling => e
268
- output 'Throttling, retrying in 15 seconds'.red
269
- sleep 15
270
- get_stack_outputs(name)
271
- else
272
- resp.stacks[0].outputs
273
- end
280
+ resp = cf_client.describe_stacks(stack_name: name)
281
+ rescue Aws::CloudFormation::Errors::Throttling => e
282
+ output 'Throttling, retrying in 15 seconds'.red
283
+ sleep 15
284
+ get_stack_outputs(name)
285
+ else
286
+ resp.stacks[0].outputs
274
287
  end
275
288
 
276
289
  def get_stack_template(name)
277
- begin
278
- resp = cf_client.get_template(stack_name: name)
279
- rescue Aws::CloudFormation::Errors::Throttling => e
280
- output 'Throttling, retrying in 15 seconds'.red
281
- sleep 15
282
- get_stack_template(name)
283
- else
284
- resp.template_body
285
- end
286
-
290
+ resp = cf_client.get_template(stack_name: name)
291
+ rescue Aws::CloudFormation::Errors::Throttling => e
292
+ output 'Throttling, retrying in 15 seconds'.red
293
+ sleep 15
294
+ get_stack_template(name)
295
+ else
296
+ resp.template_body
287
297
  end
288
298
 
289
- def stack_ready?(stack_name, failed_statuses = ['CREATE_FAILED', 'ROLLBACK_IN_PROGRESS', 'ROLLBACK_FAILED', 'DELETE_IN_PROGRESS', 'DELETE_FAILED', 'DELETE_COMPLETE', 'UPDATE_ROLLBACK_FAILED', 'UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS'])
299
+ def stack_ready?(stack_name, failed_statuses = %w[CREATE_FAILED ROLLBACK_IN_PROGRESS ROLLBACK_FAILED DELETE_IN_PROGRESS DELETE_FAILED DELETE_COMPLETE UPDATE_ROLLBACK_FAILED UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS])
290
300
  begin
291
301
  resp = cf_client.describe_stacks(
292
302
  stack_name: stack_name
@@ -297,10 +307,11 @@ module PrimaAwsClient
297
307
  return false
298
308
  end
299
309
  raise "The stack #{stack_name} errored out" if failed_statuses.include? stack_status
300
- ['CREATE_COMPLETE', 'UPDATE_COMPLETE', 'UPDATE_ROLLBACK_COMPLETE', 'ROLLBACK_COMPLETE'].include? stack_status
310
+
311
+ %w[CREATE_COMPLETE UPDATE_COMPLETE UPDATE_ROLLBACK_COMPLETE ROLLBACK_COMPLETE].include? stack_status
301
312
  end
302
313
 
303
- def stack_deleted?(stack_name, failed_statuses = ['ROLLBACK_IN_PROGRESS', 'ROLLBACK_FAILED', 'DELETE_FAILED', 'UPDATE_ROLLBACK_FAILED', 'UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS'])
314
+ def stack_deleted?(stack_name, failed_statuses = %w[ROLLBACK_IN_PROGRESS ROLLBACK_FAILED DELETE_FAILED UPDATE_ROLLBACK_FAILED UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS])
304
315
  begin
305
316
  resp = cf_client.describe_stacks(
306
317
  stack_name: stack_name
@@ -314,6 +325,7 @@ module PrimaAwsClient
314
325
  return true
315
326
  end
316
327
  raise "The stack #{stack_name} errored out" if failed_statuses.include? stack_status
328
+
317
329
  ['DELETE_COMPLETE'].include? stack_status
318
330
  end
319
331
 
@@ -326,38 +338,39 @@ module PrimaAwsClient
326
338
  !resp.contents.empty?
327
339
  end
328
340
 
329
- def upload_artifact(source_path, destination_path, bucket_name_override=nil)
330
- output "Upload dell'artifact in corso (#{(File.size(source_path).to_f / 2**20).round(2)} MiB)\n".yellow
341
+ def upload_artifact(source_path, destination_path, bucket_name_override = nil)
342
+ output "Uploading artifact (#{(File.size(source_path).to_f / 2**20).round(2)} MiB)\n".yellow
331
343
  s3 = Aws::S3::Resource.new
332
- s3_bucket = if !bucket_name_override.nil? then bucket_name_override else @s3_bucket end
344
+ s3_bucket = !bucket_name_override.nil? ? bucket_name_override : @s3_bucket
333
345
  puts s3_bucket
334
346
  obj = s3.bucket(s3_bucket).object(destination_path)
335
347
  obj.upload_file(source_path)
336
348
 
337
- output "#{s3_bucket}/#{destination_path} uploadato con successo!\n".green
349
+ output "#{s3_bucket}/#{destination_path} upload success!\n".green
338
350
  end
339
351
 
340
352
  def wait_for_artifact(bucket, path)
341
353
  ready = artifact_exists?(bucket, path)
342
354
  sleep_seconds = 13
343
- output "Attendo che sia pronto l'artefatto #{path}...\n".yellow
355
+ output "Wating that artifact #{path} becomes ready...\n".yellow
344
356
  retries = 0
345
- while !ready
357
+ until ready
346
358
  ready = true if artifact_exists?(bucket, path)
347
359
  seconds_elapsed = 0
348
360
  loop do
349
361
  break if seconds_elapsed >= sleep_seconds
362
+
350
363
  print '.'.yellow; STDOUT.flush
351
364
  sleep 1
352
365
  seconds_elapsed += 1
353
366
  end
354
367
  retries += 1
355
368
  if retries > 150
356
- output "\n Timeout raggiunto aspettando #{path}\n".red
369
+ output "\n Artifact #{path} timed out\n".red
357
370
  exit
358
371
  end
359
372
  end
360
- output "\nArtefatto #{path} creato!\n".green
373
+ output "\nArtifact #{path} created!\n".green
361
374
  end
362
375
 
363
376
  def list_import_stacks(export_name)
@@ -365,7 +378,7 @@ module PrimaAwsClient
365
378
  next_token = ''
366
379
  loop do
367
380
  print '.'.yellow; STDOUT.flush
368
- options = next_token != '' ? { export_name: export_name, next_token: next_token } : {export_name: export_name}
381
+ options = next_token != '' ? { export_name: export_name, next_token: next_token } : { export_name: export_name }
369
382
  begin
370
383
  resp = cf_client.list_imports(options)
371
384
  rescue Aws::CloudFormation::Errors::Throttling => e
@@ -375,94 +388,81 @@ module PrimaAwsClient
375
388
  end
376
389
  stacks += resp.imports
377
390
  break unless resp.next_token
391
+
378
392
  next_token = resp.next_token
379
393
  end
380
394
  stacks
381
395
  end
382
396
 
383
397
  def describe_stack_resource(cluster_stack_name, logical_resource_id)
384
- begin
385
- resp = cf_client.describe_stack_resource({stack_name: cluster_stack_name, logical_resource_id: logical_resource_id})
386
- rescue Aws::CloudFormation::Errors::Throttling => e
387
- output 'Throttling, retrying in 15 seconds'.red
388
- sleep 15
389
- resp = describe_stack_resource(cluster_stack_name, logical_resource_id)
390
- end
398
+ resp = cf_client.describe_stack_resource({ stack_name: cluster_stack_name, logical_resource_id: logical_resource_id })
399
+ rescue Aws::CloudFormation::Errors::Throttling => e
400
+ output 'Throttling, retrying in 15 seconds'.red
401
+ sleep 15
402
+ resp = describe_stack_resource(cluster_stack_name, logical_resource_id)
391
403
  end
392
404
 
393
405
  def describe_instances(instance_ids)
394
- begin
395
- resp = ec2_client.describe_instances({instance_ids: instance_ids})
396
- rescue Aws::CloudFormation::Errors::Throttling => e
397
- output 'Throttling, retrying in 15 seconds'.red
398
- sleep 15
399
- resp = describe_instances(instance_ids)
400
- end
406
+ resp = ec2_client.describe_instances({ instance_ids: instance_ids })
407
+ rescue Aws::CloudFormation::Errors::Throttling => e
408
+ output 'Throttling, retrying in 15 seconds'.red
409
+ sleep 15
410
+ resp = describe_instances(instance_ids)
401
411
  end
402
412
 
403
413
  def describe_auto_scaling_groups(auto_scaling_group_names, max_records)
404
- begin
405
- resp = asg_client.describe_auto_scaling_groups({
406
- auto_scaling_group_names: auto_scaling_group_names,
407
- max_records: max_records
408
- })
409
- rescue Aws::CloudFormation::Errors::Throttling => e
410
- output 'Throttling, retrying in 15 seconds'.red
411
- sleep 15
412
- resp = describe_auto_scaling_groups(auto_scaling_group_names, max_records)
413
- end
414
+ resp = asg_client.describe_auto_scaling_groups({
415
+ auto_scaling_group_names: auto_scaling_group_names,
416
+ max_records: max_records
417
+ })
418
+ rescue Aws::CloudFormation::Errors::Throttling => e
419
+ output 'Throttling, retrying in 15 seconds'.red
420
+ sleep 15
421
+ resp = describe_auto_scaling_groups(auto_scaling_group_names, max_records)
414
422
  end
415
423
 
416
424
  def describe_load_balancers(load_balancer_arns)
417
- begin
418
- resp = alb_client.describe_load_balancers({load_balancer_arns: load_balancer_arns})
419
- rescue Aws::ElasticLoadBalancingV2::Errors::Throttling => e
420
- output 'Throttling, retrying in 15 seconds'.red
421
- sleep 15
422
- resp = describe_load_balancers(load_balancer_arns)
423
- end
425
+ resp = alb_client.describe_load_balancers({ load_balancer_arns: load_balancer_arns })
426
+ rescue Aws::ElasticLoadBalancingV2::Errors::Throttling => e
427
+ output 'Throttling, retrying in 15 seconds'.red
428
+ sleep 15
429
+ resp = describe_load_balancers(load_balancer_arns)
424
430
  end
425
431
 
426
432
  def update_ecs_service(cluster, service, deployment_configuration)
427
- begin
428
- resp = ecs_client.update_service(
429
- cluster: cluster,
430
- service: service,
431
- deployment_configuration: deployment_configuration
432
- )
433
- rescue Aws::CloudFormation::Errors::Throttling => e
434
- output 'Throttling, retrying in 15 seconds'.red
435
- sleep 15
436
- resp = update_ecs_service(cluster, service, deployment_configuration)
437
- end
433
+ resp = ecs_client.update_service(
434
+ cluster: cluster,
435
+ service: service,
436
+ deployment_configuration: deployment_configuration
437
+ )
438
+ rescue Aws::CloudFormation::Errors::Throttling => e
439
+ output 'Throttling, retrying in 15 seconds'.red
440
+ sleep 15
441
+ resp = update_ecs_service(cluster, service, deployment_configuration)
438
442
  end
439
443
 
440
444
  def describe_ecs_tasks(cluster, tasks)
441
- begin
442
- resp = ecs_client.describe_tasks({
443
- cluster: cluster,
444
- tasks: tasks
445
- })
446
- rescue Aws::CloudFormation::Errors::Throttling => e
447
- output 'Throttling, retrying in 15 seconds'.red
448
- sleep 15
449
- resp = describe_ecs_tasks(cluster, tasks)
450
- end
445
+ resp = ecs_client.describe_tasks({
446
+ cluster: cluster,
447
+ tasks: tasks
448
+ })
449
+ rescue Aws::CloudFormation::Errors::Throttling => e
450
+ output 'Throttling, retrying in 15 seconds'.red
451
+ sleep 15
452
+ resp = describe_ecs_tasks(cluster, tasks)
451
453
  end
452
454
 
453
455
  def run_ecs_task(cluster, task_definition, overrides, count)
454
- begin
455
- resp = ecs_client.run_task({
456
- cluster: cluster,
457
- task_definition: task_definition,
458
- overrides: overrides,
459
- count: count
460
- })
461
- rescue Aws::CloudFormation::Errors::Throttling => e
462
- output 'Throttling, retrying in 15 seconds'.red
463
- sleep 15
464
- resp = run_ecs_task(cluster, task_definition, overrides, count)
465
- end
456
+ resp = ecs_client.run_task({
457
+ cluster: cluster,
458
+ task_definition: task_definition,
459
+ overrides: overrides,
460
+ count: count
461
+ })
462
+ rescue Aws::CloudFormation::Errors::Throttling => e
463
+ output 'Throttling, retrying in 15 seconds'.red
464
+ sleep 15
465
+ resp = run_ecs_task(cluster, task_definition, overrides, count)
466
466
  end
467
467
 
468
468
  def get_autoscaling_capacity(asg_name)
@@ -8,8 +8,8 @@ require 'aws-sdk-core'
8
8
  require 'rubyflare'
9
9
 
10
10
  class Prima
11
- CONFIG_KEYS=['github', 'cloudflare_email', 'cloudflare_apikey', 'aws_username', 'aws_password', 'prima_apikey']
12
- attr_reader :gh, :twig, :config, :rugged, :aws
11
+ CONFIG_KEYS=['github', 'cloudflare_email', 'cloudflare_apikey']
12
+ attr_reader :gh, :twig, :config, :rugged
13
13
 
14
14
  def initialize
15
15
  @twig = Twig.new(:read_options => true, :max_days_old => 30)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: prima-twig
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.3
4
+ version: 1.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matteo Giachino
@@ -14,7 +14,7 @@ authors:
14
14
  autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
- date: 2020-08-04 00:00:00.000000000 Z
17
+ date: 2020-11-23 00:00:00.000000000 Z
18
18
  dependencies:
19
19
  - !ruby/object:Gem::Dependency
20
20
  name: aws-sdk-autoscaling
@@ -73,21 +73,21 @@ dependencies:
73
73
  - !ruby/object:Gem::Version
74
74
  version: '1'
75
75
  - !ruby/object:Gem::Dependency
76
- name: aws-sdk-ec2
76
+ name: aws-sdk-core
77
77
  requirement: !ruby/object:Gem::Requirement
78
78
  requirements:
79
79
  - - "~>"
80
80
  - !ruby/object:Gem::Version
81
- version: '1'
81
+ version: '3'
82
82
  type: :runtime
83
83
  prerelease: false
84
84
  version_requirements: !ruby/object:Gem::Requirement
85
85
  requirements:
86
86
  - - "~>"
87
87
  - !ruby/object:Gem::Version
88
- version: '1'
88
+ version: '3'
89
89
  - !ruby/object:Gem::Dependency
90
- name: aws-sdk-ecs
90
+ name: aws-sdk-ec2
91
91
  requirement: !ruby/object:Gem::Requirement
92
92
  requirements:
93
93
  - - "~>"
@@ -101,7 +101,7 @@ dependencies:
101
101
  - !ruby/object:Gem::Version
102
102
  version: '1'
103
103
  - !ruby/object:Gem::Dependency
104
- name: aws-sdk-elasticloadbalancingv2
104
+ name: aws-sdk-ecs
105
105
  requirement: !ruby/object:Gem::Requirement
106
106
  requirements:
107
107
  - - "~>"
@@ -115,7 +115,7 @@ dependencies:
115
115
  - !ruby/object:Gem::Version
116
116
  version: '1'
117
117
  - !ruby/object:Gem::Dependency
118
- name: aws-sdk-s3
118
+ name: aws-sdk-elasticloadbalancingv2
119
119
  requirement: !ruby/object:Gem::Requirement
120
120
  requirements:
121
121
  - - "~>"
@@ -129,19 +129,19 @@ dependencies:
129
129
  - !ruby/object:Gem::Version
130
130
  version: '1'
131
131
  - !ruby/object:Gem::Dependency
132
- name: aws-sdk-core
132
+ name: aws-sdk-s3
133
133
  requirement: !ruby/object:Gem::Requirement
134
134
  requirements:
135
135
  - - "~>"
136
136
  - !ruby/object:Gem::Version
137
- version: '3'
137
+ version: '1'
138
138
  type: :runtime
139
139
  prerelease: false
140
140
  version_requirements: !ruby/object:Gem::Requirement
141
141
  requirements:
142
142
  - - "~>"
143
143
  - !ruby/object:Gem::Version
144
- version: '3'
144
+ version: '1'
145
145
  - !ruby/object:Gem::Dependency
146
146
  name: colorize
147
147
  requirement: !ruby/object:Gem::Requirement
@@ -286,11 +286,13 @@ description: Our tools to manage git and github
286
286
  email: matteo.giachino@prima.it
287
287
  executables:
288
288
  - twig-feature
289
+ - twig-packer-builder
289
290
  - twig-update-ami
290
291
  extensions: []
291
292
  extra_rdoc_files: []
292
293
  files:
293
294
  - bin/twig-feature
295
+ - bin/twig-packer-builder
294
296
  - bin/twig-update-ami
295
297
  - lib/command.rb
296
298
  - lib/prima_aws_client.rb
@@ -314,7 +316,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
314
316
  - !ruby/object:Gem::Version
315
317
  version: '0'
316
318
  requirements: []
317
- rubygems_version: 3.0.1
319
+ rubygems_version: 3.0.3
318
320
  signing_key:
319
321
  specification_version: 4
320
322
  summary: The Prima twig toolbelt