Class: Cumulus::AutoScaling::GroupConfig

Inherits:
Object
  • Object
show all
Defined in:
lib/autoscaling/models/GroupConfig.rb

Overview

Public: An object representing the configuration for an AutoScaling group.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, json = nil) ⇒ GroupConfig

Public: Constructor

name - the name of the group json - a hash containing the json configuration for the AutoScaling group



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/autoscaling/models/GroupConfig.rb', line 37

def initialize(name, json = nil)
  @name = name
  if !json.nil?
    @cooldown = json["cooldown-seconds"]
    @min = json["size"]["min"]
    @max = json["size"]["max"]
    @desired = json["size"]["desired"]
    @enabled_metrics = json["enabled-metrics"]
    @check_type = json["health-check-type"]
    @check_grace = json["health-check-grace-seconds"]
    @launch = json["launch-configuration"]
    @load_balancers = json["load-balancers"]
    @subnets = json["subnets"]
    @tags = json["tags"]
    @termination = json["termination"]
    @scheduled = Hash[(json["scheduled"] || []).map { |json| [json["name"], ScheduledConfig.new(json)] }]

    # load scaling policies
    static_policies = json["policies"]["static"].map { |file| Loader.static_policy(file) }
    template_policies = json["policies"]["templates"].map do |template|
      Loader.template_policy(template["template"], template["vars"])
    end
    inline_policies = json["policies"]["inlines"].map { |inline| PolicyConfig.new(inline) }
    @policies = static_policies + template_policies + inline_policies
    @policies = Hash[@policies.map { |policy| [policy.name, policy] }]
  else
    @enabled_metrics = []
    @load_balancers = []
    @subnets = []
    @tags = {}
    @termination = []
  end
end

Instance Attribute Details

#check_graceObject (readonly)

Returns the value of attribute check_grace.



17
18
19
# File 'lib/autoscaling/models/GroupConfig.rb', line 17

def check_grace
  @check_grace
end

#check_typeObject (readonly)

Returns the value of attribute check_type.



18
19
20
# File 'lib/autoscaling/models/GroupConfig.rb', line 18

def check_type
  @check_type
end

#cooldownObject (readonly)

Returns the value of attribute cooldown.



19
20
21
# File 'lib/autoscaling/models/GroupConfig.rb', line 19

def cooldown
  @cooldown
end

#desiredObject (readonly)

Returns the value of attribute desired.



20
21
22
# File 'lib/autoscaling/models/GroupConfig.rb', line 20

def desired
  @desired
end

#enabled_metricsObject (readonly)

Returns the value of attribute enabled_metrics.



21
22
23
# File 'lib/autoscaling/models/GroupConfig.rb', line 21

def enabled_metrics
  @enabled_metrics
end

#launchObject (readonly)

Returns the value of attribute launch.



22
23
24
# File 'lib/autoscaling/models/GroupConfig.rb', line 22

def launch
  @launch
end

#load_balancersObject (readonly)

Returns the value of attribute load_balancers.



23
24
25
# File 'lib/autoscaling/models/GroupConfig.rb', line 23

def load_balancers
  @load_balancers
end

#maxObject (readonly)

Returns the value of attribute max.



24
25
26
# File 'lib/autoscaling/models/GroupConfig.rb', line 24

def max
  @max
end

#minObject (readonly)

Returns the value of attribute min.



25
26
27
# File 'lib/autoscaling/models/GroupConfig.rb', line 25

def min
  @min
end

#nameObject (readonly)

Returns the value of attribute name.



26
27
28
# File 'lib/autoscaling/models/GroupConfig.rb', line 26

def name
  @name
end

#policiesObject (readonly)

Returns the value of attribute policies.



27
28
29
# File 'lib/autoscaling/models/GroupConfig.rb', line 27

def policies
  @policies
end

#scheduledObject (readonly)

Returns the value of attribute scheduled.



28
29
30
# File 'lib/autoscaling/models/GroupConfig.rb', line 28

def scheduled
  @scheduled
end

#subnetsObject (readonly)

Returns the value of attribute subnets.



29
30
31
# File 'lib/autoscaling/models/GroupConfig.rb', line 29

def subnets
  @subnets
end

#tagsObject (readonly)

Returns the value of attribute tags.



30
31
32
# File 'lib/autoscaling/models/GroupConfig.rb', line 30

def tags
  @tags
end

#terminationObject (readonly)

Returns the value of attribute termination.



31
32
33
# File 'lib/autoscaling/models/GroupConfig.rb', line 31

def termination
  @termination
end

Instance Method Details

#diff(aws, autoscaling) ⇒ Object

Public: Produce the differences between this local configuration and the configuration in AWS

aws - the aws resource autoscaling - the AWS client needed to get additional AWS resources

Returns an Array of the AutoScalingDiffs that were found



129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
# File 'lib/autoscaling/models/GroupConfig.rb', line 129

def diff(aws, autoscaling)
  diffs = []

  if @cooldown != aws.default_cooldown
    diffs << AutoScalingDiff.new(AutoScalingChange::COOLDOWN, aws, self)
  end
  if @enabled_metrics.deep_sort != aws.enabled_metrics.map { |k| k.metric }.deep_sort
    diffs << AutoScalingDiff.new(AutoScalingChange::METRICS, aws, self)
  end
  if @check_type != aws.health_check_type
    diffs << AutoScalingDiff.new(AutoScalingChange::CHECK_TYPE, aws, self)
  end
  if @check_grace != aws.health_check_grace_period
    diffs << AutoScalingDiff.new(AutoScalingChange::CHECK_GRACE, aws, self)
  end
  if @launch != aws.launch_configuration_name and Configuration.instance.autoscaling.override_launch_config_on_sync
    diffs << AutoScalingDiff.new(AutoScalingChange::LAUNCH, aws, self)
  end
  if @load_balancers.sort != aws.load_balancer_names.sort
    diffs << AutoScalingDiff.new(AutoScalingChange::LOAD_BALANCER, aws, self)
  end

  # Get the actual subnet objects from aws using either the id or vpc/subnet combination
  local_subnets = subnets_to_aws.sort_by(&:subnet_id)
  aws_subnets = aws.vpc_zone_identifier.split(",").map do |subnet_id|
    EC2::id_subnets[subnet_id]
  end.sort_by(&:subnet_id)

  if local_subnets != aws_subnets
    diffs << AutoScalingDiff.new(AutoScalingChange::SUBNETS, aws_subnets, local_subnets)
  end

  if @tags != Hash[aws.tags.map { |tag| [tag.key, tag.value] }]
    diffs << AutoScalingDiff.new(AutoScalingChange::TAGS, aws, self)
  end
  if @termination != aws.termination_policies
    diffs << AutoScalingDiff.new(AutoScalingChange::TERMINATION, aws, self)
  end

  # check for changes in scheduled actions
  aws_scheduled = autoscaling.describe_scheduled_actions({
    auto_scaling_group_name: @name
  }).scheduled_update_group_actions

  scheduled_diff = AutoScalingDiff.scheduled(aws_scheduled, @scheduled)
  if scheduled_diff
    diffs << scheduled_diff
  end

  aws_min = aws.min_size
  aws_max = aws.max_size
  aws_desired = aws.desired_capacity
  local_min = @min
  local_max = @max
  local_desired = @desired
  update_desired = Configuration.instance.autoscaling.force_size

  # If there is local scheduled actions, use the most recent one to determine the local min/max
  if !@scheduled.empty? and !Configuration.instance.autoscaling.force_size
    local_last_scheduled = last_scheduled

    if local_last_scheduled
      local_min = local_last_scheduled.min
      local_max = local_last_scheduled.max
      local_desired = local_last_scheduled.desired
    end
  end

  # If desired was not specified, assume it is the min
  local_desired = local_min if !local_desired

  # If the aws desired value is outside of the new min/max bounds then we need to
  # update desired to be in the bounds
  if local_min and aws_desired < local_min
    local_desired = local_min if local_desired < local_min
    update_desired = true
  elsif local_max and aws_desired > local_max
    local_desired = local_max if local_desired > local_max
    update_desired = true
  end

  if local_min and local_min != aws_min
    diffs << AutoScalingDiff.new(AutoScalingChange::MIN, aws_min, local_min)
  end
  if local_max and local_max != aws_max
    diffs << AutoScalingDiff.new(AutoScalingChange::MAX, aws_max, local_max)
  end
  if update_desired
    diffs << AutoScalingDiff.new(AutoScalingChange::DESIRED, aws_desired, local_desired)
  end

  # check for changes in scaling policies
  aws_policies = autoscaling.describe_policies({
    auto_scaling_group_name: @name
  }).scaling_policies
  policy_diffs = diff_policies(aws_policies)
  if !policy_diffs.empty?
    diffs << AutoScalingDiff.policies(self, policy_diffs)
  end

  diffs
end

#last_scheduledObject



232
233
234
235
236
237
238
239
# File 'lib/autoscaling/models/GroupConfig.rb', line 232

def last_scheduled
  time_source = Common::UTCTimeSource.new

  @scheduled.values.sort_by do |scheduled|
    cron_parser = CronParser.new(scheduled.recurrence, time_source)
    cron_parser.last
  end.last
end

#populate(resource) ⇒ Object

Public: Populate the GroupConfig from an existing AWS AutoScaling group

resource - the aws resource to populate from



244
245
246
247
248
249
250
251
252
253
254
255
256
257
# File 'lib/autoscaling/models/GroupConfig.rb', line 244

def populate(resource)
  @check_grace = resource.health_check_grace_period
  @check_type = resource.health_check_type
  @cooldown = resource.default_cooldown
  @desired = resource.desired_capacity unless resource.desired_capacity.nil?
  @enabled_metrics = resource.enabled_metrics.map { |m| m.metric }
  @launch = resource.launch_configuration_name
  @load_balancers = resource.load_balancer_names
  @max = resource.max_size
  @min = resource.min_size
  @subnets = resource.vpc_zone_identifier.split(",")
  @tags = Hash[resource.tags.map { |tag| [tag.key, tag.value] }]
  @termination = resource.termination_policies
end

#populate_policies(policies) ⇒ Object

Public: Populate the policies from existing scaling policies in AWS.

policies - the policies to populate from



274
275
276
277
278
279
280
# File 'lib/autoscaling/models/GroupConfig.rb', line 274

def populate_policies(policies)
  @policies = policies.map do |policy|
    config = PolicyConfig.new()
    config.populate(policy)
    config
  end
end

#populate_scheduled(actions) ⇒ Object

Public: Populate the scheduled actions from existing scheduled actions in AWS.

actions - the scheduled actions to populate from



263
264
265
266
267
268
269
# File 'lib/autoscaling/models/GroupConfig.rb', line 263

def populate_scheduled(actions)
  @scheduled = actions.map do |action|
    config = ScheduledConfig.new()
    config.populate(action)
    config
  end
end

#pretty_jsonObject

Public: Get the config as a prettified JSON string. All policies will be in inlines.

Returns the JSON string.



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/autoscaling/models/GroupConfig.rb', line 75

def pretty_json
  JSON.pretty_generate({
    "cooldown-seconds" => @cooldown,
    "enabled-metrics" => @enabled_metrics,
    "health-check-type" => @check_type,
    "health-check-grace-seconds" => @check_grace,
    "launch-configuration" => @launch,
    "load-balancers" => @load_balancers,
    "policies" => {
      "static" => [],
      "templates" => [],
      "inlines" => @policies.map { |p| p.hash }
    },
    "scheduled" => @scheduled.map { |s| s.hash },
    "size" => {
      "min" => @min,
      "max" => @max,
      "desired" => @desired
    },
    "subnets" => @subnets,
    "tags" => @tags,
    "termination" => @termination
  }.reject { |k, v| v.nil? })
end

#to_aws(include_min_max_desired) ⇒ Object

Public: Generate the object that AWS expects to create or update an AutoScaling group

include_min_max_desired - if true, min_size, max_size and desired_capacity will be included in the hash

Returns a hash of the information that AWS expects



107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/autoscaling/models/GroupConfig.rb', line 107

def to_aws(include_min_max_desired)
  {
    auto_scaling_group_name: @name,
    min_size: if include_min_max_desired then @min end,
    max_size: if include_min_max_desired then @max end,
    desired_capacity: if include_min_max_desired then @desired end,
    default_cooldown: @cooldown,
    health_check_type: @check_type,
    health_check_grace_period: @check_grace,
    vpc_zone_identifier: if !@subnets.empty? then subnets_to_aws.map(&:subnet_id).join(",") end,
    termination_policies: @termination,
    launch_configuration_name: @launch
  }
end