cumulus-aws 0.11.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 +15 -0
- data/.gitignore +3 -0
- data/.travis.yml +12 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +29 -0
- data/LICENSE +202 -0
- data/README.md +41 -0
- data/autocomplete +137 -0
- data/bin/cumulus +658 -0
- data/cumulus +2 -0
- data/cumulus-aws.gemspec +20 -0
- data/lib/autoscaling/AutoScaling.rb +40 -0
- data/lib/autoscaling/loader/Loader.rb +56 -0
- data/lib/autoscaling/manager/Manager.rb +360 -0
- data/lib/autoscaling/models/AlarmConfig.rb +165 -0
- data/lib/autoscaling/models/AlarmDiff.rb +172 -0
- data/lib/autoscaling/models/AutoScalingDiff.rb +178 -0
- data/lib/autoscaling/models/GroupConfig.rb +330 -0
- data/lib/autoscaling/models/PolicyConfig.rb +135 -0
- data/lib/autoscaling/models/PolicyDiff.rb +73 -0
- data/lib/autoscaling/models/ScheduledActionDiff.rb +53 -0
- data/lib/autoscaling/models/ScheduledConfig.rb +96 -0
- data/lib/aws_extensions/ec2/DhcpOptions.rb +41 -0
- data/lib/aws_extensions/ec2/Instance.rb +29 -0
- data/lib/aws_extensions/ec2/NetworkAcl.rb +25 -0
- data/lib/aws_extensions/ec2/NetworkInterface.rb +14 -0
- data/lib/aws_extensions/ec2/RouteTable.rb +26 -0
- data/lib/aws_extensions/ec2/SecurityGroup.rb +16 -0
- data/lib/aws_extensions/ec2/Subnet.rb +28 -0
- data/lib/aws_extensions/ec2/Volume.rb +24 -0
- data/lib/aws_extensions/ec2/Vpc.rb +14 -0
- data/lib/aws_extensions/ec2/VpcEndpoint.rb +11 -0
- data/lib/aws_extensions/elb/BackendServerDescription.rb +12 -0
- data/lib/aws_extensions/elb/PolicyDescription.rb +14 -0
- data/lib/aws_extensions/kinesis/StreamDescription.rb +12 -0
- data/lib/aws_extensions/route53/AliasTarget.rb +21 -0
- data/lib/aws_extensions/s3/Bucket.rb +33 -0
- data/lib/aws_extensions/s3/BucketAcl.rb +28 -0
- data/lib/aws_extensions/s3/BucketCors.rb +17 -0
- data/lib/aws_extensions/s3/BucketLifecycle.rb +21 -0
- data/lib/aws_extensions/s3/BucketLogging.rb +18 -0
- data/lib/aws_extensions/s3/BucketNotification.rb +23 -0
- data/lib/aws_extensions/s3/BucketPolicy.rb +18 -0
- data/lib/aws_extensions/s3/BucketTagging.rb +15 -0
- data/lib/aws_extensions/s3/BucketVersioning.rb +14 -0
- data/lib/aws_extensions/s3/BucketWebsite.rb +49 -0
- data/lib/aws_extensions/s3/CORSRule.rb +27 -0
- data/lib/aws_extensions/s3/ReplicationConfiguration.rb +22 -0
- data/lib/cloudfront/CloudFront.rb +83 -0
- data/lib/cloudfront/loader/Loader.rb +31 -0
- data/lib/cloudfront/manager/Manager.rb +183 -0
- data/lib/cloudfront/models/CacheBehaviorConfig.rb +237 -0
- data/lib/cloudfront/models/CacheBehaviorDiff.rb +211 -0
- data/lib/cloudfront/models/CustomOriginConfig.rb +51 -0
- data/lib/cloudfront/models/CustomOriginDiff.rb +74 -0
- data/lib/cloudfront/models/DistributionConfig.rb +183 -0
- data/lib/cloudfront/models/DistributionDiff.rb +131 -0
- data/lib/cloudfront/models/InvalidationConfig.rb +37 -0
- data/lib/cloudfront/models/OriginConfig.rb +144 -0
- data/lib/cloudfront/models/OriginDiff.rb +86 -0
- data/lib/cloudfront/models/OriginSslProtocols.rb +28 -0
- data/lib/cloudfront/models/OriginSslProtocolsDiff.rb +39 -0
- data/lib/common/BaseLoader.rb +80 -0
- data/lib/common/manager/Manager.rb +148 -0
- data/lib/common/models/Diff.rb +114 -0
- data/lib/common/models/ListChange.rb +21 -0
- data/lib/common/models/TagsDiff.rb +55 -0
- data/lib/common/models/UTCTimeSource.rb +17 -0
- data/lib/conf/Configuration.rb +365 -0
- data/lib/ec2/EC2.rb +503 -0
- data/lib/ec2/IPProtocolMapping.rb +165 -0
- data/lib/ec2/loaders/EbsLoader.rb +19 -0
- data/lib/ec2/loaders/InstanceLoader.rb +32 -0
- data/lib/ec2/managers/EbsManager.rb +176 -0
- data/lib/ec2/managers/InstanceManager.rb +509 -0
- data/lib/ec2/models/EbsGroupConfig.rb +133 -0
- data/lib/ec2/models/EbsGroupDiff.rb +48 -0
- data/lib/ec2/models/InstanceConfig.rb +202 -0
- data/lib/ec2/models/InstanceDiff.rb +95 -0
- data/lib/elb/ELB.rb +148 -0
- data/lib/elb/loader/Loader.rb +65 -0
- data/lib/elb/manager/Manager.rb +581 -0
- data/lib/elb/models/AccessLogConfig.rb +82 -0
- data/lib/elb/models/AccessLogDiff.rb +47 -0
- data/lib/elb/models/HealthCheckConfig.rb +91 -0
- data/lib/elb/models/HealthCheckDiff.rb +50 -0
- data/lib/elb/models/ListenerConfig.rb +99 -0
- data/lib/elb/models/ListenerDiff.rb +91 -0
- data/lib/elb/models/LoadBalancerConfig.rb +239 -0
- data/lib/elb/models/LoadBalancerDiff.rb +265 -0
- data/lib/iam/IAM.rb +36 -0
- data/lib/iam/loader/Loader.rb +117 -0
- data/lib/iam/manager/IamGroups.rb +98 -0
- data/lib/iam/manager/IamResource.rb +288 -0
- data/lib/iam/manager/IamRoles.rb +112 -0
- data/lib/iam/manager/IamUsers.rb +54 -0
- data/lib/iam/manager/Manager.rb +29 -0
- data/lib/iam/migration/AssumeRoleUnifier.rb +34 -0
- data/lib/iam/migration/PolicyUnifier.rb +90 -0
- data/lib/iam/models/GroupConfig.rb +40 -0
- data/lib/iam/models/IamDiff.rb +132 -0
- data/lib/iam/models/PolicyConfig.rb +67 -0
- data/lib/iam/models/ResourceWithPolicy.rb +208 -0
- data/lib/iam/models/RoleConfig.rb +53 -0
- data/lib/iam/models/StatementConfig.rb +35 -0
- data/lib/iam/models/UserConfig.rb +21 -0
- data/lib/kinesis/Kinesis.rb +94 -0
- data/lib/kinesis/loader/Loader.rb +19 -0
- data/lib/kinesis/manager/Manager.rb +206 -0
- data/lib/kinesis/models/StreamConfig.rb +75 -0
- data/lib/kinesis/models/StreamDiff.rb +58 -0
- data/lib/lambda/Lambda.rb +41 -0
- data/lib/route53/loader/Loader.rb +32 -0
- data/lib/route53/manager/Manager.rb +241 -0
- data/lib/route53/models/AliasTarget.rb +86 -0
- data/lib/route53/models/RecordConfig.rb +178 -0
- data/lib/route53/models/RecordDiff.rb +140 -0
- data/lib/route53/models/Vpc.rb +24 -0
- data/lib/route53/models/ZoneConfig.rb +156 -0
- data/lib/route53/models/ZoneDiff.rb +118 -0
- data/lib/s3/S3.rb +89 -0
- data/lib/s3/loader/Loader.rb +66 -0
- data/lib/s3/manager/Manager.rb +296 -0
- data/lib/s3/models/BucketConfig.rb +321 -0
- data/lib/s3/models/BucketDiff.rb +167 -0
- data/lib/s3/models/GrantConfig.rb +189 -0
- data/lib/s3/models/GrantDiff.rb +50 -0
- data/lib/s3/models/LifecycleConfig.rb +142 -0
- data/lib/s3/models/LifecycleDiff.rb +46 -0
- data/lib/s3/models/LoggingConfig.rb +81 -0
- data/lib/s3/models/NotificationConfig.rb +157 -0
- data/lib/s3/models/NotificationDiff.rb +62 -0
- data/lib/s3/models/ReplicationConfig.rb +133 -0
- data/lib/s3/models/ReplicationDiff.rb +60 -0
- data/lib/s3/models/WebsiteConfig.rb +107 -0
- data/lib/security/SecurityGroups.rb +39 -0
- data/lib/security/loader/Loader.rb +94 -0
- data/lib/security/manager/Manager.rb +246 -0
- data/lib/security/models/RuleConfig.rb +161 -0
- data/lib/security/models/RuleDiff.rb +72 -0
- data/lib/security/models/RuleMigration.rb +127 -0
- data/lib/security/models/SecurityGroupConfig.rb +172 -0
- data/lib/security/models/SecurityGroupDiff.rb +112 -0
- data/lib/sns/SNS.rb +40 -0
- data/lib/sqs/SQS.rb +62 -0
- data/lib/sqs/loader/Loader.rb +34 -0
- data/lib/sqs/manager/Manager.rb +128 -0
- data/lib/sqs/models/DeadLetterConfig.rb +70 -0
- data/lib/sqs/models/DeadLetterDiff.rb +35 -0
- data/lib/sqs/models/QueueConfig.rb +115 -0
- data/lib/sqs/models/QueueDiff.rb +89 -0
- data/lib/util/Colors.rb +111 -0
- data/lib/util/StatusCodes.rb +51 -0
- data/lib/vpc/loader/Loader.rb +73 -0
- data/lib/vpc/manager/Manager.rb +954 -0
- data/lib/vpc/models/AclEntryConfig.rb +150 -0
- data/lib/vpc/models/AclEntryDiff.rb +54 -0
- data/lib/vpc/models/DhcpConfig.rb +100 -0
- data/lib/vpc/models/DhcpDiff.rb +90 -0
- data/lib/vpc/models/EndpointConfig.rb +76 -0
- data/lib/vpc/models/EndpointDiff.rb +69 -0
- data/lib/vpc/models/NetworkAclConfig.rb +87 -0
- data/lib/vpc/models/NetworkAclDiff.rb +116 -0
- data/lib/vpc/models/RouteConfig.rb +82 -0
- data/lib/vpc/models/RouteDiff.rb +50 -0
- data/lib/vpc/models/RouteTableConfig.rb +92 -0
- data/lib/vpc/models/RouteTableDiff.rb +101 -0
- data/lib/vpc/models/SubnetConfig.rb +113 -0
- data/lib/vpc/models/SubnetDiff.rb +78 -0
- data/lib/vpc/models/VpcConfig.rb +173 -0
- data/lib/vpc/models/VpcDiff.rb +315 -0
- data/rakefile.rb +8 -0
- metadata +245 -0
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
require "autoscaling/loader/Loader"
|
|
2
|
+
require "autoscaling/models/AutoScalingDiff"
|
|
3
|
+
require "autoscaling/models/PolicyConfig"
|
|
4
|
+
require "autoscaling/models/PolicyDiff"
|
|
5
|
+
require "autoscaling/models/ScheduledActionDiff"
|
|
6
|
+
require "autoscaling/models/ScheduledConfig"
|
|
7
|
+
require "common/models/UTCTimeSource"
|
|
8
|
+
require "ec2/EC2"
|
|
9
|
+
|
|
10
|
+
require "parse-cron"
|
|
11
|
+
|
|
12
|
+
module Cumulus
|
|
13
|
+
module AutoScaling
|
|
14
|
+
# Public: An object representing the configuration for an AutoScaling group.
|
|
15
|
+
class GroupConfig
|
|
16
|
+
attr_reader :check_grace
|
|
17
|
+
attr_reader :check_type
|
|
18
|
+
attr_reader :cooldown
|
|
19
|
+
attr_reader :desired
|
|
20
|
+
attr_reader :enabled_metrics
|
|
21
|
+
attr_reader :launch
|
|
22
|
+
attr_reader :load_balancers
|
|
23
|
+
attr_reader :max
|
|
24
|
+
attr_reader :min
|
|
25
|
+
attr_reader :name
|
|
26
|
+
attr_reader :policies
|
|
27
|
+
attr_reader :scheduled
|
|
28
|
+
attr_reader :subnets
|
|
29
|
+
attr_reader :tags
|
|
30
|
+
attr_reader :termination
|
|
31
|
+
|
|
32
|
+
# Public: Constructor
|
|
33
|
+
#
|
|
34
|
+
# name - the name of the group
|
|
35
|
+
# json - a hash containing the json configuration for the AutoScaling group
|
|
36
|
+
def initialize(name, json = nil)
|
|
37
|
+
@name = name
|
|
38
|
+
if !json.nil?
|
|
39
|
+
@cooldown = json["cooldown-seconds"]
|
|
40
|
+
@min = json["size"]["min"]
|
|
41
|
+
@max = json["size"]["max"]
|
|
42
|
+
@desired = json["size"]["desired"]
|
|
43
|
+
@enabled_metrics = json["enabled-metrics"]
|
|
44
|
+
@check_type = json["health-check-type"]
|
|
45
|
+
@check_grace = json["health-check-grace-seconds"]
|
|
46
|
+
@launch = json["launch-configuration"]
|
|
47
|
+
@load_balancers = json["load-balancers"]
|
|
48
|
+
@subnets = json["subnets"]
|
|
49
|
+
@tags = json["tags"]
|
|
50
|
+
@termination = json["termination"]
|
|
51
|
+
@scheduled = Hash[(json["scheduled"] || []).map { |json| [json["name"], ScheduledConfig.new(json)] }]
|
|
52
|
+
|
|
53
|
+
# load scaling policies
|
|
54
|
+
static_policies = json["policies"]["static"].map { |file| Loader.static_policy(file) }
|
|
55
|
+
template_policies = json["policies"]["templates"].map do |template|
|
|
56
|
+
Loader.template_policy(template["template"], template["vars"])
|
|
57
|
+
end
|
|
58
|
+
inline_policies = json["policies"]["inlines"].map { |inline| PolicyConfig.new(inline) }
|
|
59
|
+
@policies = static_policies + template_policies + inline_policies
|
|
60
|
+
@policies = Hash[@policies.map { |policy| [policy.name, policy] }]
|
|
61
|
+
else
|
|
62
|
+
@enabled_metrics = []
|
|
63
|
+
@load_balancers = []
|
|
64
|
+
@subnets = []
|
|
65
|
+
@tags = {}
|
|
66
|
+
@termination = []
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Public: Get the config as a prettified JSON string. All policies will be in
|
|
71
|
+
# inlines.
|
|
72
|
+
#
|
|
73
|
+
# Returns the JSON string.
|
|
74
|
+
def pretty_json
|
|
75
|
+
JSON.pretty_generate({
|
|
76
|
+
"cooldown-seconds" => @cooldown,
|
|
77
|
+
"enabled-metrics" => @enabled_metrics,
|
|
78
|
+
"health-check-type" => @check_type,
|
|
79
|
+
"health-check-grace-seconds" => @check_grace,
|
|
80
|
+
"launch-configuration" => @launch,
|
|
81
|
+
"load-balancers" => @load_balancers,
|
|
82
|
+
"policies" => {
|
|
83
|
+
"static" => [],
|
|
84
|
+
"templates" => [],
|
|
85
|
+
"inlines" => @policies.map { |p| p.hash }
|
|
86
|
+
},
|
|
87
|
+
"scheduled" => @scheduled.map { |s| s.hash },
|
|
88
|
+
"size" => {
|
|
89
|
+
"min" => @min,
|
|
90
|
+
"max" => @max,
|
|
91
|
+
"desired" => @desired
|
|
92
|
+
},
|
|
93
|
+
"subnets" => @subnets,
|
|
94
|
+
"tags" => @tags,
|
|
95
|
+
"termination" => @termination
|
|
96
|
+
}.reject { |k, v| v.nil? })
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# Public: Generate the object that AWS expects to create or update an
|
|
100
|
+
# AutoScaling group
|
|
101
|
+
#
|
|
102
|
+
# include_min_max_desired - if true, min_size, max_size and desired_capacity
|
|
103
|
+
# will be included in the hash
|
|
104
|
+
#
|
|
105
|
+
# Returns a hash of the information that AWS expects
|
|
106
|
+
def to_aws(include_min_max_desired)
|
|
107
|
+
{
|
|
108
|
+
auto_scaling_group_name: @name,
|
|
109
|
+
min_size: if include_min_max_desired then @min end,
|
|
110
|
+
max_size: if include_min_max_desired then @max end,
|
|
111
|
+
desired_capacity: if include_min_max_desired then @desired end,
|
|
112
|
+
default_cooldown: @cooldown,
|
|
113
|
+
health_check_type: @check_type,
|
|
114
|
+
health_check_grace_period: @check_grace,
|
|
115
|
+
vpc_zone_identifier: if !@subnets.empty? then subnets_to_aws.map(&:subnet_id).join(",") end,
|
|
116
|
+
termination_policies: @termination,
|
|
117
|
+
launch_configuration_name: @launch
|
|
118
|
+
}
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# Public: Produce the differences between this local configuration and the
|
|
122
|
+
# configuration in AWS
|
|
123
|
+
#
|
|
124
|
+
# aws - the aws resource
|
|
125
|
+
# autoscaling - the AWS client needed to get additional AWS resources
|
|
126
|
+
#
|
|
127
|
+
# Returns an Array of the AutoScalingDiffs that were found
|
|
128
|
+
def diff(aws, autoscaling)
|
|
129
|
+
diffs = []
|
|
130
|
+
|
|
131
|
+
if @cooldown != aws.default_cooldown
|
|
132
|
+
diffs << AutoScalingDiff.new(AutoScalingChange::COOLDOWN, aws, self)
|
|
133
|
+
end
|
|
134
|
+
if @enabled_metrics != aws.enabled_metrics
|
|
135
|
+
diffs << AutoScalingDiff.new(AutoScalingChange::METRICS, aws, self)
|
|
136
|
+
end
|
|
137
|
+
if @check_type != aws.health_check_type
|
|
138
|
+
diffs << AutoScalingDiff.new(AutoScalingChange::CHECK_TYPE, aws, self)
|
|
139
|
+
end
|
|
140
|
+
if @check_grace != aws.health_check_grace_period
|
|
141
|
+
diffs << AutoScalingDiff.new(AutoScalingChange::CHECK_GRACE, aws, self)
|
|
142
|
+
end
|
|
143
|
+
if @launch != aws.launch_configuration_name and Configuration.instance.autoscaling.override_launch_config_on_sync
|
|
144
|
+
diffs << AutoScalingDiff.new(AutoScalingChange::LAUNCH, aws, self)
|
|
145
|
+
end
|
|
146
|
+
if @load_balancers.sort != aws.load_balancer_names.sort
|
|
147
|
+
diffs << AutoScalingDiff.new(AutoScalingChange::LOAD_BALANCER, aws, self)
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# Get the actual subnet objects from aws using either the id or vpc/subnet combination
|
|
151
|
+
local_subnets = subnets_to_aws.sort_by(&:subnet_id)
|
|
152
|
+
aws_subnets = aws.vpc_zone_identifier.split(",").map do |subnet_id|
|
|
153
|
+
EC2::id_subnets[subnet_id]
|
|
154
|
+
end.sort_by(&:subnet_id)
|
|
155
|
+
|
|
156
|
+
if local_subnets != aws_subnets
|
|
157
|
+
diffs << AutoScalingDiff.new(AutoScalingChange::SUBNETS, aws_subnets, local_subnets)
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
if @tags != Hash[aws.tags.map { |tag| [tag.key, tag.value] }]
|
|
161
|
+
diffs << AutoScalingDiff.new(AutoScalingChange::TAGS, aws, self)
|
|
162
|
+
end
|
|
163
|
+
if @termination != aws.termination_policies
|
|
164
|
+
diffs << AutoScalingDiff.new(AutoScalingChange::TERMINATION, aws, self)
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
# check for changes in scheduled actions
|
|
168
|
+
aws_scheduled = autoscaling.describe_scheduled_actions({
|
|
169
|
+
auto_scaling_group_name: @name
|
|
170
|
+
}).scheduled_update_group_actions
|
|
171
|
+
|
|
172
|
+
scheduled_diff = AutoScalingDiff.scheduled(aws_scheduled, @scheduled)
|
|
173
|
+
if scheduled_diff
|
|
174
|
+
diffs << scheduled_diff
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
aws_min = aws.min_size
|
|
178
|
+
aws_max = aws.max_size
|
|
179
|
+
aws_desired = aws.desired_capacity
|
|
180
|
+
local_min = @min
|
|
181
|
+
local_max = @max
|
|
182
|
+
local_desired = @desired
|
|
183
|
+
update_desired = Configuration.instance.autoscaling.force_size
|
|
184
|
+
|
|
185
|
+
# If there is local scheduled actions, use the most recent one to determine the local min/max
|
|
186
|
+
if !@scheduled.empty? and !Configuration.instance.autoscaling.force_size
|
|
187
|
+
local_last_scheduled = last_scheduled
|
|
188
|
+
|
|
189
|
+
if local_last_scheduled
|
|
190
|
+
local_min = local_last_scheduled.min
|
|
191
|
+
local_max = local_last_scheduled.max
|
|
192
|
+
local_desired = local_last_scheduled.desired
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
# If desired was not specified, assume it is the min
|
|
197
|
+
local_desired = local_min if !local_desired
|
|
198
|
+
|
|
199
|
+
# If the aws desired value is outside of the new min/max bounds then we need to
|
|
200
|
+
# update desired to be in the bounds
|
|
201
|
+
if local_min and aws_desired < local_min
|
|
202
|
+
local_desired = local_min if local_desired < local_min
|
|
203
|
+
update_desired = true
|
|
204
|
+
elsif local_max and aws_desired > local_max
|
|
205
|
+
local_desired = local_max if local_desired > local_max
|
|
206
|
+
update_desired = true
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
if local_min and local_min != aws_min
|
|
210
|
+
diffs << AutoScalingDiff.new(AutoScalingChange::MIN, aws_min, local_min)
|
|
211
|
+
end
|
|
212
|
+
if local_max and local_max != aws_max
|
|
213
|
+
diffs << AutoScalingDiff.new(AutoScalingChange::MAX, aws_max, local_max)
|
|
214
|
+
end
|
|
215
|
+
if update_desired
|
|
216
|
+
diffs << AutoScalingDiff.new(AutoScalingChange::DESIRED, aws_desired, local_desired)
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
# check for changes in scaling policies
|
|
220
|
+
aws_policies = autoscaling.describe_policies({
|
|
221
|
+
auto_scaling_group_name: @name
|
|
222
|
+
}).scaling_policies
|
|
223
|
+
policy_diffs = diff_policies(aws_policies)
|
|
224
|
+
if !policy_diffs.empty?
|
|
225
|
+
diffs << AutoScalingDiff.policies(self, policy_diffs)
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
diffs
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
def last_scheduled
|
|
232
|
+
time_source = Common::UTCTimeSource.new
|
|
233
|
+
|
|
234
|
+
@scheduled.values.sort_by do |scheduled|
|
|
235
|
+
cron_parser = CronParser.new(scheduled.recurrence, time_source)
|
|
236
|
+
cron_parser.last
|
|
237
|
+
end.last
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
# Public: Populate the GroupConfig from an existing AWS AutoScaling group
|
|
241
|
+
#
|
|
242
|
+
# resource - the aws resource to populate from
|
|
243
|
+
def populate(resource)
|
|
244
|
+
@check_grace = resource.health_check_grace_period
|
|
245
|
+
@check_type = resource.health_check_type
|
|
246
|
+
@cooldown = resource.default_cooldown
|
|
247
|
+
@desired = resource.desired_capacity unless resource.desired_capacity.nil?
|
|
248
|
+
@enabled_metrics = resource.enabled_metrics.map { |m| m.metric }
|
|
249
|
+
@launch = resource.launch_configuration_name
|
|
250
|
+
@load_balancers = resource.load_balancer_names
|
|
251
|
+
@max = resource.max_size
|
|
252
|
+
@min = resource.min_size
|
|
253
|
+
@subnets = resource.vpc_zone_identifier.split(",")
|
|
254
|
+
@tags = Hash[resource.tags.map { |tag| [tag.key, tag.value] }]
|
|
255
|
+
@termination = resource.termination_policies
|
|
256
|
+
end
|
|
257
|
+
|
|
258
|
+
# Public: Populate the scheduled actions from existing scheduled actions in
|
|
259
|
+
# AWS.
|
|
260
|
+
#
|
|
261
|
+
# actions - the scheduled actions to populate from
|
|
262
|
+
def populate_scheduled(actions)
|
|
263
|
+
@scheduled = actions.map do |action|
|
|
264
|
+
config = ScheduledConfig.new()
|
|
265
|
+
config.populate(action)
|
|
266
|
+
config
|
|
267
|
+
end
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
# Public: Populate the policies from existing scaling policies in AWS.
|
|
271
|
+
#
|
|
272
|
+
# policies - the policies to populate from
|
|
273
|
+
def populate_policies(policies)
|
|
274
|
+
@policies = policies.map do |policy|
|
|
275
|
+
config = PolicyConfig.new()
|
|
276
|
+
config.populate(policy)
|
|
277
|
+
config
|
|
278
|
+
end
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
private
|
|
282
|
+
|
|
283
|
+
# Internal: Convert the local subnet names/ids into aws Subnets
|
|
284
|
+
def subnets_to_aws
|
|
285
|
+
@subnets.map do |local_subnet|
|
|
286
|
+
if local_subnet =~ /^subnet-[a-zA-Z0-9]+$/
|
|
287
|
+
EC2::id_subnets[local_subnet]
|
|
288
|
+
else
|
|
289
|
+
# Assume its in vpc/subnet form
|
|
290
|
+
vpc, subnet = local_subnet.split("/")
|
|
291
|
+
aws_vpc = EC2::id_vpcs[vpc] || EC2::named_vpcs[vpc]
|
|
292
|
+
if !aws_vpc
|
|
293
|
+
raise "Could not find vpc for #{local_subnet}"
|
|
294
|
+
end
|
|
295
|
+
aws_subnet = EC2::vpc_subnets[aws_vpc.vpc_id].find { |s| s.subnet_id == subnet || s.name == subnet }
|
|
296
|
+
if !aws_subnet
|
|
297
|
+
raise "Could not find subnet for #{local_subnet}"
|
|
298
|
+
end
|
|
299
|
+
aws_subnet
|
|
300
|
+
end
|
|
301
|
+
end
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
# Internal: Determine changes in scaling policies.
|
|
305
|
+
#
|
|
306
|
+
# aws_policies - the scaling policies in AWS
|
|
307
|
+
#
|
|
308
|
+
# Returns an array of PolicyDiff's that represent differences between local
|
|
309
|
+
# and AWS configuration
|
|
310
|
+
def diff_policies(aws_policies)
|
|
311
|
+
diffs = []
|
|
312
|
+
|
|
313
|
+
aws_policies = Hash[aws_policies.map { |p| [p.policy_name, p] }]
|
|
314
|
+
aws_policies.reject { |k, v| @policies.include?(k) }.each do |name, aws|
|
|
315
|
+
diffs << PolicyDiff.unmanaged(aws)
|
|
316
|
+
end
|
|
317
|
+
@policies.each do |name, local|
|
|
318
|
+
if !aws_policies.include?(name)
|
|
319
|
+
diffs << PolicyDiff.added(local)
|
|
320
|
+
else
|
|
321
|
+
diffs << local.diff(aws_policies[name])
|
|
322
|
+
end
|
|
323
|
+
end
|
|
324
|
+
|
|
325
|
+
diffs.flatten
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
end
|
|
329
|
+
end
|
|
330
|
+
end
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
require "autoscaling/models/AlarmConfig"
|
|
2
|
+
require "autoscaling/models/AlarmDiff"
|
|
3
|
+
require "autoscaling/models/PolicyDiff"
|
|
4
|
+
require "conf/Configuration"
|
|
5
|
+
|
|
6
|
+
require "aws-sdk"
|
|
7
|
+
|
|
8
|
+
module Cumulus
|
|
9
|
+
module AutoScaling
|
|
10
|
+
# Public: A class that encapsulates data about the way a scaling policy is
|
|
11
|
+
# configured.
|
|
12
|
+
class PolicyConfig
|
|
13
|
+
attr_reader :adjustment
|
|
14
|
+
attr_reader :adjustment_type
|
|
15
|
+
attr_reader :alarms
|
|
16
|
+
attr_reader :cooldown
|
|
17
|
+
attr_reader :min_adjustment
|
|
18
|
+
attr_reader :name
|
|
19
|
+
|
|
20
|
+
# Public: Constructor
|
|
21
|
+
#
|
|
22
|
+
# json - a hash representing the JSON configuration for this scaling policy
|
|
23
|
+
def initialize(json = nil)
|
|
24
|
+
@@cloudwatch ||= Aws::CloudWatch::Client.new(Configuration.instance.client)
|
|
25
|
+
|
|
26
|
+
if !json.nil?
|
|
27
|
+
@name = json["name"]
|
|
28
|
+
@adjustment_type = json["adjustment-type"]
|
|
29
|
+
@adjustment = json["adjustment"]
|
|
30
|
+
@cooldown = json["cooldown"]
|
|
31
|
+
@min_adjustment = json["min-adjustment-step"]
|
|
32
|
+
@alarms = {}
|
|
33
|
+
if !json["alarms"].nil?
|
|
34
|
+
@alarms = Hash[json["alarms"].map { |alarm| [alarm["name"], AlarmConfig.new(alarm)] }]
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Public: Get the configuration as a hash
|
|
40
|
+
#
|
|
41
|
+
# Returns the hash
|
|
42
|
+
def hash
|
|
43
|
+
{
|
|
44
|
+
"name" => @name,
|
|
45
|
+
"adjustment-type" => @adjustment_type,
|
|
46
|
+
"adjustment" => @adjustment,
|
|
47
|
+
"cooldown" => @cooldown,
|
|
48
|
+
"min-adjustment-step" => @min_adjustment,
|
|
49
|
+
"alarms" => @alarms.map { |a| a.hash }
|
|
50
|
+
}.reject { |k, v| v.nil? }
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Public: Produce the differences between this local configuration and the
|
|
54
|
+
# configuration in AWS
|
|
55
|
+
#
|
|
56
|
+
# aws - the scaling policy in AWS
|
|
57
|
+
def diff(aws)
|
|
58
|
+
diffs = []
|
|
59
|
+
|
|
60
|
+
if @adjustment_type != aws.adjustment_type
|
|
61
|
+
diffs << PolicyDiff.new(PolicyChange::ADJUSTMENT_TYPE, aws, self)
|
|
62
|
+
end
|
|
63
|
+
if @adjustment != aws.scaling_adjustment
|
|
64
|
+
diffs << PolicyDiff.new(PolicyChange::ADJUSTMENT, aws, self)
|
|
65
|
+
end
|
|
66
|
+
if @cooldown != aws.cooldown
|
|
67
|
+
diffs << PolicyDiff.new(PolicyChange::COOLDOWN, aws, self)
|
|
68
|
+
end
|
|
69
|
+
if @min_adjustment != aws.min_adjustment_step
|
|
70
|
+
diffs << PolicyDiff.new(PolicyChange::MIN_ADJUSTMENT, aws, self)
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# get all cloudwatch alarms that trigger this policy as their action
|
|
74
|
+
aws_alarms = @@cloudwatch.describe_alarms({
|
|
75
|
+
action_prefix: aws.policy_arn
|
|
76
|
+
}).metric_alarms
|
|
77
|
+
alarm_diffs = diff_alarms(aws_alarms, aws.policy_arn)
|
|
78
|
+
if !alarm_diffs.empty?
|
|
79
|
+
diffs << PolicyDiff.alarms(alarm_diffs, self, aws.policy_arn)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
diffs
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Public: Populate the PolicyConfig from an existing AWS scaling policy
|
|
86
|
+
#
|
|
87
|
+
# resource - the aws resource to populate from
|
|
88
|
+
def populate(resource)
|
|
89
|
+
@name = resource.policy_name
|
|
90
|
+
@adjustment_type = resource.adjustment_type
|
|
91
|
+
@adjustment = resource.scaling_adjustment
|
|
92
|
+
@cooldown = resource.cooldown
|
|
93
|
+
@min_adjustment = resource.min_adjustment_step
|
|
94
|
+
|
|
95
|
+
alarms = @@cloudwatch.describe_alarms({
|
|
96
|
+
action_prefix: resource.policy_arn
|
|
97
|
+
}).metric_alarms
|
|
98
|
+
@alarms = alarms.map do |alarm|
|
|
99
|
+
config = AlarmConfig.new()
|
|
100
|
+
config.populate(resource.policy_arn, alarm)
|
|
101
|
+
config
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
private
|
|
106
|
+
|
|
107
|
+
# Internal: Determine changes in alarms
|
|
108
|
+
#
|
|
109
|
+
# aws_alarms - the Cloudwatch alarms in AWS
|
|
110
|
+
# policy_arn - the policy arn is the action the alarms for this policy should
|
|
111
|
+
# take
|
|
112
|
+
#
|
|
113
|
+
# Returns an array of AlarmDiff's that represent differences between local and
|
|
114
|
+
# AWS configuration.
|
|
115
|
+
def diff_alarms(aws_alarms, policy_arn)
|
|
116
|
+
diffs = []
|
|
117
|
+
|
|
118
|
+
aws_alarms = Hash[aws_alarms.map { |a| [a.alarm_name, a] }]
|
|
119
|
+
aws_alarms.reject { |k, v| @alarms.include?(k) }.each do |name, aws|
|
|
120
|
+
diffs << AlarmDiff.unmanaged(aws)
|
|
121
|
+
end
|
|
122
|
+
@alarms.each do |name, local|
|
|
123
|
+
if !aws_alarms.include?(name)
|
|
124
|
+
diffs << AlarmDiff.added(local)
|
|
125
|
+
else
|
|
126
|
+
diffs << local.diff(aws_alarms[name], policy_arn)
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
diffs.flatten
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|