tass 0.2.2 → 1.0.0

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
  SHA1:
3
- metadata.gz: f3f94224d11a7c396b61b38b44d026139f06b038
4
- data.tar.gz: 70597218851be9ffe6d8cd1eccef2db50d144a22
3
+ metadata.gz: d63df49ef7d75eeec0d74aef90721a098a829efa
4
+ data.tar.gz: 23bf79d63f1bb9157c51896c85e05ed28ed20f47
5
5
  SHA512:
6
- metadata.gz: 34905de3f29c57247d272728b3ca0a510703a8129a8148f23d843ce57b6a445fb4dcc37c97026c7631ecaf2f8c067645be3ffa4ec8be2dd6616abc557e35f411
7
- data.tar.gz: 8750964d46b84e5e55b32ae5cc3909b8d0af0e402db82b14d4dda9f410234820183cda03f0754138c392a9f6ef2813ac4e396bf1de75f2602c048c52d976fc0e
6
+ metadata.gz: 921b36ca3ccf7eab2817009c1493357b87f11377b13b92099f7a5af0439c9d29e3aa4fe55f5f189928edee0fcd46eff8253b947af901e4b2bb58a28b5908a96b
7
+ data.tar.gz: 6a1edbb35badfd93bb59c988982581b9bd0cb9be651ebabef6dda8fcb88620b7a14b341e3d66758c240777f0328e5185f6988334c70b6ff9758035e7be14b4ff
data/bin/tass CHANGED
@@ -2,20 +2,31 @@
2
2
 
3
3
  require 'tapjoy/autoscaling_bootstrap'
4
4
 
5
+ def common_args
6
+ opt :filename, 'Specify config file to load', type: :string, required: true
7
+ opt :prompt, 'Enable/disable prompts', default: true
8
+ opt :env, 'Specify which environment config to load', type: :string
9
+ end
10
+
5
11
  def confirm_config(aws_env, misc_config, opts)
6
12
  use_vpc = true if misc_config[:vpc_subnets]
7
- unless Tapjoy::AutoscalingBootstrap::Base.new.confirm_config(**aws_env,
8
- **misc_config, **opts, use_vpc: use_vpc)
13
+ has_elb = true if misc_config.key?(:elb)
14
+ Tapjoy::AutoscalingBootstrap::Base.new.confirm_config(**aws_env,
15
+ **misc_config, **opts, use_vpc: use_vpc, has_elb: has_elb,
16
+ config: misc_config)
17
+ end
9
18
 
10
- abort('Cannot continue if configuration is not correct. Please fix.')
11
- end
19
+ def configure_environment(opts)
20
+ config, aws_env, user_data = Tapjoy::AutoscalingBootstrap::Base.new.configure_environment(opts)
21
+ Aws.config[:region] = config[:aws_region]
22
+ [config, aws_env, user_data]
12
23
  end
13
24
 
14
- SUB_COMMANDS = %w(create update audit)
25
+ SUB_COMMANDS = %w(create update audit scale)
15
26
  Trollop::options do
16
27
  usage '[SUB_COMMAND] [options]'
17
28
  synopsis "\nConfigures autoscaling groups.\nAvailable subcommands are: #{SUB_COMMANDS}"
18
- version "#{File.basename($0)} #{Tapjoy::AutoscalingBootstrap::VERSION} \u00A9 2015 Tapjoy, Inc."
29
+ version "#{File.basename($PROGRAM_NAME)} #{Tapjoy::AutoscalingBootstrap::VERSION} \u00A9 2015 Tapjoy, Inc."
19
30
  stop_on SUB_COMMANDS
20
31
  end
21
32
 
@@ -27,33 +38,43 @@ when 'create'
27
38
  usage 'create [options]'
28
39
  synopsis 'This command creates new autoscaling groups, and overwrites existing ones.'
29
40
 
30
- opt :filename, 'Specify config file to load', type: :string, required: true
31
- opt :config_dir, 'Specify the directory for configuration files', type: :string, short: :none, default: Tapjoy::AutoscalingBootstrap.config_dir
32
- opt :env, 'Specify which environment config to load', type: :string
33
41
  opt :clobber_elb, 'Force ELB creation', default: false, short: :none
34
42
  opt :clobber_as, 'Force AS group creation', default: false, short: :none
35
- opt :prompt, 'Enable/disable prompts', default: true
43
+ common_args
36
44
  end
37
45
 
38
- config, aws_env, user_data = Tapjoy::AutoscalingBootstrap::Base.new.configure_environment(opts[:filename], opts[:env], opts[:config_dir])
39
- Aws.config[:region] = config[:aws_region]
40
- confirm_config(aws_env, config, opts)
46
+ config, aws_env, user_data = configure_environment(opts)
41
47
 
42
48
  Tapjoy::AutoscalingBootstrap::Base.new.check_clobber(opts, config)
49
+ unless confirm_config(aws_env, config, opts)
50
+ abort('Cannot continue if configuration is not correct. Please fix.')
51
+ end
43
52
  Tapjoy::AutoscalingBootstrap::AutoscalingGroup.new.create(opts, config, aws_env, user_data)
53
+
54
+ if config.key?(:elb)
55
+ config[:elb].each do |elb|
56
+ elb.each do |elb_name, elb_config|
57
+ Tapjoy::AutoscalingBootstrap.elb_name = elb_name
58
+ elb_hash = {
59
+ elb_name => config[:default_elb_parameters].merge!(elb[elb_name])
60
+ }
61
+
62
+ Tapjoy::AutoscalingBootstrap::ELB.new(
63
+ elb_hash, config[:clobber_elb], config[:zones],
64
+ config[:security_groups])
65
+ end
66
+ end
67
+ end
68
+
44
69
  when 'update'
45
70
  opts = Trollop.options do
46
71
  # Set help message
47
72
  usage 'update [options]'
48
73
  synopsis 'This command creates new launch configurations based on existing autoscaling groups using local instance configuration files as overrides.'
49
- opt :filename, 'Specify config file to load', type: :string, required: true
50
- opt :config_dir, 'Specify the directory for configuration files', type: :string, short: :none, default: Tapjoy::AutoscalingBootstrap.config_dir
51
- opt :env, 'Specify which environment config to load', type: :string
52
- opt :prompt, 'Enable/disable prompts', default: true
74
+ common_args
53
75
  end
54
76
 
55
- config, aws_env, user_data = Tapjoy::AutoscalingBootstrap::Base.new.configure_environment(opts[:filename], opts[:env], opts[:config_dir])
56
- Aws.config[:region] = config[:aws_region]
77
+ config, aws_env, user_data = configure_environment(opts)
57
78
  confirm_config(aws_env, config, opts)
58
79
 
59
80
  Tapjoy::AutoscalingBootstrap::LaunchConfiguration.new(config, aws_env, user_data)
@@ -61,17 +82,23 @@ when 'audit'
61
82
  opts = Trollop.options do
62
83
  usage 'audit'
63
84
  synopsis 'This command compares local configuration files for a given cluster to the existing launch configuration and autoscaling group running in AWS.'
64
- opt :filename, 'Specify config file to load', type: :string, required: true
65
- opt :config_dir, 'Specify the directory for configuration files', type: :string, short: :none, default: Tapjoy::AutoscalingBootstrap.config_dir
66
- opt :env, 'Specify which environment config to load', required: true, type: :string
67
- opt :prompt, 'Enable/disable prompts', default: true
85
+ common_args
68
86
  end
69
87
 
70
- config, aws_env, user_data = Tapjoy::AutoscalingBootstrap::Base.new.configure_environment(opts[:filename], opts[:env], opts[:config_dir])
71
- Aws.config[:region] = config[:aws_region]
88
+ config, aws_env, user_data = configure_environment(opts)
72
89
 
73
- config.merge!(aws_env.merge({user_data: Base64.encode64("#{user_data}")}))
90
+ config.merge!(aws_env.merge(user_data: Base64.encode64("#{user_data}")))
74
91
  Tapjoy::AutoscalingBootstrap::Audit.new(config)
92
+ when 'scale'
93
+ opts = Trollop.options do
94
+ usage 'scale [options]'
95
+ synopsis 'This command is used to scale up/down auto scaling groups'
96
+ common_args
97
+ opt :instance_ids, 'Instance IDs to scale down', type: :strings
98
+ end
99
+
100
+ config, aws_env, user_data = configure_environment(opts)
101
+ Tapjoy::AutoscalingBootstrap::Autoscaling::Group.new.scale(config)
75
102
  else
76
103
  Trollop.educate
77
104
  end
@@ -30,6 +30,7 @@ require_relative 'autoscaling_bootstrap/autoscaling_group'
30
30
  require_relative 'autoscaling_bootstrap/launch_configuration'
31
31
  require_relative 'autoscaling_bootstrap/version'
32
32
  require_relative 'autoscaling_bootstrap/audit'
33
+ require_relative 'autoscaling_bootstrap/ec2'
33
34
 
34
35
  module Tapjoy
35
36
  # Module for Autoscaling Bootstrap
@@ -45,24 +46,6 @@ module Tapjoy
45
46
  @elb_name = str
46
47
  end
47
48
 
48
- # If you're using AutoscalingBootstrap to join to a list of existing ELBs, that array
49
- # goes here. This list can include or not include the provided elb_name, the
50
- # array + a custom elb_name will be uniq-ed before being passed to Amazon
51
- def elb_list=(list)
52
- @elb_list = list
53
- end
54
-
55
- def elb_list
56
- @elb_list ||= []
57
- end
58
-
59
- # This is the list of elbs passed to the autoscaling configuration. It will include
60
- # the created elb, as well as the specific list of elbs to join. It will call uniq
61
- # on the list in case you accidentally specify the same elb twice
62
- def elbs_to_join
63
- (elb_list + [Tapjoy::AutoscalingBootstrap.elb_name]).uniq
64
- end
65
-
66
49
  def policy
67
50
  @policy = Tapjoy::AutoscalingBootstrap::Autoscaling::Policy.new
68
51
  end
@@ -83,9 +66,8 @@ module Tapjoy
83
66
  @config_dir ||= ENV['TASS_CONFIG_DIR'] || "#{ENV['HOME']}/.tass"
84
67
  end
85
68
 
86
- def is_valid_env?(config_dir, env)
87
- env_list = self.supported_envs(config_dir)
88
- puts config_dir
69
+ def valid_env?(config_dir, env)
70
+ env_list = supported_envs(config_dir)
89
71
  unless env_list.include?(env)
90
72
  Trollop.die :env, "Currently supported enviroments are #{env_list.join(',')}"
91
73
  end
@@ -93,7 +75,7 @@ module Tapjoy
93
75
 
94
76
  def supported_envs(listing)
95
77
  envs = []
96
- Dir.entries("#{listing}/config/common").each do |file|
78
+ Dir.entries(listing).each do |file|
97
79
  next unless file.end_with?('yaml')
98
80
  next if file.start_with?('defaults')
99
81
  envs << file.chomp!('.yaml')
@@ -111,17 +93,16 @@ module Tapjoy
111
93
  end
112
94
 
113
95
  # Using variables passed in, generate user data file
114
- def generate_user_data(config)
96
+ def generate_user_data(userdata_dir, bootstrap_script, config)
115
97
 
116
98
  ERB.new(
117
- File.new("#{config[:config_dir]}/userdata/#{config[:bootstrap_script]}").read,nil,'-'
99
+ File.new(File.join(userdata_dir, bootstrap_script)).read, nil, '-'
118
100
  ).result(binding)
119
101
  end
120
102
 
121
103
  # Check if we allow clobbering and need to clobber
122
104
  def check_clobber(opts, config)
123
105
  fail Tapjoy::AutoscalingBootstrap::Errors::ClobberRequired if check_as_clobber(**opts, **config)
124
- fail Tapjoy::AutoscalingBootstrap::Errors::ELB::ClobberRequired if check_elb_clobber(**opts, **config)
125
106
  puts "We don't need to clobber"
126
107
  end
127
108
 
@@ -130,41 +111,40 @@ module Tapjoy
130
111
  create_as_group && Tapjoy::AutoscalingBootstrap.group.exists && !clobber_as
131
112
  end
132
113
 
133
- # Check ELB clobber
134
- def check_elb_clobber(create_elb:, clobber_elb:, **unused_values)
135
- elb = Tapjoy::AutoscalingBootstrap::ELB.new
136
- create_elb && elb.exists && !clobber_elb
137
- end
138
-
139
114
  # Get AWS Environment
140
115
  def get_security_groups(config_dir, env, group)
141
116
 
142
117
  # Check environment file
143
- unless File.readable?("#{config_dir}/config/common/#{env}.yaml")
118
+ unless File.readable?("#{config_dir}/#{env}.yaml")
144
119
  fail Tapjoy::AutoscalingBootstrap::Errors::InvalidEnvironment
145
120
  end
146
121
 
147
122
  security_groups = {security_groups: group.split(',')}
148
123
  end
149
124
 
125
+ # Clean list of ELBs
126
+ def elb_list(config)
127
+ config[:elb].map(&:keys).flatten.join(',')
128
+ end
129
+
150
130
  # Confirm config settings before running autoscaling code
151
131
  def confirm_config(keypair:, zones:, security_groups:, instance_type:,
152
132
  image_id:, iam_instance_profile:, prompt:, use_vpc: use_vpc,
153
- vpc_subnets: nil, **unused_values)
154
-
155
- elb_name = Tapjoy::AutoscalingBootstrap.elb_name
133
+ vpc_subnets: nil, has_elb: has_elb, config:, termination_policies:,
134
+ **unused_values)
156
135
 
157
136
  puts ' Preparing to configure the following autoscaling group:'
158
- puts " Launch Config: #{Tapjoy::AutoscalingBootstrap.config_name}"
159
- puts " Auto Scaler: #{Tapjoy::AutoscalingBootstrap.scaler_name}"
160
- puts " ELB: #{elb_name}" unless elb_name.eql? 'NaE'
161
- puts " Key Pair: #{keypair}"
162
- puts " Zones: #{zones.join(',')}"
163
- puts " Groups: #{security_groups.sort.join(',')}"
164
- puts " Instance Type: #{instance_type}"
165
- puts " Image ID: #{image_id}"
166
- puts " IAM Role: #{iam_instance_profile}"
167
- puts " VPC Subnets: #{vpc_subnets}" if use_vpc
137
+ puts " Launch Config: #{Tapjoy::AutoscalingBootstrap.config_name}"
138
+ puts " Auto Scaler: #{Tapjoy::AutoscalingBootstrap.scaler_name}"
139
+ puts " ELB: #{elb_list(config)}" if has_elb
140
+ puts " Key Pair: #{keypair}"
141
+ puts " Zones: #{zones.join(',')}"
142
+ puts " Groups: #{security_groups.sort.join(',')}"
143
+ puts " Instance Type: #{instance_type}"
144
+ puts " Image ID: #{image_id}"
145
+ puts " IAM Role: #{iam_instance_profile}"
146
+ puts " VPC Subnets: #{vpc_subnets}" if use_vpc
147
+ puts " Termination Policies: #{termination_policies.sort.join(',')}"
168
148
 
169
149
  puts "\n\nNOTE! Continuing may have adverse effects if you end up " \
170
150
  "deleting an IN-USE PRODUCTION scaling group. Don't be dumb."
@@ -174,41 +154,41 @@ module Tapjoy
174
154
 
175
155
  # configure environment
176
156
 
177
- def configure_environment(filename, env=nil, config_dir)
178
- if filename.include?(File::SEPARATOR)
179
- facet_file = filename
180
- config_dir = File.expand_path('../../..', facet_file)
181
- else
182
- facet_file = File.join(config_dir, 'config', 'clusters', filename)
183
- end
157
+ def configure_environment(opts)
158
+ filename = opts[:filename]
159
+ facet_file = filename
160
+ config_dir = File.expand_path('../..', facet_file)
161
+ userdata_dir = "#{File.expand_path('../../..', facet_file)}/userdata"
184
162
 
185
- common_path = File.join(config_dir, 'config', 'common')
163
+ common_path = File.join(config_dir, 'common')
186
164
  defaults_hash = self.load_yaml(File.join(common_path, 'defaults.yaml'))
187
165
  facet_hash = self.load_yaml(facet_file)
188
- env ||= facet_hash[:environment]
189
- env ||= defaults_hash[:environment]
190
- Tapjoy::AutoscalingBootstrap.is_valid_env?(config_dir, env)
166
+ env = opts[:env] || facet_hash[:environment] || defaults_hash[:environment]
167
+ Tapjoy::AutoscalingBootstrap.valid_env?(common_path, env)
191
168
  env_hash = self.load_yaml(File.join(common_path, "#{env}.yaml"))
192
169
 
193
170
  new_config = defaults_hash.merge!(env_hash).merge(facet_hash)
194
171
  new_config[:config_dir] = config_dir
195
- aws_env = self.get_security_groups(config_dir, env, new_config[:group])
172
+ new_config[:instance_ids] = opts[:instance_ids] if opts.key?(:instance_ids)
173
+ aws_env = self.get_security_groups(common_path, env, new_config[:group])
174
+ new_config.merge!(aws_env)
196
175
 
176
+ new_config[:autoscale] = false unless new_config[:scaling_type].eql?('dynamic')
177
+ new_config[:tags] << {Name: new_config[:name]}
197
178
  Tapjoy::AutoscalingBootstrap.scaler_name = "#{new_config[:name]}-group"
198
179
  Tapjoy::AutoscalingBootstrap.config_name = "#{new_config[:name]}-config"
199
180
  # If there's no ELB, then Not a ELB
200
- puts new_config[:elb_name]
201
- Tapjoy::AutoscalingBootstrap.elb_name = new_config[:elb_name] || 'NaE'
202
- Tapjoy::AutoscalingBootstrap.create_elb = new_config[:create_elb]
203
- Tapjoy::AutoscalingBootstrap.elb_list = new_config[:elb_list] || []
204
- user_data = self.generate_user_data(new_config)
205
- return new_config, aws_env, user_data
181
+ user_data = self.generate_user_data(userdata_dir,
182
+ new_config[:bootstrap_script], new_config)
183
+
184
+ [new_config, aws_env, user_data]
206
185
  end
207
186
 
208
187
  # Exponential backup
209
188
  def aws_wait(tries)
210
- puts "Sleeping for #{2 ** tries}..."
211
- sleep 2 ** tries
189
+ backoff_sleep = 2 ** tries
190
+ puts "Sleeping for #{backoff_sleep}..."
191
+ sleep backoff_sleep
212
192
  end
213
193
 
214
194
  # Check if security group exists and create it if it does not
@@ -9,11 +9,10 @@ module Tapjoy
9
9
  @client ||= Tapjoy::AutoscalingBootstrap::AWS::Autoscaling.client
10
10
  end
11
11
 
12
- def resize(min_size: 0, max_size: 0, desired_capacity:0)
12
+ def resize(min: 0, max: 0, desired:0)
13
13
  self.client.update_auto_scaling_group(
14
14
  auto_scaling_group_name: Tapjoy::AutoscalingBootstrap.scaler_name,
15
- min_size: min_size, max_size: max_size,
16
- desired_capacity: desired_capacity)
15
+ min_size: min, max_size: max, desired_capacity: desired)
17
16
  end
18
17
 
19
18
  def delete(force_delete: true)
@@ -30,31 +29,36 @@ module Tapjoy
30
29
  )[0][0]
31
30
  end
32
31
 
32
+ def detach
33
+ self.client.detach_instances(
34
+ instance_ids: describe.instances.map(&:instance_id),
35
+ auto_scaling_group_name: Tapjoy::AutoscalingBootstrap.scaler_name,
36
+ should_decrement_desired_capacity: true,
37
+ )
38
+ end
39
+
33
40
  def create(zones:, health_check_type: nil, tags:,
34
- vpc_subnets: nil, create_elb:, **unused_values)
41
+ vpc_subnets: nil, termination_policies: , **unused_values)
35
42
 
36
43
  group_hash = {
37
44
  auto_scaling_group_name: Tapjoy::AutoscalingBootstrap.scaler_name,
38
45
  availability_zones: zones,
39
46
  launch_configuration_name: Tapjoy::AutoscalingBootstrap.config_name,
40
47
  min_size: 0, max_size: 0, desired_capacity: 0,
41
- termination_policies: ['OldestInstance'],
48
+ termination_policies: termination_policies,
42
49
  vpc_zone_identifier: vpc_subnets,
43
50
  tags: Tapjoy::AutoscalingBootstrap::Autoscaling::Group.new.generate_tags(tags)
44
51
  }
45
52
 
46
- # If we've chosen to explicitly create an ELB and assign to this ASG
47
- # OR if we've given it a list of ELBs to join (or both)
48
- if create_elb || !Tapjoy::AutoscalingBootstrap.elb_list.empty?
49
- group_hash.merge!({
50
- load_balancer_names: Tapjoy::AutoscalingBootstrap.elbs_to_join,
51
- health_check_type: health_check_type,
52
- health_check_grace_period: 300,
53
- })
54
- end
55
-
56
53
  self.client.create_auto_scaling_group(**group_hash)
57
54
  end
55
+
56
+ def attach_elb(elb_list)
57
+ self.client.attach_load_balancers({
58
+ auto_scaling_group_name: Tapjoy::AutoscalingBootstrap.scaler_name,
59
+ load_balancer_names: elb_list.split(','),
60
+ })
61
+ end
58
62
  end
59
63
  end
60
64
  end
@@ -1,7 +1,7 @@
1
1
  module Tapjoy
2
2
  module AutoscalingBootstrap
3
3
  module AWS
4
- # This class contains AWS methods for ELB
4
+ # This class contains AWS methods for EC2
5
5
  module EC2
6
6
  class << self
7
7
  def client
@@ -16,6 +16,24 @@ module Tapjoy
16
16
  self.client.create_security_group(group_name: group,
17
17
  description: "Security group for #{Tapjoy::AutoscalingBootstrap.scaler_name}")
18
18
  end
19
+
20
+ def describe_instances_by_tag(config)
21
+ self.client.describe_instances(filters: [
22
+ {name: 'tag:Name', values: [config[:name]]},
23
+ {name: 'instance-state-name', values: %w(running)}
24
+ ])
25
+ end
26
+
27
+ def toggle_termination_protection(instance_id, state)
28
+ client.modify_instance_attribute(
29
+ instance_id: instance_id,
30
+ attribute: 'disableApiTermination',
31
+ value: state)
32
+ end
33
+
34
+ def terminate_instances(instance_ids)
35
+ client.terminate_instances(instance_ids: instance_ids)
36
+ end
19
37
  end
20
38
  end
21
39
  end
@@ -22,7 +22,7 @@ module Tapjoy
22
22
  config[:key_name] = config.delete :keypair
23
23
  config[:launch_configuration_name] = Tapjoy::AutoscalingBootstrap.config_name
24
24
  keys = %w(bootstrap_script chef_server_url clobber clobber_elb
25
- create_as_group config_dir)
25
+ create_as_group)
26
26
  delete_keys(config, keys)
27
27
 
28
28
  config
@@ -61,8 +61,60 @@ module Tapjoy
61
61
  tag_array
62
62
  end
63
63
 
64
+ # Scale auto scaling groups
65
+ def scale(config)
66
+ if config[:scaling_type].eql?('dynamic')
67
+ Tapjoy::AutoscalingBootstrap::AWS::Autoscaling::Group.resize(
68
+ **config[:instance_counts])
69
+ elsif config[:scaling_type].eql?('static')
70
+ scale_static(config)
71
+ else
72
+ abort('Unknown scaling type')
73
+ end
74
+ end
75
+
64
76
  private
65
77
 
78
+ # Logic for scaling static clusters
79
+ def scale_static(config)
80
+ current_count = Tapjoy::AutoscalingBootstrap::EC2.count_static_instances(config)
81
+ count_delta = config[:instance_counts][:desired] - current_count
82
+ if count_delta < 0
83
+ count_delta = count_delta.abs
84
+ puts "Scaling #{count_delta} instances down"
85
+ abort('Instances to terminate must be specified') unless config.key?(:instance_ids)
86
+ unless config[:instance_ids].length.eql?(count_delta)
87
+ fail Tapjoy::AutoscalingBootstrap::Errors::IncorrectNumberIds
88
+ end
89
+ disable_termination_protection(config[:instance_ids])
90
+ Tapjoy::AutoscalingBootstrap::AWS::EC2.terminate_instances(config[:instance_ids])
91
+ elsif count_delta > 0
92
+ puts 'Scaling up...'
93
+ puts count_delta
94
+ Tapjoy::AutoscalingBootstrap::AWS::Autoscaling::Group.resize(
95
+ min: 0, max: count_delta, desired: count_delta)
96
+ wait_for_asg_to_populate(config[:instance_counts][:desired], config)
97
+ enable_termination_protection
98
+ Tapjoy::AutoscalingBootstrap::AWS::Autoscaling::Group.detach
99
+ else
100
+ puts 'No action needed'
101
+ end
102
+ end
103
+
104
+ # Helper method to disable termination protection
105
+ def disable_termination_protection(instance_ids)
106
+ instance_ids.each do |instance|
107
+ Tapjoy::AutoscalingBootstrap::EC2.disable_termination_protection(instance)
108
+ end
109
+ end
110
+ # Helper method to enable termination protection
111
+ def enable_termination_protection
112
+ asg = Tapjoy::AutoscalingBootstrap::AWS::Autoscaling::Group.describe
113
+ asg.instances.map(&:instance_id).each do |instance|
114
+ Tapjoy::AutoscalingBootstrap::EC2.enable_termination_protection(instance)
115
+ end
116
+ end
117
+
66
118
  # Clear out existing autoscaling group
67
119
  def zero_autoscale_group
68
120
  Tapjoy::AutoscalingBootstrap::AWS::Autoscaling::Group.resize
@@ -107,6 +159,17 @@ module Tapjoy
107
159
  Tapjoy::AutoscalingBootstrap::Base.new.aws_wait(tries)
108
160
  end
109
161
  end
162
+
163
+ # Wait for ASG to populate
164
+ def wait_for_asg_to_populate(desired, config)
165
+ current_count = Tapjoy::AutoscalingBootstrap::EC2.count_static_instances(config)
166
+ tries = 0
167
+ until current_count.eql?(desired) do
168
+ tries += 1
169
+ Tapjoy::AutoscalingBootstrap::Base.new.aws_wait(tries)
170
+ current_count = Tapjoy::AutoscalingBootstrap::EC2.count_static_instances(config)
171
+ end
172
+ end
110
173
  end
111
174
  end
112
175
  end
@@ -12,7 +12,7 @@ module Tapjoy
12
12
 
13
13
  # Create autoscaling policy
14
14
  def create(policy, scale)
15
- return unless Tapjoy::AutoscalingBootstrap.group.exists
15
+ fail Tapjoy::AutoscalingBootstrap::Errors::InvalidAutoscalingGroup unless Tapjoy::AutoscalingBootstrap.group.exists
16
16
  Tapjoy::AutoscalingBootstrap::AWS::Autoscaling.put_scaling_policy(
17
17
  policy_name: policy, **scale)
18
18
  end
@@ -3,25 +3,7 @@ module Tapjoy
3
3
  # This class is the central launching point for new autoscaling group creation
4
4
  class AutoscalingGroup
5
5
  # Initialize the class
6
- def create(opts, new_config, aws_env, user_data,
7
-
8
- # ELB Parameters
9
- elb_health_target: "#{new_config[:instance_protocol]}:#{new_config[:instance_port]}/healthz",
10
- elb_protocol: new_config[:instance_protocol],
11
- elb_name: "#{new_config[:name].gsub('_','-')}-discovery"
12
- )
13
-
14
- if new_config[:create_elb]
15
- new_config.merge!({
16
- elb_health_target: elb_health_target,
17
- elb_protocol: elb_protocol,
18
- elb_name: elb_name
19
- })
20
-
21
- Tapjoy::AutoscalingBootstrap::ELB.new.create(new_config, aws_env)
22
- else
23
- puts "\nNo ELB required"
24
- end
6
+ def create(opts, new_config, aws_env, user_data)
25
7
 
26
8
  Tapjoy::AutoscalingBootstrap::ConfigureAutoscalers.new(**new_config,
27
9
  aws_env: aws_env, user_data: user_data, misc_config: new_config)
@@ -0,0 +1,26 @@
1
+ module Tapjoy
2
+ module AutoscalingBootstrap
3
+ # This class contains tass methods for EC2
4
+ module EC2
5
+ class << self
6
+ def count_static_instances(config)
7
+ find_static_instances(config).length
8
+ end
9
+
10
+ def enable_termination_protection(instance_id)
11
+ Tapjoy::AutoscalingBootstrap::AWS::EC2.toggle_termination_protection(instance_id, 'true')
12
+ end
13
+
14
+ def disable_termination_protection(instance_id)
15
+ Tapjoy::AutoscalingBootstrap::AWS::EC2.toggle_termination_protection(instance_id, 'false')
16
+ end
17
+
18
+ private
19
+ def find_static_instances(config)
20
+ response = Tapjoy::AutoscalingBootstrap::AWS::EC2.describe_instances_by_tag(config)
21
+ response.reservations
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -2,16 +2,32 @@ module Tapjoy
2
2
  module AutoscalingBootstrap
3
3
  # This class configures elastic load balancers
4
4
  class ELB
5
- # Initialize the class
6
- def initialize
5
+ def initialize(elb_hash, clobber_elb, zones, security_groups)
6
+ elb_config = build_config(elb_hash, zones, security_groups)
7
+ check_valid_config(elb_config)
8
+
9
+ if exists && clobber_elb
10
+ delete
11
+ create(elb_config)
12
+ elsif exists
13
+ Tapjoy::AutoscalingBootstrap::AWS::Autoscaling::Group.attach_elb(
14
+ Tapjoy::AutoscalingBootstrap.elb_name)
15
+ else
16
+ create(elb_config)
17
+ end
7
18
  end
8
19
 
9
- # Create load balancer
10
- def create(config, aws_env)
20
+ # Build config hash
21
+ def build_config(elb_hash, zones, security_groups)
22
+ elb_config = elb_hash[Tapjoy::AutoscalingBootstrap.elb_name]
23
+ elb_config[:elb_protocol] ||= elb_config[:instance_protocol]
24
+ elb_config[:elb_health_target] ||= "#{elb_config[:instance_protocol]}:#{elb_config[:instance_port]}/healthz"
25
+ elb_config.merge!({zones: zones, groups: security_groups})
26
+ end
11
27
 
12
- check_valid_config(config)
13
- delete if exists
14
- Tapjoy::AutoscalingBootstrap::AWS::ELB.create(**config, **aws_env)
28
+ # Create load balancer
29
+ def create(config)
30
+ Tapjoy::AutoscalingBootstrap::AWS::ELB.create(**config)
15
31
  health_check(config)
16
32
  end
17
33
 
@@ -25,6 +25,15 @@ module Tapjoy
25
25
  abort("ERROR: Specified autoscaling group doesn't exist")
26
26
  end
27
27
  end
28
+
29
+ # Raise if an incorrect number of instance ids have been specified
30
+ class IncorrectNumberIds < ArgumentError
31
+ def initialize
32
+ error = 'Number of instance IDs specified must match the number '\
33
+ 'of instances scaled down'
34
+ abort(error)
35
+ end
36
+ end
28
37
  end
29
38
  end
30
39
  end
@@ -1,9 +1,9 @@
1
1
  module Tapjoy
2
2
  module AutoscalingBootstrap
3
3
  module Version
4
- MAJOR = 0
5
- MINOR = 2
6
- PATCH = 2
4
+ MAJOR = 1
5
+ MINOR = 0
6
+ PATCH = 0
7
7
  end
8
8
 
9
9
  VERSION = [Version::MAJOR, Version::MINOR, Version::PATCH].join('.')
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tass
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ali Tayarani
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-22 00:00:00.000000000 Z
11
+ date: 2015-11-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: trollop
@@ -122,6 +122,20 @@ dependencies:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
124
  version: '2.9'
125
+ - !ruby/object:Gem::Dependency
126
+ name: rspec_junit_formatter
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - '='
130
+ - !ruby/object:Gem::Version
131
+ version: 0.2.2
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - '='
137
+ - !ruby/object:Gem::Version
138
+ version: 0.2.2
125
139
  description: TASS is the suite of tools that the Tapjoy Operations team uses to manage
126
140
  autoscaling groups and launch configurations.
127
141
  email: ali.tayarani@tapjoy.com
@@ -150,6 +164,7 @@ files:
150
164
  - lib/tapjoy/autoscaling_bootstrap/aws.rb
151
165
  - lib/tapjoy/autoscaling_bootstrap/cloudwatch.rb
152
166
  - lib/tapjoy/autoscaling_bootstrap/configure_autoscaler.rb
167
+ - lib/tapjoy/autoscaling_bootstrap/ec2.rb
153
168
  - lib/tapjoy/autoscaling_bootstrap/elb.rb
154
169
  - lib/tapjoy/autoscaling_bootstrap/errors.rb
155
170
  - lib/tapjoy/autoscaling_bootstrap/errors/elb.rb