applb 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +12 -0
- data/.rspec +2 -0
- data/.travis.yml +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +255 -0
- data/Rakefile +6 -0
- data/applb.gemspec +33 -0
- data/aws_config.yml.enc +2 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/exe/applb +5 -0
- data/lib/applb.rb +14 -0
- data/lib/applb/cli.rb +80 -0
- data/lib/applb/client.rb +386 -0
- data/lib/applb/client_wrapper.rb +85 -0
- data/lib/applb/converter.rb +22 -0
- data/lib/applb/dsl.rb +56 -0
- data/lib/applb/dsl/attributes.rb +49 -0
- data/lib/applb/dsl/checker.rb +27 -0
- data/lib/applb/dsl/ec2.rb +35 -0
- data/lib/applb/dsl/listener.rb +140 -0
- data/lib/applb/dsl/listeners.rb +29 -0
- data/lib/applb/dsl/load_balancer.rb +209 -0
- data/lib/applb/dsl/rule.rb +157 -0
- data/lib/applb/dsl/rules.rb +32 -0
- data/lib/applb/dsl/target_group.rb +156 -0
- data/lib/applb/dsl/target_groups.rb +28 -0
- data/lib/applb/error.rb +4 -0
- data/lib/applb/exporter.rb +7 -0
- data/lib/applb/filterable.rb +13 -0
- data/lib/applb/output_alb.erb +122 -0
- data/lib/applb/template_helper.rb +20 -0
- data/lib/applb/utils.rb +48 -0
- data/lib/applb/version.rb +3 -0
- metadata +192 -0
@@ -0,0 +1,157 @@
|
|
1
|
+
module Applb
|
2
|
+
class DSL
|
3
|
+
class EC2
|
4
|
+
class LoadBalancer
|
5
|
+
class Listeners
|
6
|
+
class Listener
|
7
|
+
class Rules
|
8
|
+
class Rule
|
9
|
+
include Applb::DSL::Checker
|
10
|
+
|
11
|
+
class Result
|
12
|
+
ATTRIBUTES = %i/priority actions conditions listener_arn rule_arn/
|
13
|
+
attr_accessor *ATTRIBUTES
|
14
|
+
|
15
|
+
def initialize(context, listener)
|
16
|
+
@context = context
|
17
|
+
@options = context.options
|
18
|
+
@listener = listener
|
19
|
+
end
|
20
|
+
|
21
|
+
def aws(aws_rule)
|
22
|
+
@aws_rule = aws_rule
|
23
|
+
self
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_h
|
27
|
+
Hash[ATTRIBUTES.sort.map { |name| [name, public_send(name)] }]
|
28
|
+
end
|
29
|
+
|
30
|
+
def create
|
31
|
+
Applb.logger.info("Create rule #{conditions.first[:values].first}")
|
32
|
+
return if @options[:dry_run]
|
33
|
+
|
34
|
+
Applb.logger.debug("create rule with option blow.")
|
35
|
+
Applb.logger.debug(create_option.pretty_inspect)
|
36
|
+
rule = client.create_rule(create_option).rules.first
|
37
|
+
rule_arn = rule.rule_arn
|
38
|
+
rule
|
39
|
+
end
|
40
|
+
|
41
|
+
def modify
|
42
|
+
dsl_hash = to_diff_h
|
43
|
+
aws_hash = to_diff_h_aws
|
44
|
+
result = nil
|
45
|
+
|
46
|
+
# modify rule
|
47
|
+
if dsl_hash != aws_hash
|
48
|
+
Applb.logger.info("Modify rule #{@aws_rule.rule_arn}")
|
49
|
+
Applb.logger.info("<diff>\n#{Applb::Utils.diff(aws_hash, dsl_hash, color: @options[:color])}")
|
50
|
+
|
51
|
+
unless @options[:dry_run]
|
52
|
+
result = client.modify_rule(modify_option).rules.first
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
# modify rule priority
|
57
|
+
if priority.to_s != @aws_rule.priority
|
58
|
+
Applb.logger.info("Modify priority #{@aws_rule.priority} to #{priority}")
|
59
|
+
Applb.logger.info("<diff>\n#{Applb::Utils.diff(@aws_rule.priority, priority, color: @options[:color])}")
|
60
|
+
|
61
|
+
unless @options[:dry_run]
|
62
|
+
rule_priority_option = {
|
63
|
+
rule_priorities: [{ rule_arn: @aws_rule.rule_arn, priority: priority}]
|
64
|
+
}
|
65
|
+
result = client.set_rule_priorities(rule_priority_option).rules.first
|
66
|
+
end
|
67
|
+
end
|
68
|
+
result
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
def create_option
|
74
|
+
options = to_h.reject { |k, v| k == :rule_arn }
|
75
|
+
options[:actions].first.delete(:target_group_name)
|
76
|
+
options
|
77
|
+
end
|
78
|
+
|
79
|
+
def modify_option
|
80
|
+
options = to_h.reject { |k, v| k == :priority }
|
81
|
+
options[:rule_arn] = @aws_rule.rule_arn
|
82
|
+
options[:actions].first.delete(:target_group_name)
|
83
|
+
options.delete(:listener_arn)
|
84
|
+
options
|
85
|
+
end
|
86
|
+
|
87
|
+
def to_diff_h
|
88
|
+
Applb::Utils.normalize_hash(to_h).reject do |k, v|
|
89
|
+
%i/:priority listener_arn rule_arn priority/.include?(k)
|
90
|
+
end.tap { |h| h[:actions].first.delete(:target_group_name) }
|
91
|
+
end
|
92
|
+
|
93
|
+
def to_diff_h_aws
|
94
|
+
Applb::Utils.normalize_hash(@aws_rule.to_h).reject do |k, v|
|
95
|
+
%i/priority is_default rule_arn/.include?(k)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def needs_modify?
|
100
|
+
to_diff_h != to_diff_h_aws
|
101
|
+
end
|
102
|
+
|
103
|
+
def client
|
104
|
+
@client ||= Applb::ClientWrapper.new(@options)
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def initialize(context, listener, &block)
|
109
|
+
@context = context.dup
|
110
|
+
@listener = listener
|
111
|
+
|
112
|
+
@result = Result.new(context, listener)
|
113
|
+
@result.actions = []
|
114
|
+
@result.conditions = []
|
115
|
+
|
116
|
+
instance_eval(&block)
|
117
|
+
end
|
118
|
+
|
119
|
+
def result
|
120
|
+
required(:conditions, @result.conditions)
|
121
|
+
required(:priority, @result.priority)
|
122
|
+
required(:actions, @result.actions)
|
123
|
+
@result
|
124
|
+
end
|
125
|
+
|
126
|
+
private
|
127
|
+
|
128
|
+
def rule_arn(rule_arn)
|
129
|
+
@result.rule_arn = rule_arn
|
130
|
+
end
|
131
|
+
|
132
|
+
def priority(priority)
|
133
|
+
@result.priority = priority
|
134
|
+
end
|
135
|
+
|
136
|
+
def actions(target_group_name: nil, target_group_arn: nil, type:)
|
137
|
+
@result.actions << {
|
138
|
+
target_group_arn: target_group_arn,
|
139
|
+
target_group_name: target_group_name,
|
140
|
+
type: type,
|
141
|
+
}
|
142
|
+
end
|
143
|
+
|
144
|
+
def conditions(field: , values:)
|
145
|
+
@result.conditions << {
|
146
|
+
field: field,
|
147
|
+
values: values,
|
148
|
+
}
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'applb/dsl/rule'
|
2
|
+
|
3
|
+
module Applb
|
4
|
+
class DSL
|
5
|
+
class EC2
|
6
|
+
class LoadBalancer
|
7
|
+
class Listeners
|
8
|
+
class Listener
|
9
|
+
class Rules
|
10
|
+
def initialize(context, listener, &block)
|
11
|
+
@context = context.dup
|
12
|
+
@listener = listener
|
13
|
+
|
14
|
+
@result = []
|
15
|
+
|
16
|
+
instance_eval(&block)
|
17
|
+
end
|
18
|
+
|
19
|
+
attr_reader :result
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def rule(&block)
|
24
|
+
@result << Rule.new(@context, @listener, &block).result
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,156 @@
|
|
1
|
+
module Applb
|
2
|
+
class DSL
|
3
|
+
class EC2
|
4
|
+
class LoadBalancer
|
5
|
+
class TargetGroups
|
6
|
+
class TargetGroup
|
7
|
+
include Checker
|
8
|
+
include Applb::TemplateHelper
|
9
|
+
|
10
|
+
class Result
|
11
|
+
ATTRIBUTES = %i/
|
12
|
+
name protocol port vpc_id health_check_protocol health_check_port health_check_path
|
13
|
+
health_check_interval_seconds health_check_timeout_seconds healthy_threshold_count
|
14
|
+
unhealthy_threshold_count matcher
|
15
|
+
/
|
16
|
+
|
17
|
+
attr_accessor *ATTRIBUTES
|
18
|
+
|
19
|
+
def initialize(context)
|
20
|
+
@context = context
|
21
|
+
@options = context.options
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_h
|
25
|
+
Hash[ATTRIBUTES.sort.map { |name| [name, public_send(name)] }]
|
26
|
+
end
|
27
|
+
|
28
|
+
def aws(aws_tg)
|
29
|
+
@aws_tg = aws_tg
|
30
|
+
self
|
31
|
+
end
|
32
|
+
|
33
|
+
def create
|
34
|
+
Applb.logger.info("Create target group #{name}")
|
35
|
+
return if @options[:dry_run]
|
36
|
+
client.create_target_group(create_option).target_groups.first
|
37
|
+
end
|
38
|
+
|
39
|
+
def modify
|
40
|
+
dsl_hash = to_diff_h
|
41
|
+
aws_hash = to_diff_h_aws
|
42
|
+
return if dsl_hash == aws_hash
|
43
|
+
|
44
|
+
Applb.logger.info("Modify target group #{name}")
|
45
|
+
Applb.logger.info("<diff>\n#{Applb::Utils.diff(aws_hash, dsl_hash, color: @options[:color])}")
|
46
|
+
return if @options[:dry_run]
|
47
|
+
|
48
|
+
puts modify_option
|
49
|
+
client.modify_target_group(modify_option).target_groups.first
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
def create_option
|
55
|
+
to_h
|
56
|
+
end
|
57
|
+
|
58
|
+
UNMODIFIABLE_ATTRIBUTES = %i/name port protocol vpc_id/
|
59
|
+
def modify_option
|
60
|
+
options = to_h.
|
61
|
+
merge(target_group_arn: @aws_tg.target_group_arn).
|
62
|
+
reject! { |k, v| UNMODIFIABLE_ATTRIBUTES.include?(k) }
|
63
|
+
end
|
64
|
+
|
65
|
+
def to_diff_h
|
66
|
+
hash = to_h
|
67
|
+
hash.delete(:target_group_arn)
|
68
|
+
Hash[hash.sort]
|
69
|
+
end
|
70
|
+
|
71
|
+
def to_diff_h_aws
|
72
|
+
hash = @aws_tg.to_h
|
73
|
+
hash[:name] = hash.delete(:target_group_name)
|
74
|
+
hash.delete(:target_group_arn)
|
75
|
+
hash.delete(:load_balancer_arns)
|
76
|
+
Hash[hash.sort]
|
77
|
+
end
|
78
|
+
|
79
|
+
def client
|
80
|
+
@client ||= Applb::ClientWrapper.new(@options)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def initialize(context, name, lb_name, &block)
|
85
|
+
@context = context.dup
|
86
|
+
@lb_name = lb_name
|
87
|
+
@result = Result.new(@context)
|
88
|
+
@result.name = name
|
89
|
+
|
90
|
+
instance_eval(&block)
|
91
|
+
end
|
92
|
+
|
93
|
+
def result
|
94
|
+
required(:name, @result.name)
|
95
|
+
required(:protocol, @result.protocol)
|
96
|
+
required(:port, @result.port)
|
97
|
+
required(:vpc_id, @result.vpc_id)
|
98
|
+
|
99
|
+
@result
|
100
|
+
end
|
101
|
+
|
102
|
+
private
|
103
|
+
|
104
|
+
def name(name)
|
105
|
+
@result.name = name
|
106
|
+
end
|
107
|
+
|
108
|
+
def protocol(protocol)
|
109
|
+
@result.protocol = protocol
|
110
|
+
end
|
111
|
+
|
112
|
+
def port(port)
|
113
|
+
@result.port = port
|
114
|
+
end
|
115
|
+
|
116
|
+
def vpc_id(vpc_id)
|
117
|
+
@result.vpc_id = vpc_id
|
118
|
+
end
|
119
|
+
|
120
|
+
def health_check_protocol(health_check_protocol)
|
121
|
+
@result.health_check_protocol = health_check_protocol
|
122
|
+
end
|
123
|
+
|
124
|
+
def health_check_port(health_check_port)
|
125
|
+
@result.health_check_port = health_check_port
|
126
|
+
end
|
127
|
+
|
128
|
+
def health_check_path(health_check_path)
|
129
|
+
@result.health_check_path = health_check_path
|
130
|
+
end
|
131
|
+
|
132
|
+
def health_check_interval_seconds(health_check_interval_seconds)
|
133
|
+
@result.health_check_interval_seconds = health_check_interval_seconds
|
134
|
+
end
|
135
|
+
|
136
|
+
def health_check_timeout_seconds(health_check_timeout_seconds)
|
137
|
+
@result.health_check_timeout_seconds = health_check_timeout_seconds
|
138
|
+
end
|
139
|
+
|
140
|
+
def healthy_threshold_count(healthy_threshold_count)
|
141
|
+
@result.healthy_threshold_count = healthy_threshold_count
|
142
|
+
end
|
143
|
+
|
144
|
+
def unhealthy_threshold_count(unhealthy_threshold_count)
|
145
|
+
@result.unhealthy_threshold_count = unhealthy_threshold_count
|
146
|
+
end
|
147
|
+
|
148
|
+
def matcher(http_code:)
|
149
|
+
@result.matcher = { http_code: http_code }
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'applb/dsl/target_group'
|
2
|
+
|
3
|
+
module Applb
|
4
|
+
class DSL
|
5
|
+
class EC2
|
6
|
+
class LoadBalancer
|
7
|
+
class TargetGroups
|
8
|
+
include Applb::TemplateHelper
|
9
|
+
|
10
|
+
attr_reader :result
|
11
|
+
|
12
|
+
def initialize(context, lb, &block)
|
13
|
+
@context = context.dup
|
14
|
+
@lb = lb
|
15
|
+
@result = []
|
16
|
+
instance_eval(&block)
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def target_group(name, &block)
|
22
|
+
@result << TargetGroup.new(@context, name, @lb, &block).result
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
data/lib/applb/error.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
module Applb
|
2
|
+
module Filterable
|
3
|
+
def target?(lb_name)
|
4
|
+
unless @options[:includes].empty?
|
5
|
+
return @options[:includes].include?(lb_name)
|
6
|
+
end
|
7
|
+
unless @options[:excludes].empty?
|
8
|
+
return !@options[:excludes].any? { |regex| lb_name =~ regex }
|
9
|
+
end
|
10
|
+
true
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
ec2 <%= vpc_id.inspect %> do
|
2
|
+
<%- lbs_by_name.each do |name, attr| -%>
|
3
|
+
elb_v2 <%= name.inspect %> do
|
4
|
+
subnets(
|
5
|
+
<%- attr[:availability_zones].each do |az| -%>
|
6
|
+
<%= az[:subnet_id].inspect %>, # <%= az[:zone_name] %>
|
7
|
+
<%- end -%>
|
8
|
+
)
|
9
|
+
|
10
|
+
security_groups(
|
11
|
+
<%- attr[:security_groups].each do |sg| -%>
|
12
|
+
<%= sg.inspect %>,
|
13
|
+
<%- end -%>
|
14
|
+
)
|
15
|
+
|
16
|
+
scheme(<%= attr[:scheme].inspect %>)
|
17
|
+
|
18
|
+
<%- unless tags_by_arn[attr[:load_balancer_arn]].empty? -%>
|
19
|
+
tags(
|
20
|
+
<%- tags_by_arn[attr[:load_balancer_arn]].each do |key, value| -%>
|
21
|
+
<%= key.inspect %> => <%= value.inspect %>,
|
22
|
+
<%- end -%>
|
23
|
+
)
|
24
|
+
|
25
|
+
<%- end -%>
|
26
|
+
ip_address_type(<%= attr[:ip_address_type].inspect %>)
|
27
|
+
|
28
|
+
attributes do
|
29
|
+
<%- attr[:attributes].each do |key, value|
|
30
|
+
case key
|
31
|
+
when "access_logs" then -%>
|
32
|
+
access_logs({
|
33
|
+
s3_enabled: <%= value[:s3][:enabled] %>,
|
34
|
+
s3_bucket: <%= value[:s3][:bucket].inspect %>,
|
35
|
+
s3_prefix: <%= value[:s3][:prefix].inspect %>,
|
36
|
+
})
|
37
|
+
<%- else -%>
|
38
|
+
<%= key.gsub('.', ' ') %>: <%= value %>
|
39
|
+
<%- end
|
40
|
+
end
|
41
|
+
-%>
|
42
|
+
end
|
43
|
+
|
44
|
+
target_groups do
|
45
|
+
<%- attr[:target_groups].each do |target_group| -%>
|
46
|
+
target_group <%= target_group.target_group_name.inspect %> do
|
47
|
+
protocol <%= target_group.protocol.inspect %>
|
48
|
+
port <%= target_group.port %>
|
49
|
+
vpc_id <%= vpc_id.inspect %>
|
50
|
+
health_check_interval_seconds <%= target_group.health_check_interval_seconds %>
|
51
|
+
health_check_path <%= target_group.health_check_path.inspect %>
|
52
|
+
health_check_port <%= target_group.health_check_port.inspect %>
|
53
|
+
health_check_protocol <%= target_group.health_check_protocol.inspect %>
|
54
|
+
health_check_timeout_seconds <%= target_group.health_check_timeout_seconds %>
|
55
|
+
healthy_threshold_count <%= target_group.healthy_threshold_count %>
|
56
|
+
unhealthy_threshold_count <%= target_group.unhealthy_threshold_count %>
|
57
|
+
matcher http_code: <%= target_group.matcher.http_code.inspect %>
|
58
|
+
end
|
59
|
+
<%- end -%>
|
60
|
+
end
|
61
|
+
|
62
|
+
listeners do
|
63
|
+
<%- attr[:listeners].each do |listener| -%>
|
64
|
+
listener do
|
65
|
+
<%- listener.certificates.each do |certificate| -%>
|
66
|
+
certificates certificate_arn: <%= certificate.certificate_arn.inspect %>
|
67
|
+
<%- end -%>
|
68
|
+
<%- if listener.ssl_policy -%>
|
69
|
+
ssl_policy <%= listener.ssl_policy.inspect %>
|
70
|
+
<%- end -%>
|
71
|
+
port <%= listener.port %>
|
72
|
+
protocol <%= listener.protocol.inspect %>
|
73
|
+
<%- listener.default_actions.each do |action| -%>
|
74
|
+
|
75
|
+
default_actions(
|
76
|
+
target_group_name: <%= attr[:target_groups].find { |target_group| target_group.target_group_arn == action.target_group_arn }.target_group_name.inspect %>,
|
77
|
+
target_group_arn: <%= action.target_group_arn.inspect %>,
|
78
|
+
type: <%= action.type.inspect %>,
|
79
|
+
)
|
80
|
+
<%- end -%>
|
81
|
+
|
82
|
+
rules do
|
83
|
+
<%- if attr[:rules_by_listener_arn][listener.listener_arn].reject(&:is_default).empty? -%>
|
84
|
+
# no rules
|
85
|
+
<%- end -%>
|
86
|
+
<%- attr[:rules_by_listener_arn][listener.listener_arn].reject(&:is_default).each do |rule| -%>
|
87
|
+
rule do
|
88
|
+
rule_arn <%= rule.rule_arn.inspect %>
|
89
|
+
priority <%= rule.priority.inspect %>
|
90
|
+
|
91
|
+
<%- rule.actions.each do |action| -%>
|
92
|
+
actions(
|
93
|
+
target_group_name: <%= attr[:target_groups].find { |target_group| target_group.target_group_arn == action.target_group_arn }.target_group_name.inspect %>,
|
94
|
+
target_group_arn: <%= action.target_group_arn.inspect %>,
|
95
|
+
type: <%= action.type.inspect %>,
|
96
|
+
)
|
97
|
+
|
98
|
+
<%- end -%>
|
99
|
+
conditions(
|
100
|
+
<%- rule.conditions.each do |condition| -%>
|
101
|
+
field: <%= condition.field.inspect %>,
|
102
|
+
values: <%= condition.values.inspect %>,
|
103
|
+
<%- end -%>
|
104
|
+
)
|
105
|
+
end
|
106
|
+
<%- if attr[:rules_by_listener_arn][listener.listener_arn].reject(&:is_default).last != rule -%>
|
107
|
+
|
108
|
+
<%- end -%>
|
109
|
+
<%- end -%>
|
110
|
+
end
|
111
|
+
end
|
112
|
+
<%- if attr[:listeners].last != listener -%>
|
113
|
+
|
114
|
+
<%- end -%>
|
115
|
+
<%- end -%>
|
116
|
+
end
|
117
|
+
end
|
118
|
+
<%- if lbs_by_name.keys.last != name -%>
|
119
|
+
|
120
|
+
<%- end -%>
|
121
|
+
<%- end -%>
|
122
|
+
end
|