cumulus-aws 0.11.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (173) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +3 -0
  3. data/.travis.yml +12 -0
  4. data/Gemfile +4 -0
  5. data/Gemfile.lock +29 -0
  6. data/LICENSE +202 -0
  7. data/README.md +41 -0
  8. data/autocomplete +137 -0
  9. data/bin/cumulus +658 -0
  10. data/cumulus +2 -0
  11. data/cumulus-aws.gemspec +20 -0
  12. data/lib/autoscaling/AutoScaling.rb +40 -0
  13. data/lib/autoscaling/loader/Loader.rb +56 -0
  14. data/lib/autoscaling/manager/Manager.rb +360 -0
  15. data/lib/autoscaling/models/AlarmConfig.rb +165 -0
  16. data/lib/autoscaling/models/AlarmDiff.rb +172 -0
  17. data/lib/autoscaling/models/AutoScalingDiff.rb +178 -0
  18. data/lib/autoscaling/models/GroupConfig.rb +330 -0
  19. data/lib/autoscaling/models/PolicyConfig.rb +135 -0
  20. data/lib/autoscaling/models/PolicyDiff.rb +73 -0
  21. data/lib/autoscaling/models/ScheduledActionDiff.rb +53 -0
  22. data/lib/autoscaling/models/ScheduledConfig.rb +96 -0
  23. data/lib/aws_extensions/ec2/DhcpOptions.rb +41 -0
  24. data/lib/aws_extensions/ec2/Instance.rb +29 -0
  25. data/lib/aws_extensions/ec2/NetworkAcl.rb +25 -0
  26. data/lib/aws_extensions/ec2/NetworkInterface.rb +14 -0
  27. data/lib/aws_extensions/ec2/RouteTable.rb +26 -0
  28. data/lib/aws_extensions/ec2/SecurityGroup.rb +16 -0
  29. data/lib/aws_extensions/ec2/Subnet.rb +28 -0
  30. data/lib/aws_extensions/ec2/Volume.rb +24 -0
  31. data/lib/aws_extensions/ec2/Vpc.rb +14 -0
  32. data/lib/aws_extensions/ec2/VpcEndpoint.rb +11 -0
  33. data/lib/aws_extensions/elb/BackendServerDescription.rb +12 -0
  34. data/lib/aws_extensions/elb/PolicyDescription.rb +14 -0
  35. data/lib/aws_extensions/kinesis/StreamDescription.rb +12 -0
  36. data/lib/aws_extensions/route53/AliasTarget.rb +21 -0
  37. data/lib/aws_extensions/s3/Bucket.rb +33 -0
  38. data/lib/aws_extensions/s3/BucketAcl.rb +28 -0
  39. data/lib/aws_extensions/s3/BucketCors.rb +17 -0
  40. data/lib/aws_extensions/s3/BucketLifecycle.rb +21 -0
  41. data/lib/aws_extensions/s3/BucketLogging.rb +18 -0
  42. data/lib/aws_extensions/s3/BucketNotification.rb +23 -0
  43. data/lib/aws_extensions/s3/BucketPolicy.rb +18 -0
  44. data/lib/aws_extensions/s3/BucketTagging.rb +15 -0
  45. data/lib/aws_extensions/s3/BucketVersioning.rb +14 -0
  46. data/lib/aws_extensions/s3/BucketWebsite.rb +49 -0
  47. data/lib/aws_extensions/s3/CORSRule.rb +27 -0
  48. data/lib/aws_extensions/s3/ReplicationConfiguration.rb +22 -0
  49. data/lib/cloudfront/CloudFront.rb +83 -0
  50. data/lib/cloudfront/loader/Loader.rb +31 -0
  51. data/lib/cloudfront/manager/Manager.rb +183 -0
  52. data/lib/cloudfront/models/CacheBehaviorConfig.rb +237 -0
  53. data/lib/cloudfront/models/CacheBehaviorDiff.rb +211 -0
  54. data/lib/cloudfront/models/CustomOriginConfig.rb +51 -0
  55. data/lib/cloudfront/models/CustomOriginDiff.rb +74 -0
  56. data/lib/cloudfront/models/DistributionConfig.rb +183 -0
  57. data/lib/cloudfront/models/DistributionDiff.rb +131 -0
  58. data/lib/cloudfront/models/InvalidationConfig.rb +37 -0
  59. data/lib/cloudfront/models/OriginConfig.rb +144 -0
  60. data/lib/cloudfront/models/OriginDiff.rb +86 -0
  61. data/lib/cloudfront/models/OriginSslProtocols.rb +28 -0
  62. data/lib/cloudfront/models/OriginSslProtocolsDiff.rb +39 -0
  63. data/lib/common/BaseLoader.rb +80 -0
  64. data/lib/common/manager/Manager.rb +148 -0
  65. data/lib/common/models/Diff.rb +114 -0
  66. data/lib/common/models/ListChange.rb +21 -0
  67. data/lib/common/models/TagsDiff.rb +55 -0
  68. data/lib/common/models/UTCTimeSource.rb +17 -0
  69. data/lib/conf/Configuration.rb +365 -0
  70. data/lib/ec2/EC2.rb +503 -0
  71. data/lib/ec2/IPProtocolMapping.rb +165 -0
  72. data/lib/ec2/loaders/EbsLoader.rb +19 -0
  73. data/lib/ec2/loaders/InstanceLoader.rb +32 -0
  74. data/lib/ec2/managers/EbsManager.rb +176 -0
  75. data/lib/ec2/managers/InstanceManager.rb +509 -0
  76. data/lib/ec2/models/EbsGroupConfig.rb +133 -0
  77. data/lib/ec2/models/EbsGroupDiff.rb +48 -0
  78. data/lib/ec2/models/InstanceConfig.rb +202 -0
  79. data/lib/ec2/models/InstanceDiff.rb +95 -0
  80. data/lib/elb/ELB.rb +148 -0
  81. data/lib/elb/loader/Loader.rb +65 -0
  82. data/lib/elb/manager/Manager.rb +581 -0
  83. data/lib/elb/models/AccessLogConfig.rb +82 -0
  84. data/lib/elb/models/AccessLogDiff.rb +47 -0
  85. data/lib/elb/models/HealthCheckConfig.rb +91 -0
  86. data/lib/elb/models/HealthCheckDiff.rb +50 -0
  87. data/lib/elb/models/ListenerConfig.rb +99 -0
  88. data/lib/elb/models/ListenerDiff.rb +91 -0
  89. data/lib/elb/models/LoadBalancerConfig.rb +239 -0
  90. data/lib/elb/models/LoadBalancerDiff.rb +265 -0
  91. data/lib/iam/IAM.rb +36 -0
  92. data/lib/iam/loader/Loader.rb +117 -0
  93. data/lib/iam/manager/IamGroups.rb +98 -0
  94. data/lib/iam/manager/IamResource.rb +288 -0
  95. data/lib/iam/manager/IamRoles.rb +112 -0
  96. data/lib/iam/manager/IamUsers.rb +54 -0
  97. data/lib/iam/manager/Manager.rb +29 -0
  98. data/lib/iam/migration/AssumeRoleUnifier.rb +34 -0
  99. data/lib/iam/migration/PolicyUnifier.rb +90 -0
  100. data/lib/iam/models/GroupConfig.rb +40 -0
  101. data/lib/iam/models/IamDiff.rb +132 -0
  102. data/lib/iam/models/PolicyConfig.rb +67 -0
  103. data/lib/iam/models/ResourceWithPolicy.rb +208 -0
  104. data/lib/iam/models/RoleConfig.rb +53 -0
  105. data/lib/iam/models/StatementConfig.rb +35 -0
  106. data/lib/iam/models/UserConfig.rb +21 -0
  107. data/lib/kinesis/Kinesis.rb +94 -0
  108. data/lib/kinesis/loader/Loader.rb +19 -0
  109. data/lib/kinesis/manager/Manager.rb +206 -0
  110. data/lib/kinesis/models/StreamConfig.rb +75 -0
  111. data/lib/kinesis/models/StreamDiff.rb +58 -0
  112. data/lib/lambda/Lambda.rb +41 -0
  113. data/lib/route53/loader/Loader.rb +32 -0
  114. data/lib/route53/manager/Manager.rb +241 -0
  115. data/lib/route53/models/AliasTarget.rb +86 -0
  116. data/lib/route53/models/RecordConfig.rb +178 -0
  117. data/lib/route53/models/RecordDiff.rb +140 -0
  118. data/lib/route53/models/Vpc.rb +24 -0
  119. data/lib/route53/models/ZoneConfig.rb +156 -0
  120. data/lib/route53/models/ZoneDiff.rb +118 -0
  121. data/lib/s3/S3.rb +89 -0
  122. data/lib/s3/loader/Loader.rb +66 -0
  123. data/lib/s3/manager/Manager.rb +296 -0
  124. data/lib/s3/models/BucketConfig.rb +321 -0
  125. data/lib/s3/models/BucketDiff.rb +167 -0
  126. data/lib/s3/models/GrantConfig.rb +189 -0
  127. data/lib/s3/models/GrantDiff.rb +50 -0
  128. data/lib/s3/models/LifecycleConfig.rb +142 -0
  129. data/lib/s3/models/LifecycleDiff.rb +46 -0
  130. data/lib/s3/models/LoggingConfig.rb +81 -0
  131. data/lib/s3/models/NotificationConfig.rb +157 -0
  132. data/lib/s3/models/NotificationDiff.rb +62 -0
  133. data/lib/s3/models/ReplicationConfig.rb +133 -0
  134. data/lib/s3/models/ReplicationDiff.rb +60 -0
  135. data/lib/s3/models/WebsiteConfig.rb +107 -0
  136. data/lib/security/SecurityGroups.rb +39 -0
  137. data/lib/security/loader/Loader.rb +94 -0
  138. data/lib/security/manager/Manager.rb +246 -0
  139. data/lib/security/models/RuleConfig.rb +161 -0
  140. data/lib/security/models/RuleDiff.rb +72 -0
  141. data/lib/security/models/RuleMigration.rb +127 -0
  142. data/lib/security/models/SecurityGroupConfig.rb +172 -0
  143. data/lib/security/models/SecurityGroupDiff.rb +112 -0
  144. data/lib/sns/SNS.rb +40 -0
  145. data/lib/sqs/SQS.rb +62 -0
  146. data/lib/sqs/loader/Loader.rb +34 -0
  147. data/lib/sqs/manager/Manager.rb +128 -0
  148. data/lib/sqs/models/DeadLetterConfig.rb +70 -0
  149. data/lib/sqs/models/DeadLetterDiff.rb +35 -0
  150. data/lib/sqs/models/QueueConfig.rb +115 -0
  151. data/lib/sqs/models/QueueDiff.rb +89 -0
  152. data/lib/util/Colors.rb +111 -0
  153. data/lib/util/StatusCodes.rb +51 -0
  154. data/lib/vpc/loader/Loader.rb +73 -0
  155. data/lib/vpc/manager/Manager.rb +954 -0
  156. data/lib/vpc/models/AclEntryConfig.rb +150 -0
  157. data/lib/vpc/models/AclEntryDiff.rb +54 -0
  158. data/lib/vpc/models/DhcpConfig.rb +100 -0
  159. data/lib/vpc/models/DhcpDiff.rb +90 -0
  160. data/lib/vpc/models/EndpointConfig.rb +76 -0
  161. data/lib/vpc/models/EndpointDiff.rb +69 -0
  162. data/lib/vpc/models/NetworkAclConfig.rb +87 -0
  163. data/lib/vpc/models/NetworkAclDiff.rb +116 -0
  164. data/lib/vpc/models/RouteConfig.rb +82 -0
  165. data/lib/vpc/models/RouteDiff.rb +50 -0
  166. data/lib/vpc/models/RouteTableConfig.rb +92 -0
  167. data/lib/vpc/models/RouteTableDiff.rb +101 -0
  168. data/lib/vpc/models/SubnetConfig.rb +113 -0
  169. data/lib/vpc/models/SubnetDiff.rb +78 -0
  170. data/lib/vpc/models/VpcConfig.rb +173 -0
  171. data/lib/vpc/models/VpcDiff.rb +315 -0
  172. data/rakefile.rb +8 -0
  173. metadata +245 -0
@@ -0,0 +1,165 @@
1
+ require "autoscaling/models/AlarmDiff"
2
+
3
+ module Cumulus
4
+ module AutoScaling
5
+ # Public: A class that encapsulates data about configuration for an autoscaling
6
+ # Cloudwatch alarm.
7
+ #
8
+ # The action to be taken is inferred to be activating the policy that contains
9
+ # the alarm. As such, we don't keep arrays of actions to take when various alarm
10
+ # states are triggered. We just apply the action (activating the policy) to the
11
+ # states contained in the `action_states` array. Valid values are "alarm", "ok",
12
+ # and "insufficient-data".
13
+ class AlarmConfig
14
+ attr_reader :action_states
15
+ attr_reader :actions_enabled
16
+ attr_reader :comparison
17
+ attr_reader :description
18
+ attr_reader :dimensions
19
+ attr_reader :evaluation_periods
20
+ attr_reader :metric
21
+ attr_reader :name
22
+ attr_reader :namespace
23
+ attr_reader :period
24
+ attr_reader :statistic
25
+ attr_reader :threshold
26
+ attr_reader :unit
27
+
28
+ # Public: Constructor
29
+ #
30
+ # json - a hash containing the JSON configuration for the alarm
31
+ def initialize(json = nil)
32
+ if !json.nil?
33
+ @action_states = json["action-states"]
34
+ @actions_enabled = json["actions-enabled"]
35
+ @comparison = json["comparison"]
36
+ @description = json["description"]
37
+ @dimensions = json["dimensions"]
38
+ @evaluation_periods = json["evaluation-periods"]
39
+ @metric = json["metric"]
40
+ @name = json["name"]
41
+ @namespace = json["namespace"]
42
+ @period = json["period-seconds"]
43
+ @statistic = json["statistic"]
44
+ @threshold = json["threshold"]
45
+ @unit = json["unit"]
46
+ end
47
+ end
48
+
49
+ # Public: Get the configuration as a hash
50
+ #
51
+ # Returns the hash
52
+ def hash
53
+ {
54
+ "name" => @name,
55
+ "action-states" => @action_states,
56
+ "actions-enabled" => @actions_enabled,
57
+ "comparison" => @comparison,
58
+ "description" => @description,
59
+ "dimensions" => @dimensions,
60
+ "evaluation-periods" => @evaluation_periods,
61
+ "metric" => @metric,
62
+ "namespace" => @namespace,
63
+ "period-seconds" => @period,
64
+ "statistic" => @statistic,
65
+ "threshold" => @threshold,
66
+ "unit" => @unit
67
+ }.reject { |k, v| v.nil? }
68
+ end
69
+
70
+ # Public: Populate the AlarmConfig from an existing AWS cloudwatch alarm
71
+ #
72
+ # policy_arn - the arn of the policy the alarm should be attached to
73
+ # resource - the aws resource to populate from
74
+ def populate(policy_arn, resource)
75
+ action_states = []
76
+ if resource.ok_actions.include?(policy_arn) then action_states << "ok" end
77
+ if resource.alarm_actions.include?(policy_arn) then action_states << "alarm" end
78
+ if resource.insufficient_data_actions.include?(policy_arn) then action_states << "insufficient-data" end
79
+
80
+ @action_states = action_states
81
+ @actions_enabled = resource.actions_enabled
82
+ @comparison = resource.comparison_operator
83
+ @description = resource.alarm_description
84
+ @dimensions = Hash[resource.dimensions.map { |d| [d.name, d.value] }]
85
+ @evaluation_periods = resource.evaluation_periods
86
+ @metric = resource.metric_name
87
+ @name = resource.alarm_name
88
+ @namespace = resource.namespace
89
+ @period = resource.period
90
+ @statistic = resource.statistic
91
+ @threshold = resource.threshold
92
+ @unit = resource.unit
93
+ end
94
+
95
+ # Public: Produce the differences between this local configuration and the
96
+ # configuration in AWS
97
+ #
98
+ # aws - the alarm in AWS
99
+ # policy_arn - the policy arn is the action this alarm should take
100
+ #
101
+ # Returns an array of AlarmDiff objects representing the differences
102
+ def diff(aws, policy_arn)
103
+ diffs = []
104
+
105
+ if @description != aws.alarm_description
106
+ diffs << AlarmDiff.new(AlarmChange::DESCRIPTION, aws, self)
107
+ end
108
+ if @actions_enabled != aws.actions_enabled
109
+ diffs << AlarmDiff.new(AlarmChange::ENABLED, aws, self)
110
+ end
111
+ if @comparison != aws.comparison_operator
112
+ diffs << AlarmDiff.new(AlarmChange::COMPARISON, aws, self)
113
+ end
114
+ if @evaluation_periods != aws.evaluation_periods
115
+ diffs << AlarmDiff.new(AlarmChange::EVALUATION, aws, self)
116
+ end
117
+ if @metric != aws.metric_name
118
+ diffs << AlarmDiff.new(AlarmChange::METRIC, aws, self)
119
+ end
120
+ if @namespace != aws.namespace
121
+ diffs << AlarmDiff.new(AlarmChange::NAMESPACE, aws, self)
122
+ end
123
+ if @period != aws.period
124
+ diffs << AlarmDiff.new(AlarmChange::PERIOD, aws, self)
125
+ end
126
+ if @statistic != aws.statistic
127
+ diffs << AlarmDiff.new(AlarmChange::STATISTIC, aws, self)
128
+ end
129
+ if @threshold != aws.threshold
130
+ diffs << AlarmDiff.new(AlarmChange::THRESHOLD, aws, self)
131
+ end
132
+ if @unit != aws.unit
133
+ diffs << AlarmDiff.new(AlarmChange::UNIT, aws, self)
134
+ end
135
+ aws_dimensions = Hash[aws.dimensions.map { |d| [d.name, d.value] }]
136
+ if @dimensions != aws_dimensions
137
+ diffs << AlarmDiff.new(AlarmChange::DIMENSIONS, aws, self)
138
+ end
139
+
140
+ ["ok", "alarm", "insufficient-data"].each do |state|
141
+ case state
142
+ when "ok"
143
+ actions = aws.ok_actions
144
+ change_type = AlarmChange::OK
145
+ when "alarm"
146
+ actions = aws.alarm_actions
147
+ change_type = AlarmChange::ALARM
148
+ when "insufficient-data"
149
+ actions = aws.insufficient_data_actions
150
+ change_type = AlarmChange::INSUFFICIENT
151
+ end
152
+
153
+ if (!@action_states.include?(state) and actions.size != 0) or
154
+ (@action_states.include?(state) and (actions.size != 1 or actions[0] != policy_arn))
155
+ diff = AlarmDiff.new(change_type, aws, self)
156
+ diff.policy_arn = policy_arn
157
+ diffs << diff
158
+ end
159
+ end
160
+
161
+ diffs
162
+ end
163
+ end
164
+ end
165
+ end
@@ -0,0 +1,172 @@
1
+ require "common/models/Diff"
2
+ require "util/Colors"
3
+
4
+ module Cumulus
5
+ module AutoScaling
6
+ # Public: The types of changes that can be made to alarms
7
+ module AlarmChange
8
+ include Common::DiffChange
9
+
10
+ ALARM = Common::DiffChange::next_change_id
11
+ COMPARISON = Common::DiffChange::next_change_id
12
+ DESCRIPTION = Common::DiffChange::next_change_id
13
+ DIMENSIONS = Common::DiffChange::next_change_id
14
+ ENABLED = Common::DiffChange::next_change_id
15
+ EVALUATION = Common::DiffChange::next_change_id
16
+ INSUFFICIENT = Common::DiffChange::next_change_id
17
+ METRIC = Common::DiffChange::next_change_id
18
+ NAMESPACE = Common::DiffChange::next_change_id
19
+ OK = Common::DiffChange::next_change_id
20
+ PERIOD = Common::DiffChange::next_change_id
21
+ STATISTIC = Common::DiffChange::next_change_id
22
+ THRESHOLD = Common::DiffChange::next_change_id
23
+ UNIT = Common::DiffChange::next_change_id
24
+ end
25
+
26
+ # Public: Represents a single difference between local configuration and AWS
27
+ # configuration of Cloudwatch alarms
28
+ class AlarmDiff < Common::Diff
29
+ include AlarmChange
30
+
31
+ attr_accessor :policy_arn
32
+
33
+ def diff_string
34
+ diff_lines = [@local.name]
35
+
36
+ case @type
37
+ when ALARM
38
+ lines = ["\tAlarm actions:"]
39
+ lines << alarm_actions_to_remove.map { |a| "\t\t#{Colors.removed(a)}" }
40
+ lines << alarm_actions_to_add.map { |a| "\t\t#{Colors.added(a)}" }
41
+ diff_lines << lines.flatten.join("\n")
42
+ when COMPARISON
43
+ diff_lines << "\tComparison type: AWS - #{Colors.aws_changes(@aws.comparison_operator)}, Local - #{Colors.local_changes(@local.comparison)}"
44
+ when DESCRIPTION
45
+ diff_lines << [
46
+ "\tDescription:",
47
+ Colors.aws_changes("\t\tAWS - #{@aws.alarm_description}"),
48
+ Colors.local_changes("\t\tLocal - #{@local.description}")
49
+ ].join("\n")
50
+ when DIMENSIONS
51
+ lines = ["\tDimensions:"]
52
+ lines << dimensions_to_remove.map { |d| "\t\t#{Colors.removed(d)}" }
53
+ lines << dimensions_to_add.map { |d| "\t\t#{Colors.added(d)}" }
54
+ diff_lines << lines.flatten.join("\n")
55
+ when ENABLED
56
+ diff_lines << "\tActions enabled: AWS - #{Colors.aws_changes(@aws.actions_enabled)}, Local - #{Colors.local_changes(@local.actions_enabled)}"
57
+ when EVALUATION
58
+ diff_lines << "\tEvaluation periods: AWS - #{Colors.aws_changes(@aws.evaluation_periods)}, Local - #{Colors.local_changes(@local.evaluation_periods)}"
59
+ when INSUFFICIENT
60
+ lines = ["\tInsufficient data actions:"]
61
+ lines << insufficient_actions_to_remove.map { |i| "\t\t#{Colors.removed(i)}" }
62
+ lines << insufficient_actions_to_add.map { |i| "\t\t#{Colors.added(i)}" }
63
+ diff_lines << lines.flatten.join("\n")
64
+ when METRIC
65
+ diff_lines << "\tMetric: AWS - #{Colors.aws_changes(@aws.metric_name)}, Local - #{Colors.local_changes(@local.metric)}"
66
+ when NAMESPACE
67
+ diff_lines << "\tNamespace: AWS - #{Colors.aws_changes(@aws.namespace)}, Local - #{Colors.local_changes(@local.namespace)}"
68
+ when OK
69
+ lines = ["\tOk actions:"]
70
+ lines << ok_actions_to_remove.map { |o| "\t\t#{Colors.removed(o)}" }
71
+ lines << ok_actions_to_add.map { |o| "\t\t#{Colors.added(o)}" }
72
+ diff_lines << lines.flatten.join("\n")
73
+ when PERIOD
74
+ diff_lines << "\tPeriod seconds: AWS - #{Colors.aws_changes(@aws.period)}, Local - #{Colors.local_changes(@local.period)}"
75
+ when STATISTIC
76
+ diff_lines << "\tStatistic: AWS - #{Colors.aws_changes(@aws.statistic)}, Local - #{Colors.local_changes(@local.statistic)}"
77
+ when THRESHOLD
78
+ diff_lines << "\tThreshold: AWS - #{Colors.aws_changes(@aws.threshold)}, Local - #{Colors.local_changes(@local.threshold)}"
79
+ when UNIT
80
+ diff_lines << "\tUnit: AWS - #{Colors.aws_changes(@aws.unit)}, Local - #{Colors.local_changes(@local.unit)}"
81
+ end
82
+
83
+ diff_lines.flatten.join("\n")
84
+ end
85
+
86
+ def asset_type
87
+ "Alarm"
88
+ end
89
+
90
+ def aws_name
91
+ @aws.alarm_name
92
+ end
93
+
94
+ # Public: Get the alarm actions that will be removed
95
+ #
96
+ # Returns an array of arns to remove
97
+ def alarm_actions_to_remove
98
+ @aws.alarm_actions - local_actions("alarm")
99
+ end
100
+
101
+ # Public: Get the alarm actions that will be added
102
+ #
103
+ # Returns an array of arns to add
104
+ def alarm_actions_to_add
105
+ local_actions("alarm") - @aws.alarm_actions
106
+ end
107
+
108
+ # Public: Get the dimensions that will be removed
109
+ #
110
+ # Returns a hash of key value pairs to be removed
111
+ def dimensions_to_remove
112
+ aws_dimensions.reject { |k, v| @local.dimensions.include?(k) and @local.dimensions[k] == v }
113
+ end
114
+
115
+ # Public: Get the dimensions that will be added
116
+ #
117
+ # Returns a hash of key value pairs to add
118
+ def dimensions_to_add
119
+ @local.dimensions.reject { |k, v| aws_dimensions.include?(k) and aws_dimensions[k] == v }
120
+ end
121
+
122
+ # Public: Get the insufficient data actions that will be removed
123
+ #
124
+ # Returns an array of arns to remove
125
+ def insufficient_actions_to_remove
126
+ @aws.insufficient_data_actions - local_actions("insufficient-data")
127
+ end
128
+
129
+ # Public: Get the insufficient data actions that will be added
130
+ #
131
+ # Returns an array of arns to add
132
+ def insufficient_actions_to_add
133
+ local_actions("insufficient-data") - @aws.insufficient_data_actions
134
+ end
135
+
136
+ # Public: Get the ok actions that will be removed
137
+ #
138
+ # Returns an array of arns to remove
139
+ def ok_actions_to_remove
140
+ @aws.ok_actions - local_actions("ok")
141
+ end
142
+
143
+ # Public: Get the ok actions that will be added
144
+ #
145
+ # Returns an array of arns to add
146
+ def ok_actions_to_add
147
+ local_actions("ok") - @aws.ok_actions
148
+ end
149
+
150
+ private
151
+
152
+ # Internal: Get the actions defined locally for a particular state
153
+ #
154
+ # Returns an array of arns
155
+ def local_actions(state)
156
+ local_policies = []
157
+ if @local.action_states.include?(state)
158
+ local_policies << @policy_arn
159
+ end
160
+ local_policies
161
+ end
162
+
163
+ # Internal: Get the AWS dimensions in the same format as local configuration
164
+ #
165
+ # Returns a hash of key value pairs
166
+ def aws_dimensions
167
+ @aws_dimensions ||= Hash[@aws.dimensions.map { |d| [d.name, d.value] }]
168
+ end
169
+
170
+ end
171
+ end
172
+ end
@@ -0,0 +1,178 @@
1
+ require "common/models/Diff"
2
+ require "common/models/TagsDiff"
3
+ require "common/models/ListChange"
4
+ require "util/Colors"
5
+
6
+ module Cumulus
7
+ module AutoScaling
8
+ # Public: The types of changes that can be made to an AutoScaling Group
9
+ module AutoScalingChange
10
+ include Common::DiffChange
11
+
12
+ MIN = Common::DiffChange::next_change_id
13
+ MAX = Common::DiffChange::next_change_id
14
+ DESIRED = Common::DiffChange::next_change_id
15
+ METRICS = Common::DiffChange::next_change_id
16
+ CHECK_TYPE = Common::DiffChange::next_change_id
17
+ CHECK_GRACE = Common::DiffChange::next_change_id
18
+ LOAD_BALANCER = Common::DiffChange::next_change_id
19
+ SUBNETS = Common::DiffChange::next_change_id
20
+ TAGS = Common::DiffChange::next_change_id
21
+ TERMINATION = Common::DiffChange::next_change_id
22
+ COOLDOWN = Common::DiffChange::next_change_id
23
+ LAUNCH = Common::DiffChange::next_change_id
24
+ SCHEDULED = Common::DiffChange::next_change_id
25
+ POLICY = Common::DiffChange::next_change_id
26
+ end
27
+
28
+ # Public: Represents a single difference between local configuration and AWS
29
+ # configuration of AutoScaling Groups
30
+ class AutoScalingDiff < Common::Diff
31
+ include AutoScalingChange
32
+ include Common::TagsDiff
33
+
34
+ attr_accessor :policy_diffs
35
+
36
+ # Public: Static method that will produce a diff that contains changes in
37
+ # scheduled actions
38
+ #
39
+ # aws - the array of AWS scheduled actions
40
+ # local - the map of scheduled action name to local configuration
41
+ #
42
+ # Returns the AutoScalingDiff
43
+ def AutoScalingDiff.scheduled(aws, local)
44
+ aws_scheduled = Hash[aws.map { |s| [s.scheduled_action_name, s] }]
45
+
46
+ removed = aws_scheduled.reject { |k, v| local.include?(k) }.map { |_, sched| ScheduledActionDiff.unmanaged(sched) }
47
+ added = local.reject { |k, v| aws_scheduled.include? k }.map { |_, sched| ScheduledActionDiff.added(sched) }
48
+ modified = local.select { |k, v| aws_scheduled.include? k }.map do |name, local_sched|
49
+ aws_sched = aws_scheduled[name]
50
+ sched_diffs = local_sched.diff(aws_sched)
51
+
52
+ if !sched_diffs.empty?
53
+ ScheduledActionDiff.modified(aws_sched, local_sched, sched_diffs)
54
+ end
55
+ end.reject { |v| !v }
56
+
57
+ if !removed.empty? or !added.empty? or !modified.empty?
58
+ diff = AutoScalingDiff.new(AutoScalingChange::SCHEDULED, aws, local)
59
+ diff.changes = Common::ListChange.new(added, removed, modified)
60
+ diff
61
+ end
62
+ end
63
+
64
+ # Public: Static method that will produce a diff that contains changes in
65
+ # scaling policies
66
+ #
67
+ # local - the local configuration
68
+ # policy_diffs - the differences in scaling policies
69
+ #
70
+ # Returns the diff
71
+ def AutoScalingDiff.policies(local, policy_diffs)
72
+ diff = AutoScalingDiff.new(POLICY, nil, local)
73
+ diff.policy_diffs = policy_diffs
74
+ diff
75
+ end
76
+
77
+ def diff_string
78
+ case @type
79
+ when LAUNCH
80
+ "Launch configuration: AWS - #{Colors.aws_changes(@aws.launch_configuration_name)}, Local - #{Colors.local_changes(@local.launch)}"
81
+ when MIN
82
+ "Min size: AWS - #{Colors.aws_changes(@aws)}, Local - #{Colors.local_changes(@local)}"
83
+ when MAX
84
+ "Max size: AWS - #{Colors.aws_changes(@aws)}, Local - #{Colors.local_changes(@local)}"
85
+ when DESIRED
86
+ "Desired size: AWS - #{Colors.aws_changes(@aws)}, Local - #{Colors.local_changes(@local)}"
87
+ when METRICS
88
+ lines = ["Enabled Metrics:"]
89
+ lines << metrics_to_disable.map { |m| "\t#{Colors.removed(m)}" }
90
+ lines << metrics_to_enable.map { |m| "\t#{Colors.added(m)}" }
91
+ lines.flatten.join("\n")
92
+ when CHECK_TYPE
93
+ "Health check type: AWS - #{Colors.aws_changes(@aws.health_check_type)}, Local - #{Colors.local_changes(@local.check_type)}"
94
+ when CHECK_GRACE
95
+ "Health check grace period: AWS - #{Colors.aws_changes(@aws.health_check_grace_period)}, Local - #{Colors.local_changes(@local.check_grace)}"
96
+ when LOAD_BALANCER
97
+ lines = ["Load balancers:"]
98
+ lines << load_balancers_to_remove.map { |l| "\t#{Colors.removed(l)}" }
99
+ lines << load_balancers_to_add.map { |l| "\t#{Colors.added(l)}" }
100
+ lines.flatten.join("\n")
101
+ when SUBNETS
102
+ lines = ["Subnets:"]
103
+ lines << (@aws - @local).map { |s| s.vpc_subnet_name || s.subnet_id }.map { |s| "\t#{Colors.removed(s)}" }
104
+ lines << (@local - @aws).map { |s| s.vpc_subnet_name || s.subnet_id }.map { |s| "\t#{Colors.added(s)}" }
105
+ lines.flatten.join("\n")
106
+ when TAGS
107
+ tags_diff_string
108
+ when TERMINATION
109
+ lines = ["Termination policies:"]
110
+ lines << (@aws.termination_policies - @local.termination).map { |t| "\t#{Colors.removed(t)}" }
111
+ lines << (@local.termination - @aws.termination_policies).map { |t| "\t#{Colors.added(t)}" }
112
+ lines.flatten.join("\n")
113
+ when COOLDOWN
114
+ "Cooldown: AWS - #{Colors.aws_changes(@aws.default_cooldown)}, Local - #{Colors.local_changes(@local.cooldown)}"
115
+ when SCHEDULED
116
+ [
117
+ "Scheduled Actions:",
118
+ changes.removed.map { |added_diff| "\t#{added_diff}" },
119
+ changes.added.map { |removed_diff| "\t#{removed_diff}" },
120
+ changes.modified.map do |modified_diff|
121
+ [
122
+ "\t#{modified_diff.local.name}:",
123
+ modified_diff.changes.map do |scheduled_diff|
124
+ scheduled_diff.to_s.lines.map { |l| "\t\t#{l}".chomp("\n") }
125
+ end
126
+ ]
127
+ end
128
+ ].flatten.join("\n")
129
+ when POLICY
130
+ lines = ["Scaling policies:"]
131
+ lines << policy_diffs.map { |d| "\t#{d}" }
132
+ lines.flatten.join("\n")
133
+ end
134
+ end
135
+
136
+ def asset_type
137
+ "Autoscaling group"
138
+ end
139
+
140
+ def aws_name
141
+ @aws.auto_scaling_group_name
142
+ end
143
+
144
+ # Public: Get the metrics to disable, ie. are in AWS but not in local
145
+ # configuration.
146
+ #
147
+ # Returns an array of metrics
148
+ def metrics_to_disable
149
+ @aws.enabled_metrics - @local.enabled_metrics
150
+ end
151
+
152
+ # Public: Get the metrics to enable, ie. are in local configuration, but not
153
+ # AWS.
154
+ #
155
+ # Returns an array of metrics
156
+ def metrics_to_enable
157
+ @local.enabled_metrics - @aws.enabled_metrics
158
+ end
159
+
160
+ # Public: Get the load balancers to remove, ie. are in AWS and not local
161
+ # configuration
162
+ #
163
+ # Returns an array of load balancer names
164
+ def load_balancers_to_remove
165
+ @aws.load_balancer_names - @local.load_balancers
166
+ end
167
+
168
+ # Public: Get the load balancers to add, ie. are in local configuration but
169
+ # not in AWS
170
+ #
171
+ # Returns an array of load balancer names
172
+ def load_balancers_to_add
173
+ @local.load_balancers - @aws.load_balancer_names
174
+ end
175
+
176
+ end
177
+ end
178
+ end