lucid-cumulus 0.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.gitignore +3 -0
- data/.travis.yml +11 -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/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/lucid-cumulus.gemspec +20 -0
- data/rakefile.rb +8 -0
- metadata +245 -0
@@ -0,0 +1,239 @@
|
|
1
|
+
require "conf/Configuration"
|
2
|
+
require "elb/models/LoadBalancerDiff"
|
3
|
+
require "elb/models/ListenerConfig"
|
4
|
+
require "elb/models/HealthCheckConfig"
|
5
|
+
require "elb/models/AccessLogConfig"
|
6
|
+
require "elb/loader/Loader"
|
7
|
+
require "elb/ELB"
|
8
|
+
require "ec2/EC2"
|
9
|
+
require "security/SecurityGroups"
|
10
|
+
|
11
|
+
require "json"
|
12
|
+
|
13
|
+
module Cumulus
|
14
|
+
module ELB
|
15
|
+
|
16
|
+
# Public: An object representing configuration for a load balancer
|
17
|
+
class LoadBalancerConfig
|
18
|
+
attr_reader :name
|
19
|
+
attr_reader :listeners
|
20
|
+
attr_reader :availability_zones
|
21
|
+
attr_reader :subnets
|
22
|
+
attr_reader :security_groups
|
23
|
+
attr_reader :internal
|
24
|
+
attr_reader :tags
|
25
|
+
attr_reader :manage_instances
|
26
|
+
attr_reader :health_check
|
27
|
+
attr_reader :cross_zone
|
28
|
+
attr_reader :access_log
|
29
|
+
attr_reader :connection_draining
|
30
|
+
attr_reader :idle_timeout
|
31
|
+
attr_reader :backend_policies
|
32
|
+
|
33
|
+
require "aws_extensions/elb/BackendServerDescription"
|
34
|
+
Aws::ElasticLoadBalancing::Types::BackendServerDescription.send(:include, AwsExtensions::ELB::BackendServerDescription)
|
35
|
+
|
36
|
+
# Public: Constructor
|
37
|
+
#
|
38
|
+
# json - a hash containing the JSON configuration for the load balancer
|
39
|
+
def initialize(name, json = nil)
|
40
|
+
@name = name
|
41
|
+
if !json.nil?
|
42
|
+
|
43
|
+
# load the included listeners and templates
|
44
|
+
@listeners = []
|
45
|
+
if json["listeners"]
|
46
|
+
if json["listeners"]["includes"]
|
47
|
+
json["listeners"]["includes"].each do |template_json|
|
48
|
+
@listeners << Loader.listener(template_json["template"], template_json["vars"])
|
49
|
+
end
|
50
|
+
end
|
51
|
+
if json["listeners"]["inlines"]
|
52
|
+
json["listeners"]["inlines"].each do |inline|
|
53
|
+
@listeners << ListenerConfig.new(inline)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# Map subnets to their actual subnet description from aws
|
59
|
+
@subnets = (json["subnets"] || []).map do |subnet|
|
60
|
+
full_subnet = EC2::named_subnets[subnet]
|
61
|
+
|
62
|
+
if full_subnet.nil?
|
63
|
+
raise "#{subnet} is not a valid subnet name or id"
|
64
|
+
else
|
65
|
+
full_subnet
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# Map backend policies to the Aws::ElasticLoadBalancing::Types::BackendServerDescription
|
70
|
+
# reject any local polices with empty policies array which means it should be deleted from aws
|
71
|
+
@backend_policies = (json["backend-policies"] || []).map do |backend|
|
72
|
+
Aws::ElasticLoadBalancing::Types::BackendServerDescription.new({
|
73
|
+
instance_port: backend["port"],
|
74
|
+
policy_names: backend["policies"]
|
75
|
+
})
|
76
|
+
end.reject { |backend| backend.policy_names.empty? }
|
77
|
+
|
78
|
+
@security_groups = json["security-groups"] || []
|
79
|
+
@internal = json["internal"] || false
|
80
|
+
@tags = json["tags"] || {}
|
81
|
+
@manage_instances = json["manage-instances"] || false
|
82
|
+
@health_check = if json["health-check"] then HealthCheckConfig.new(json["health-check"]) end
|
83
|
+
@cross_zone = json["cross-zone"] || false
|
84
|
+
@access_log = if json["access-log"] then AccessLogConfig.new(json["access-log"]) else false end
|
85
|
+
@connection_draining = json["connection-draining"] || false
|
86
|
+
@idle_timeout = json["idle-timeout"]
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# Public: Returns the vpc id for the load balancer config using the first subnet
|
91
|
+
def vpc_id
|
92
|
+
first_subnet = @subnets.first
|
93
|
+
first_subnet.vpc_id if first_subnet
|
94
|
+
end
|
95
|
+
|
96
|
+
# Public: Get the config as a prettified JSON string.
|
97
|
+
#
|
98
|
+
# Returns the JSON string
|
99
|
+
def pretty_json
|
100
|
+
JSON.pretty_generate({
|
101
|
+
"listeners" => {
|
102
|
+
"includes" => [],
|
103
|
+
"inlines" => @listeners.map(&:to_hash)
|
104
|
+
},
|
105
|
+
"subnets" => @subnets.map { |s| s.name || s.subnet_id },
|
106
|
+
"security-groups" => @security_groups,
|
107
|
+
"internal" => @internal,
|
108
|
+
"tags" => @tags,
|
109
|
+
"manage-instances" => @manage_instances,
|
110
|
+
"health-check" => @health_check.to_hash,
|
111
|
+
"backend-policies" => @backend_policies.map do |backend_policy|
|
112
|
+
{
|
113
|
+
"port" => backend_policy.instance_port,
|
114
|
+
"policies" => backend_policy.policy_names
|
115
|
+
}
|
116
|
+
end,
|
117
|
+
"cross-zone" => @cross_zone,
|
118
|
+
"access-log" => if @access_log then @access_log.to_hash else @access_log end,
|
119
|
+
"connection-draining" => @connection_draining,
|
120
|
+
"idle-timeout" => @idle_timeout,
|
121
|
+
})
|
122
|
+
end
|
123
|
+
|
124
|
+
# Public: populates the fields of a LoadBalancerConfig from AWS config
|
125
|
+
#
|
126
|
+
# aws_elb - the elb
|
127
|
+
def populate!(aws_elb, aws_tags, aws_attributes)
|
128
|
+
@listeners = aws_elb.listener_descriptions.map do |l|
|
129
|
+
config = ListenerConfig.new
|
130
|
+
config.populate!(l)
|
131
|
+
config
|
132
|
+
end
|
133
|
+
@subnets = aws_elb.subnets.map { |subnet_id| EC2::id_subnets[subnet_id] }
|
134
|
+
@security_groups = aws_elb.security_groups.map do |sg_id|
|
135
|
+
SecurityGroups::id_security_groups[sg_id].group_name
|
136
|
+
end
|
137
|
+
@internal = aws_elb.scheme == "internal"
|
138
|
+
@tags = Hash[aws_tags.map do |tag|
|
139
|
+
[tag.key, tag.value]
|
140
|
+
end]
|
141
|
+
@manage_instances = aws_elb.instances.map { |i| i.instance_id }
|
142
|
+
@health_check = HealthCheckConfig.new
|
143
|
+
@health_check.populate!(aws_elb.health_check)
|
144
|
+
@backend_policies = aws_elb.backend_server_descriptions
|
145
|
+
@cross_zone = aws_attributes.cross_zone_load_balancing.enabled
|
146
|
+
@access_log = AccessLogConfig.new
|
147
|
+
@access_log.populate!(aws_attributes.access_log)
|
148
|
+
@connection_draining = aws_attributes.connection_draining.enabled && aws_attributes.connection_draining.timeout
|
149
|
+
@idle_timeout = aws_attributes.connection_settings.idle_timeout
|
150
|
+
end
|
151
|
+
|
152
|
+
# Public: Produce an array of differences between this local configuration and the
|
153
|
+
# configuration in AWS
|
154
|
+
#
|
155
|
+
# aws - the AWS resource
|
156
|
+
#
|
157
|
+
# Returns an array of the LoadBalancerDiffs that were found
|
158
|
+
def diff(aws)
|
159
|
+
diffs = []
|
160
|
+
|
161
|
+
listener_diff = LoadBalancerDiff.listeners(aws.listener_descriptions, @listeners)
|
162
|
+
if listener_diff
|
163
|
+
diffs << listener_diff
|
164
|
+
end
|
165
|
+
|
166
|
+
aws_subnets = aws.subnets.map { |subnet_id| EC2::id_subnets[subnet_id] }
|
167
|
+
if @subnets.sort != aws_subnets.sort
|
168
|
+
diffs << LoadBalancerDiff.subnets(aws_subnets, @subnets)
|
169
|
+
end
|
170
|
+
|
171
|
+
named_aws_security_groups = aws.security_groups.map do |sg_id|
|
172
|
+
SecurityGroups::id_security_groups[sg_id].group_name
|
173
|
+
end
|
174
|
+
if @security_groups.sort != named_aws_security_groups.sort
|
175
|
+
diffs << LoadBalancerDiff.security_groups(named_aws_security_groups, @security_groups)
|
176
|
+
end
|
177
|
+
|
178
|
+
aws_internal = (aws.scheme == "internal")
|
179
|
+
if @internal != aws_internal
|
180
|
+
diffs << LoadBalancerDiff.internal(aws_internal, @internal)
|
181
|
+
end
|
182
|
+
|
183
|
+
aws_tags = Hash[ELB::elb_tags(@name).map { |tag| [tag.key, tag.value] }]
|
184
|
+
if @tags != aws_tags
|
185
|
+
diffs << LoadBalancerDiff.tags(aws_tags, @tags)
|
186
|
+
end
|
187
|
+
|
188
|
+
aws_instances = (aws.instances || []).map { |i| i.instance_id }
|
189
|
+
if (@manage_instances != false) && @manage_instances.sort != aws_instances.sort
|
190
|
+
diffs << LoadBalancerDiff.instances(aws_instances, @manage_instances)
|
191
|
+
end
|
192
|
+
|
193
|
+
aws_health_check = aws.health_check
|
194
|
+
health_diffs = @health_check.diff(aws_health_check)
|
195
|
+
if !health_diffs.empty?
|
196
|
+
diffs << LoadBalancerDiff.health_check(health_diffs)
|
197
|
+
end
|
198
|
+
|
199
|
+
aws_backend_policies = aws.backend_server_descriptions
|
200
|
+
if @backend_policies.sort != aws_backend_policies.sort
|
201
|
+
diffs << LoadBalancerDiff.backend_policies(aws_backend_policies, @backend_policies)
|
202
|
+
end
|
203
|
+
|
204
|
+
aws_attributes = ELB::elb_attributes(@name)
|
205
|
+
|
206
|
+
aws_cross_zone = (aws_attributes.cross_zone_load_balancing.enabled) rescue false
|
207
|
+
if @cross_zone != aws_cross_zone
|
208
|
+
diffs << LoadBalancerDiff.new(LoadBalancerChange::CROSS, aws_cross_zone, @cross_zone)
|
209
|
+
end
|
210
|
+
|
211
|
+
aws_access_log = aws_attributes.access_log
|
212
|
+
if @access_log == false
|
213
|
+
if aws_access_log.enabled == true
|
214
|
+
log_diffs = (AccessLogConfig.new).diff(aws_access_log)
|
215
|
+
diffs << LoadBalancerDiff.access_log(log_diffs)
|
216
|
+
end
|
217
|
+
else
|
218
|
+
log_diffs = @access_log.diff(aws_access_log)
|
219
|
+
if !log_diffs.empty?
|
220
|
+
diffs << LoadBalancerDiff.access_log(log_diffs)
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
aws_connection_draining = if aws_attributes.connection_draining.enabled then aws_attributes.connection_draining.timeout else false end
|
225
|
+
if @connection_draining != aws_connection_draining
|
226
|
+
diffs << LoadBalancerDiff.new(LoadBalancerChange::DRAINING, aws_connection_draining, @connection_draining)
|
227
|
+
end
|
228
|
+
|
229
|
+
aws_idle_timeout = aws_attributes.connection_settings.idle_timeout
|
230
|
+
if @idle_timeout != aws_idle_timeout
|
231
|
+
diffs << LoadBalancerDiff.new(LoadBalancerChange::IDLE, aws_idle_timeout, @idle_timeout)
|
232
|
+
end
|
233
|
+
|
234
|
+
diffs.flatten
|
235
|
+
end
|
236
|
+
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
@@ -0,0 +1,265 @@
|
|
1
|
+
require "common/models/Diff"
|
2
|
+
require "common/models/ListChange"
|
3
|
+
require "elb/models/ListenerDiff"
|
4
|
+
require "util/Colors"
|
5
|
+
|
6
|
+
module Cumulus
|
7
|
+
module ELB
|
8
|
+
# Public: The types of changes that can be made to a load balancer
|
9
|
+
module LoadBalancerChange
|
10
|
+
include Common::DiffChange
|
11
|
+
|
12
|
+
LISTENERS = Common::DiffChange.next_change_id
|
13
|
+
SUBNETS = Common::DiffChange.next_change_id
|
14
|
+
SECURITY = Common::DiffChange.next_change_id
|
15
|
+
INTERNAL = Common::DiffChange.next_change_id
|
16
|
+
TAGS = Common::DiffChange.next_change_id
|
17
|
+
INSTANCES = Common::DiffChange.next_change_id
|
18
|
+
HEALTH = Common::DiffChange.next_change_id
|
19
|
+
BACKEND = Common::DiffChange.next_change_id
|
20
|
+
CROSS = Common::DiffChange.next_change_id
|
21
|
+
LOG = Common::DiffChange.next_change_id
|
22
|
+
DRAINING = Common::DiffChange.next_change_id
|
23
|
+
IDLE = Common::DiffChange.next_change_id
|
24
|
+
end
|
25
|
+
|
26
|
+
# Public: Represents a single difference between local configuration and
|
27
|
+
# an AWS Load Balancer.
|
28
|
+
class LoadBalancerDiff < Common::Diff
|
29
|
+
include LoadBalancerChange
|
30
|
+
|
31
|
+
attr_accessor :listeners
|
32
|
+
attr_accessor :subnets
|
33
|
+
attr_accessor :security_groups
|
34
|
+
attr_accessor :tags
|
35
|
+
attr_accessor :instances
|
36
|
+
attr_accessor :health_diffs
|
37
|
+
attr_accessor :backend_policies
|
38
|
+
attr_accessor :log_diffs
|
39
|
+
|
40
|
+
def self.listeners(aws, local)
|
41
|
+
# map listeners to load balancer port
|
42
|
+
aws_listeners = Hash[aws.map { |l| [l.listener.load_balancer_port, l] }]
|
43
|
+
local_listeners = Hash[local.map { |l| [l.load_balancer_port, l] }]
|
44
|
+
|
45
|
+
added_listeners = local_listeners.reject { |k, v| aws_listeners.has_key? k }
|
46
|
+
removed_listeners = aws_listeners.reject { |k, v| local_listeners.has_key? k }
|
47
|
+
modified_listeners = local_listeners.select { |k, v| aws_listeners.has_key? k }
|
48
|
+
|
49
|
+
added_diffs = Hash[added_listeners.map { |port, added| [port, ListenerDiff.added(added)] }]
|
50
|
+
removed_diffs = Hash[removed_listeners.map { |port, removed| [port, ListenerDiff.unmanaged(removed)] }]
|
51
|
+
modified_diffs = Hash[modified_listeners.map do |port, modified|
|
52
|
+
[port, modified.diff(aws_listeners[port])]
|
53
|
+
end].reject { |k, v| v.empty? }
|
54
|
+
|
55
|
+
if !added_diffs.empty? or !removed_diffs.empty? or !modified_diffs.empty?
|
56
|
+
diff = LoadBalancerDiff.new(LISTENERS, aws, local)
|
57
|
+
diff.listeners = Common::ListChange.new(added_diffs, removed_diffs, modified_diffs)
|
58
|
+
diff
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def self.subnets(aws, local)
|
63
|
+
local_ids = local.map { |s| s.subnet_id }
|
64
|
+
aws_ids = aws.map { |s| s.subnet_id }
|
65
|
+
|
66
|
+
added = local.reject { |s| aws_ids.include? s.subnet_id }
|
67
|
+
removed = aws.reject { |s| local_ids.include? s.subnet_id }
|
68
|
+
diff = LoadBalancerDiff.new(SUBNETS, aws, local)
|
69
|
+
diff.subnets = Common::ListChange.new(added, removed)
|
70
|
+
diff
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.security_groups(aws, local)
|
74
|
+
added = local - aws
|
75
|
+
removed = aws - local
|
76
|
+
diff = LoadBalancerDiff.new(SECURITY, aws, local)
|
77
|
+
diff.security_groups = Common::ListChange.new(added, removed)
|
78
|
+
diff
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.internal(aws, local)
|
82
|
+
LoadBalancerDiff.new(INTERNAL, aws, local)
|
83
|
+
end
|
84
|
+
|
85
|
+
TagChange = Struct.new(:key, :aws, :local)
|
86
|
+
def self.tags(aws, local)
|
87
|
+
added = []
|
88
|
+
removed = []
|
89
|
+
modified = []
|
90
|
+
|
91
|
+
aws.each_pair do |key, val|
|
92
|
+
if local.has_key?(key)
|
93
|
+
if local[key] != val
|
94
|
+
modified << TagChange.new(key, val, local[key])
|
95
|
+
end
|
96
|
+
else
|
97
|
+
removed << TagChange.new(key, val, nil)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
local.each_pair do |key, val|
|
102
|
+
if !aws.has_key?(key)
|
103
|
+
added << TagChange.new(key, nil, val)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
diff = LoadBalancerDiff.new(TAGS, aws, local)
|
108
|
+
diff.tags = Common::ListChange.new(added, removed, modified)
|
109
|
+
diff
|
110
|
+
end
|
111
|
+
|
112
|
+
def self.instances(aws, local)
|
113
|
+
added = local - aws
|
114
|
+
removed = aws - local
|
115
|
+
diff = LoadBalancerDiff.new(INSTANCES, aws, local)
|
116
|
+
diff.instances = Common::ListChange.new(added, removed)
|
117
|
+
diff
|
118
|
+
end
|
119
|
+
|
120
|
+
def self.health_check(health_diffs)
|
121
|
+
diff = LoadBalancerDiff.new(HEALTH, nil, nil)
|
122
|
+
diff.health_diffs = health_diffs
|
123
|
+
diff
|
124
|
+
end
|
125
|
+
|
126
|
+
BackendChange = Struct.new(:port, :aws_policies, :local_policies)
|
127
|
+
def self.backend_policies(aws, local)
|
128
|
+
# map the aws and local policies to their ports
|
129
|
+
aws_backends = Hash[aws.map { |b| [b.instance_port, b.policy_names] }]
|
130
|
+
local_backends = Hash[local.map { |b| [b.instance_port, b.policy_names] }]
|
131
|
+
|
132
|
+
added = local_backends.reject { |port, _| aws_backends.has_key? port }.map do |port, policies|
|
133
|
+
BackendChange.new(port, nil, policies)
|
134
|
+
end
|
135
|
+
removed = aws_backends.reject { |port, _| local_backends.has_key? port }.map do |port, policies|
|
136
|
+
BackendChange.new(port, policies, nil)
|
137
|
+
end
|
138
|
+
modified = local_backends.reject { |port, _| !aws_backends.has_key? port }.map do |port, policies|
|
139
|
+
if aws_backends[port].sort != policies.sort
|
140
|
+
BackendChange.new(port, aws_backends[port], policies)
|
141
|
+
end
|
142
|
+
end.reject(&:nil?)
|
143
|
+
|
144
|
+
diff = LoadBalancerDiff.new(BACKEND, aws, local)
|
145
|
+
diff.backend_policies = Common::ListChange.new(added, removed, modified)
|
146
|
+
diff
|
147
|
+
end
|
148
|
+
|
149
|
+
def self.access_log(log_diffs)
|
150
|
+
diff = LoadBalancerDiff.new(LOG, nil, nil)
|
151
|
+
diff.log_diffs = log_diffs
|
152
|
+
diff
|
153
|
+
end
|
154
|
+
|
155
|
+
def asset_type
|
156
|
+
"Load Balancer"
|
157
|
+
end
|
158
|
+
|
159
|
+
def aws_name
|
160
|
+
@aws.load_balancer_name
|
161
|
+
end
|
162
|
+
|
163
|
+
def diff_string
|
164
|
+
case @type
|
165
|
+
when LISTENERS
|
166
|
+
[
|
167
|
+
"listeners:",
|
168
|
+
@listeners.removed.map { |_, diff| "\t#{diff}" },
|
169
|
+
@listeners.added.map { |_, diff| "\t#{diff}" },
|
170
|
+
@listeners.modified.map do |port, diffs|
|
171
|
+
[
|
172
|
+
"\tListener for port #{port}:",
|
173
|
+
diffs.map do |diff|
|
174
|
+
diff.to_s.lines.map { |l| "\t\t#{l}".chomp("\n") }
|
175
|
+
end
|
176
|
+
].join("\n")
|
177
|
+
end
|
178
|
+
].flatten.join("\n")
|
179
|
+
when SUBNETS
|
180
|
+
[
|
181
|
+
"subnets:",
|
182
|
+
@subnets.removed.map { |s| Colors.removed("\t#{s.subnet_id} (#{s.name})") },
|
183
|
+
@subnets.added.map { |s| Colors.added("\t#{s.subnet_id} (#{s.name})") },
|
184
|
+
].flatten.join("\n")
|
185
|
+
when SECURITY
|
186
|
+
[
|
187
|
+
"security groups:",
|
188
|
+
@security_groups.removed.map { |s| Colors.removed("\t#{s}") },
|
189
|
+
@security_groups.added.map { |s| Colors.added("\t#{s}") },
|
190
|
+
].flatten.join("\n")
|
191
|
+
when INTERNAL
|
192
|
+
[
|
193
|
+
"internal:",
|
194
|
+
Colors.aws_changes("\tAWS - #{aws}"),
|
195
|
+
Colors.local_changes("\tLocal - #{local}"),
|
196
|
+
].join("\n")
|
197
|
+
when TAGS
|
198
|
+
[
|
199
|
+
"tags:",
|
200
|
+
@tags.removed.map { |t| Colors.removed("\t#{t.key}: #{t.aws}") },
|
201
|
+
@tags.added.map { |t| Colors.added("\t#{t.key}: #{t.local}") },
|
202
|
+
@tags.modified.map do |t|
|
203
|
+
[
|
204
|
+
"\t#{t.key}:",
|
205
|
+
Colors.aws_changes("(AWS) #{t.aws}"),
|
206
|
+
Colors.local_changes("(Local) #{t.local}")
|
207
|
+
].join(" ")
|
208
|
+
end
|
209
|
+
].flatten.join("\n")
|
210
|
+
when INSTANCES
|
211
|
+
[
|
212
|
+
"managed instances:",
|
213
|
+
@instances.removed.map { |i| Colors.removed("\t#{i}") },
|
214
|
+
@instances.added.map { |i| Colors.added("\t#{i}") },
|
215
|
+
].flatten.join("\n")
|
216
|
+
when HEALTH
|
217
|
+
[
|
218
|
+
"health check:",
|
219
|
+
@health_diffs.map do |d|
|
220
|
+
d.to_s.lines.map { |l| "\t#{l}".chomp("\n") }
|
221
|
+
end
|
222
|
+
].join("\n")
|
223
|
+
when BACKEND
|
224
|
+
[
|
225
|
+
"backend policies:",
|
226
|
+
@backend_policies.removed.map { |bc| Colors.removed("\tinstance port #{bc.port}: #{bc.aws_policies.join(" ")}") },
|
227
|
+
@backend_policies.added.map { |bc| Colors.added("\tinstance port #{bc.port}: #{bc.local_policies.join(" ")}") },
|
228
|
+
@backend_policies.modified.map do |bc|
|
229
|
+
[
|
230
|
+
"\tinstance port #{bc.port}:",
|
231
|
+
(bc.aws_policies - bc.local_policies).map { |p| Colors.removed("#{p}") },
|
232
|
+
(bc.local_policies - bc.aws_policies).map { |p| Colors.added("#{p}") },
|
233
|
+
].flatten.join(" ")
|
234
|
+
end
|
235
|
+
].flatten.join("\n")
|
236
|
+
when CROSS
|
237
|
+
[
|
238
|
+
"cross zone load balancing:",
|
239
|
+
Colors.aws_changes("\tAWS - #{aws}"),
|
240
|
+
Colors.local_changes("\tLocal - #{local}"),
|
241
|
+
].flatten.join("\n")
|
242
|
+
when LOG
|
243
|
+
[
|
244
|
+
"access log:",
|
245
|
+
@log_diffs.map do |d|
|
246
|
+
d.to_s.lines.map { |l| "\t#{l}".chomp("\n") }
|
247
|
+
end
|
248
|
+
].join("\n")
|
249
|
+
when DRAINING
|
250
|
+
[
|
251
|
+
"connection draining:",
|
252
|
+
Colors.aws_changes("\tAWS - #{aws}"),
|
253
|
+
Colors.local_changes("\tLocal - #{local}"),
|
254
|
+
].join("\n")
|
255
|
+
when IDLE
|
256
|
+
[
|
257
|
+
"idle timeout:",
|
258
|
+
Colors.aws_changes("\tAWS - #{aws}"),
|
259
|
+
Colors.local_changes("\tLocal - #{local}"),
|
260
|
+
].join("\n")
|
261
|
+
end
|
262
|
+
end
|
263
|
+
end
|
264
|
+
end
|
265
|
+
end
|