prima-twig 1.2.2 → 1.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 375cff1dcb6c293a35af2cbed16c3d2868c8e02df37fc6dd9daaa3cc86b9bf9b
4
- data.tar.gz: e7fd3d93fc6a856eb504290ba8c1498121b0c900ba35be697033a3fcde833aae
3
+ metadata.gz: dca7d3d6359bd512ce34021d35d023a917507ae1004de5f758abe3f70f6f1c10
4
+ data.tar.gz: 14221958e4695b6ff58ac68a3c332f9b735ad2ca99093f72eaad8d1ffe4989a3
5
5
  SHA512:
6
- metadata.gz: 06a6dd7bf5686f6bc466728dfd0916987e9b0c537133ea521d6faaeae57e5409208785428f03e6a34a7e6654cb93be7a648c91960f014d011293025e5682793b
7
- data.tar.gz: '009485acbc7e40d0fc4d1a0c03c9f730ee5f0704ea15b48f228f926a1af82d5b772021d706c54b29424e509cd52904c6457e9b3cdfe670764760135cc5eb4194'
6
+ metadata.gz: e2d5a682591fee449f6e62e2c7dc07bb9cb5b9fe6cf3ad265698daf5f484df20b6d77d84ca4edd279191bab807849ee7a395ed734cc4e34a55ad03d9fb1233f8
7
+ data.tar.gz: 754189d1268adc751f5d44fa20422bba0fb712e5024560234049bf417e8d59c62d7a1fd6c02caad8e740e948fd58e448aabec7112e98336637654070d3314f71
@@ -326,7 +326,7 @@ class Release
326
326
  tags.push tag_keep_data
327
327
  end
328
328
 
329
- update_cluster_stack(cluster_stack_name, tags)
329
+ update_cluster_stack(cluster_stack_name, tags, get_stack_parameters(cluster_stack_name))
330
330
 
331
331
  output "Finito!".green
332
332
  end
@@ -581,9 +581,9 @@ class Release
581
581
  resp.load_balancers[0].dns_name
582
582
  end
583
583
 
584
- def update_cluster_stack(stack_name, tags = [])
584
+ def update_cluster_stack(stack_name, tags = [], parameters = [])
585
585
  stack_body = get_stack_template(stack_name)
586
- update_stack(stack_name, stack_body, [], tags)
586
+ update_stack(stack_name, stack_body, parameters, tags)
587
587
  end
588
588
 
589
589
  def choose_branch_to_deploy(project_name, select_master = false)
@@ -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.2
4
+ version: 1.3.1
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-07-21 00:00:00.000000000 Z
17
+ date: 2020-11-18 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