applb 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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,22 @@
|
|
1
|
+
require 'erb'
|
2
|
+
|
3
|
+
module Applb
|
4
|
+
class Converter
|
5
|
+
def initialize(lbs_by_vpc_id, tags_by_arn)
|
6
|
+
@lbs_by_vpc_id = lbs_by_vpc_id
|
7
|
+
@tags_by_arn = tags_by_arn
|
8
|
+
end
|
9
|
+
|
10
|
+
def convert
|
11
|
+
@lbs_by_vpc_id.each do |vpc_id, lbs_by_name|
|
12
|
+
yield vpc_id, output_alb(vpc_id, @tags_by_arn, lbs_by_name)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def output_alb(vpc_id, tags_by_arn, lbs_by_name)
|
19
|
+
ERB.new(File.read('lib/applb/output_alb.erb'), nil, '-').result(binding)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
data/lib/applb/dsl.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'hashie'
|
2
|
+
require 'applb/template_helper'
|
3
|
+
require 'applb/dsl/ec2'
|
4
|
+
|
5
|
+
module Applb
|
6
|
+
class DSL
|
7
|
+
include Applb::TemplateHelper
|
8
|
+
|
9
|
+
class << self
|
10
|
+
def define(source, filepath, options)
|
11
|
+
self.new(filepath, options) do
|
12
|
+
eval(source, binding, filepath)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
attr_reader :result
|
18
|
+
|
19
|
+
def initialize(filepath, options,&block)
|
20
|
+
@filepath = filepath
|
21
|
+
@result = OpenStruct.new(ec2s: {})
|
22
|
+
|
23
|
+
@context = Hashie::Mash.new(
|
24
|
+
filepath: filepath,
|
25
|
+
templates: {},
|
26
|
+
options: options,
|
27
|
+
)
|
28
|
+
|
29
|
+
instance_eval(&block)
|
30
|
+
end
|
31
|
+
|
32
|
+
def require(file)
|
33
|
+
albfile = (file =~ %r|\A/|) ? file : File.expand_path(File.join(File.dirname(@path), file))
|
34
|
+
|
35
|
+
if File.exist?(albfile)
|
36
|
+
instance_eval(File.read(albfile), albfile)
|
37
|
+
elsif File.exist?("#{albfile}.rb")
|
38
|
+
instance_eval(File.read("#{albfile}.rb"), "#{albfile}.rb")
|
39
|
+
else
|
40
|
+
Kernel.require(file)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def template(name, &block)
|
45
|
+
@context.templates[name.to_s] = block
|
46
|
+
end
|
47
|
+
|
48
|
+
def ec2(vpc_id, &block)
|
49
|
+
if ec2_result = @result.ec2s[vpc_id]
|
50
|
+
@result.ec2s[vpc_id] = EC2.new(@context, vpc_id, ec2_result.load_balancers, &block).result
|
51
|
+
else
|
52
|
+
@result.ec2s[vpc_id] = EC2.new(@context, vpc_id, [], &block).result
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Applb
|
2
|
+
class DSL
|
3
|
+
class EC2
|
4
|
+
class LoadBalancer
|
5
|
+
class Attributes
|
6
|
+
include Applb::DSL::Checker
|
7
|
+
include Applb::TemplateHelper
|
8
|
+
|
9
|
+
attr_reader :result
|
10
|
+
|
11
|
+
def initialize(context, lb_name, &block)
|
12
|
+
@context = context.dup
|
13
|
+
@lb_name = lb_name
|
14
|
+
|
15
|
+
@result = {
|
16
|
+
'access_logs.s3.enabled' => false,
|
17
|
+
'access_logs.s3.bucket' => '',
|
18
|
+
'access_logs.s3.prefix' => '',
|
19
|
+
'idle_timeout.timeout_seconds' => 60,
|
20
|
+
'deletion_protection.enabled' => false,
|
21
|
+
}
|
22
|
+
|
23
|
+
instance_eval(&block)
|
24
|
+
end
|
25
|
+
|
26
|
+
def result
|
27
|
+
@result.map { |k, v| {key: k, value: v} }
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def access_logs(args)
|
33
|
+
@result['access_logs.s3.enabled'] = args[:s3_enabled] if args[:s3_enabled]
|
34
|
+
@result['access_logs.s3.bucket'] = args[:s3_bucket] if args[:s3_bucket]
|
35
|
+
@result['access_logs.s3.prefix'] = args[:s3_prefix] if args[:s3_prefix]
|
36
|
+
end
|
37
|
+
|
38
|
+
def idle_timeout(timeout_seconds:)
|
39
|
+
@result['idle_timeout.timeout_seconds'] = timeout_seconds if timeout_seconds
|
40
|
+
end
|
41
|
+
|
42
|
+
def deletion_protection(enabled:)
|
43
|
+
@result['deletion_protection.enabled'] = enabled if enabled
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'applb/error'
|
2
|
+
|
3
|
+
module Applb
|
4
|
+
class DSL
|
5
|
+
module Checker
|
6
|
+
private
|
7
|
+
|
8
|
+
class ValidationError < Error
|
9
|
+
end
|
10
|
+
|
11
|
+
def required(name, value)
|
12
|
+
if value
|
13
|
+
case value
|
14
|
+
when String
|
15
|
+
invalid = value.strip.empty?
|
16
|
+
when Array, Hash
|
17
|
+
invalid = value.empty?
|
18
|
+
end
|
19
|
+
else
|
20
|
+
invalid = true
|
21
|
+
end
|
22
|
+
|
23
|
+
raise ValidationError.new("`#{name}' is required") if invalid
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
require 'applb/dsl/load_balancer'
|
3
|
+
|
4
|
+
module Applb
|
5
|
+
class DSL
|
6
|
+
class EC2
|
7
|
+
include Applb::TemplateHelper
|
8
|
+
|
9
|
+
attr_reader :result
|
10
|
+
|
11
|
+
def initialize(context, vpc_id, lbs, &block)
|
12
|
+
@context = context.merge(vpc_id: vpc_id)
|
13
|
+
|
14
|
+
@result = OpenStruct.new({
|
15
|
+
vpc_id: vpc_id,
|
16
|
+
load_balancers: lbs,
|
17
|
+
})
|
18
|
+
|
19
|
+
@names = lbs.map(&:name)
|
20
|
+
instance_eval(&block)
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def elb_v2(name, &block)
|
26
|
+
if @names.include?(name)
|
27
|
+
raise "#{@result.vpc_id}: #{name} is already defined"
|
28
|
+
end
|
29
|
+
|
30
|
+
@result.load_balancers << LoadBalancer.new(@context, name, @result.vpc_id, &block).result
|
31
|
+
@names << name
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
require 'applb/dsl/rules'
|
2
|
+
require 'applb/utils'
|
3
|
+
require 'applb/client_wrapper'
|
4
|
+
|
5
|
+
module Applb
|
6
|
+
class DSL
|
7
|
+
class EC2
|
8
|
+
class LoadBalancer
|
9
|
+
class Listeners
|
10
|
+
class Listener
|
11
|
+
include Checker
|
12
|
+
include Applb::TemplateHelper
|
13
|
+
|
14
|
+
class Result
|
15
|
+
ATTRIBUTES = %i/certificates ssl_policy port protocol default_actions rules load_balancer_arn/
|
16
|
+
attr_accessor *ATTRIBUTES
|
17
|
+
|
18
|
+
def initialize(context, lb_name)
|
19
|
+
@context = context
|
20
|
+
@options = context.options
|
21
|
+
@lb_name = lb_name
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_h
|
25
|
+
Hash[ATTRIBUTES.sort.map { |name| [name, public_send(name)] }]
|
26
|
+
end
|
27
|
+
|
28
|
+
def aws(aws_listener)
|
29
|
+
@aws_listener = aws_listener
|
30
|
+
self
|
31
|
+
end
|
32
|
+
|
33
|
+
def create
|
34
|
+
Applb.logger.info("#{@lb_name} Create listener for port #{port}")
|
35
|
+
return if @options[:dry_run]
|
36
|
+
client.create_listener(create_option).listeners.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("#{@lb_name} Modify listener for port #{port}")
|
45
|
+
Applb.logger.info("<diff>\n#{Applb::Utils.diff(aws_hash, dsl_hash, color: @options[:color])}")
|
46
|
+
return if @options[:dry_run]
|
47
|
+
|
48
|
+
client.modify_listener(modify_option).listeners.first
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def to_diff_h
|
54
|
+
options = Applb::Utils.normalize_hash(to_h)
|
55
|
+
target_group_name = options[:default_actions].first.delete(:target_group_name)
|
56
|
+
if options[:ssl_policy] && options[:ssl_policy].empty?
|
57
|
+
options.delete(:certificates)
|
58
|
+
options.delete(:ssl_policy)
|
59
|
+
end
|
60
|
+
options.reject! { |k, v| %i/listener_arn load_balancer_arn rules/.include?(k) }
|
61
|
+
end
|
62
|
+
|
63
|
+
def to_diff_h_aws
|
64
|
+
options = Applb::Utils.normalize_hash(@aws_listener.to_h)
|
65
|
+
if options[:ssl_policy] && options[:ssl_policy].empty?
|
66
|
+
options.delete(:certificates)
|
67
|
+
options.delete(:ssl_policy)
|
68
|
+
end
|
69
|
+
options.reject! { |k, v| %i/listener_arn load_balancer_arn rules/.include?(k) }
|
70
|
+
end
|
71
|
+
|
72
|
+
def create_option
|
73
|
+
options = to_h.reject { |k, _| %i/policy_name rules/.include?(k) }
|
74
|
+
options[:default_actions].first.delete(:target_group_name)
|
75
|
+
options
|
76
|
+
end
|
77
|
+
|
78
|
+
def modify_option
|
79
|
+
to_diff_h.merge(listener_arn: @aws_listener.listener_arn)
|
80
|
+
end
|
81
|
+
|
82
|
+
def client
|
83
|
+
@client ||= Applb::ClientWrapper.new(@options)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
attr_reader :result
|
88
|
+
|
89
|
+
def initialize(context, lb_name, &block)
|
90
|
+
@context = context.dup
|
91
|
+
@lb_name = lb_name
|
92
|
+
|
93
|
+
@result = Result.new(@context, @lb_name)
|
94
|
+
|
95
|
+
instance_eval(&block)
|
96
|
+
end
|
97
|
+
|
98
|
+
private
|
99
|
+
|
100
|
+
def certificates(certificate_arn:)
|
101
|
+
@result.certificates ||= []
|
102
|
+
@result.certificates << {certificate_arn: certificate_arn}
|
103
|
+
end
|
104
|
+
|
105
|
+
def ssl_policy(ssl_policy)
|
106
|
+
@result.ssl_policy = ssl_policy if ssl_policy
|
107
|
+
end
|
108
|
+
|
109
|
+
def port(port)
|
110
|
+
@result.port = port
|
111
|
+
end
|
112
|
+
|
113
|
+
def protocol(protocol)
|
114
|
+
@result.protocol = protocol
|
115
|
+
end
|
116
|
+
|
117
|
+
def default_actions(target_group_name: nil, target_group_arn: nil, type:)
|
118
|
+
unless target_group_name || target_group_arn
|
119
|
+
raise "target_group_name or target_group_arn is required"
|
120
|
+
end
|
121
|
+
@result.default_actions ||= []
|
122
|
+
@result.default_actions << {
|
123
|
+
target_group_arn: target_group_arn,
|
124
|
+
target_group_name: target_group_name,
|
125
|
+
type: type,
|
126
|
+
}
|
127
|
+
end
|
128
|
+
|
129
|
+
def rules(&block)
|
130
|
+
rules = Rules.new(@context, self, &block).result
|
131
|
+
unless rules.empty?
|
132
|
+
@result.rules = rules
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'applb/dsl/listener'
|
2
|
+
|
3
|
+
module Applb
|
4
|
+
class DSL
|
5
|
+
class EC2
|
6
|
+
class LoadBalancer
|
7
|
+
class Listeners
|
8
|
+
include Applb::TemplateHelper
|
9
|
+
|
10
|
+
attr_reader :result
|
11
|
+
|
12
|
+
def initialize(context, lb_name, &block)
|
13
|
+
@context = context.dup
|
14
|
+
@lb_name = lb_name
|
15
|
+
@result = []
|
16
|
+
|
17
|
+
instance_eval(&block)
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def listener(&block)
|
23
|
+
@result << Listener.new(@context, @lb_name, &block).result
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,209 @@
|
|
1
|
+
require 'applb/dsl/checker'
|
2
|
+
require 'applb/dsl/attributes'
|
3
|
+
require 'applb/dsl/listeners'
|
4
|
+
require 'applb/dsl/target_groups'
|
5
|
+
|
6
|
+
module Applb
|
7
|
+
class DSL
|
8
|
+
class EC2
|
9
|
+
class LoadBalancer
|
10
|
+
include Applb::DSL::Checker
|
11
|
+
include Applb::TemplateHelper
|
12
|
+
|
13
|
+
class Result
|
14
|
+
ATTRIBUTES = %i/name instances scheme subnets security_groups tags ip_address_type attributes target_groups listeners load_balancer_arn/
|
15
|
+
attr_accessor *ATTRIBUTES
|
16
|
+
|
17
|
+
def initialize(context)
|
18
|
+
@context = context
|
19
|
+
@options = context.options
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_h
|
23
|
+
Hash[ATTRIBUTES.sort.map { |name| [name, public_send(name)] }]
|
24
|
+
end
|
25
|
+
|
26
|
+
CREATE_KEYS = %i/name subnets security_groups scheme tags ip_address_type/
|
27
|
+
def create_option
|
28
|
+
to_h.select { |k, _| CREATE_KEYS.include?(k) }
|
29
|
+
end
|
30
|
+
|
31
|
+
def create
|
32
|
+
Applb.logger.info "Create ELB v2 #{name}"
|
33
|
+
return if @options[:dry_run]
|
34
|
+
|
35
|
+
client.create_load_balancer(create_option).load_balancers.first
|
36
|
+
end
|
37
|
+
|
38
|
+
def aws(aws_lb)
|
39
|
+
@aws_lb = aws_lb
|
40
|
+
self
|
41
|
+
end
|
42
|
+
|
43
|
+
def subnets_updated?
|
44
|
+
subnets.sort != @aws_lb.availability_zones.map(&:subnet_id).sort
|
45
|
+
end
|
46
|
+
|
47
|
+
def security_groups_updated?
|
48
|
+
security_groups.sort != @aws_lb.security_groups.sort
|
49
|
+
end
|
50
|
+
|
51
|
+
def ip_address_type_updated?
|
52
|
+
ip_address_type != @aws_lb.ip_address_type
|
53
|
+
end
|
54
|
+
|
55
|
+
def modify_subnets
|
56
|
+
return unless subnets_updated?
|
57
|
+
|
58
|
+
Applb.logger.info("Modify #{name} subnets")
|
59
|
+
diff = Applb::Utils.diff(
|
60
|
+
@aws_lb.availability_zones.map(&:subnet_id).sort,
|
61
|
+
subnets.sort,
|
62
|
+
color: @options[:color],
|
63
|
+
)
|
64
|
+
Applb.logger.info("<diff>\n#{diff}")
|
65
|
+
return if @options[:dry_run]
|
66
|
+
|
67
|
+
client.set_subnets(
|
68
|
+
load_balancer_arn: @aws_lb.load_balancer_arn,
|
69
|
+
subnets: subnets,
|
70
|
+
).availability_zones
|
71
|
+
end
|
72
|
+
|
73
|
+
def modify_security_groups
|
74
|
+
return unless security_groups_updated?
|
75
|
+
|
76
|
+
Applb.logger.info "Modify #{name} security_groups"
|
77
|
+
diff = Applb::Utils.diff(
|
78
|
+
@aws_lb.security_groups.sort,
|
79
|
+
security_groups.sort,
|
80
|
+
color: @options[:color],
|
81
|
+
)
|
82
|
+
Applb.logger.info("<diff>\n#{diff}")
|
83
|
+
return if @options[:dry_run]
|
84
|
+
|
85
|
+
client.set_security_groups(
|
86
|
+
load_balancer_arn: @aws_lb.load_balancer_arn,
|
87
|
+
security_groups: security_groups,
|
88
|
+
).security_group_ids
|
89
|
+
end
|
90
|
+
|
91
|
+
def modify_ip_address_type
|
92
|
+
return unless ip_address_type_updated?
|
93
|
+
|
94
|
+
Applb.logger.info "Modify #{name} ip_address_type"
|
95
|
+
diff = Applb::Utils.diff(
|
96
|
+
@aws_lb.ip_address_type,
|
97
|
+
ip_address_type,
|
98
|
+
color: @options[:color],
|
99
|
+
)
|
100
|
+
Applb.logger.info("<diff>\n#{diff}")
|
101
|
+
|
102
|
+
return if @options[:dry_run]
|
103
|
+
client.set_ip_address_type(
|
104
|
+
load_balancer_arn: @aws_lb.load_balancer_arn,
|
105
|
+
ip_address_type: ip_address_type,
|
106
|
+
).ip_address_type
|
107
|
+
end
|
108
|
+
|
109
|
+
def modify_load_balancer_attributes
|
110
|
+
attrs = attributes.map do |attr|
|
111
|
+
{key: attr[:key], value: attr[:value].to_s}
|
112
|
+
end
|
113
|
+
log_enabled = attrs.find { |attr| attr[:key] == 'access_logs.s3.enabled' }[:value]
|
114
|
+
if log_enabled.to_s == 'false'
|
115
|
+
attrs.reject! do |attr|
|
116
|
+
%w/access_logs.s3.bucket access_logs.s3.prefix/.include?(attr[:key])
|
117
|
+
end
|
118
|
+
end
|
119
|
+
dsl_hash = attrs.map { |a| a.to_h }.sort { |a, b| a[:key] <=> b[:key] }
|
120
|
+
|
121
|
+
aws_attributes = client.describe_load_balancer_attributes(
|
122
|
+
load_balancer_arn: @aws_lb.load_balancer_arn,
|
123
|
+
).attributes
|
124
|
+
aws_hash = aws_attributes.map { |a| a.to_h }.sort { |a, b| a[:key] <=> b[:key] }
|
125
|
+
aws_log_enabled = aws_attributes.find { |attr| attr[:key] == 'access_logs.s3.enabled' }[:value]
|
126
|
+
if aws_log_enabled == 'false'
|
127
|
+
aws_hash.reject! do |attr|
|
128
|
+
%w/access_logs.s3.bucket access_logs.s3.prefix/.include?(attr[:key])
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
return if dsl_hash == aws_hash
|
133
|
+
|
134
|
+
Applb.logger.info "Modify #{name} load_balancer_attributes"
|
135
|
+
Applb.logger.info("<diff>\n#{Applb::Utils.diff(aws_hash, dsl_hash, color: @options[:color])}")
|
136
|
+
return if @options[:dry_run]
|
137
|
+
|
138
|
+
client.modify_load_balancer_attributes(
|
139
|
+
load_balancer_arn: @aws_lb.load_balancer_arn,
|
140
|
+
attributes: attrs,
|
141
|
+
).attributes
|
142
|
+
end
|
143
|
+
|
144
|
+
private
|
145
|
+
|
146
|
+
def client
|
147
|
+
@client ||= Applb::ClientWrapper.new(@options)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
def initialize(context, name, vpc_id, &block)
|
152
|
+
@name = name
|
153
|
+
@vpc_id = vpc_id
|
154
|
+
@context = context.merge(name: name)
|
155
|
+
|
156
|
+
@result = Result.new(@context)
|
157
|
+
@result.name = name
|
158
|
+
@result.attributes = Attributes.new(@context, @name) {}.result
|
159
|
+
@result.instances = []
|
160
|
+
@result.target_groups = []
|
161
|
+
@result.listeners = []
|
162
|
+
|
163
|
+
instance_eval(&block)
|
164
|
+
end
|
165
|
+
|
166
|
+
def result
|
167
|
+
required(:subnets, @result.subnets)
|
168
|
+
required(:security_groups, @result.security_groups)
|
169
|
+
|
170
|
+
@result
|
171
|
+
end
|
172
|
+
|
173
|
+
private
|
174
|
+
|
175
|
+
def subnets(*subnets)
|
176
|
+
@result.subnets = subnets
|
177
|
+
end
|
178
|
+
|
179
|
+
def security_groups(*security_groups)
|
180
|
+
@result.security_groups = security_groups
|
181
|
+
end
|
182
|
+
|
183
|
+
def scheme(scheme)
|
184
|
+
@result.scheme = scheme
|
185
|
+
end
|
186
|
+
|
187
|
+
def tags(tags)
|
188
|
+
@result.tags = tags.map { |k, v| { key: k, value: v } }
|
189
|
+
end
|
190
|
+
|
191
|
+
def ip_address_type(ip_address_type)
|
192
|
+
@result.ip_address_type = ip_address_type
|
193
|
+
end
|
194
|
+
|
195
|
+
def attributes(&block)
|
196
|
+
@result.attributes = Attributes.new(@context, @name, &block).result
|
197
|
+
end
|
198
|
+
|
199
|
+
def target_groups(&block)
|
200
|
+
@result.target_groups = TargetGroups.new(@context, @name, &block).result
|
201
|
+
end
|
202
|
+
|
203
|
+
def listeners(&block)
|
204
|
+
@result.listeners = Listeners.new(@context, @name, &block).result
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|