Class: Hako::Schedulers::EcsElbV2

Inherits:
Object
  • Object
show all
Defined in:
lib/hako/schedulers/ecs_elb_v2.rb

Instance Method Summary collapse

Constructor Details

#initialize(app_id, region, elb_v2_config, dry_run:) ⇒ EcsElbV2

Returns a new instance of EcsElbV2.

Parameters:

  • app_id (String)
  • region (String)
  • elb_v2_config (Hash)
  • dry_run (Boolean)


14
15
16
17
18
19
# File 'lib/hako/schedulers/ecs_elb_v2.rb', line 14

def initialize(app_id, region, elb_v2_config, dry_run:)
  @app_id = app_id
  @region = region
  @elb_v2_config = elb_v2_config
  @dry_run = dry_run
end

Instance Method Details

#describe_load_balancerAws::ElasticLoadBalancingV2::Types::LoadBalancer

Returns:

  • (Aws::ElasticLoadBalancingV2::Types::LoadBalancer)


33
34
35
36
37
# File 'lib/hako/schedulers/ecs_elb_v2.rb', line 33

def describe_load_balancer
  elb_client.describe_load_balancers(names: [elb_name]).load_balancers[0]
rescue Aws::ElasticLoadBalancingV2::Errors::LoadBalancerNotFound
  nil
end

#describe_target_groupAws::ElasticLoadBalancingV2::Types::TargetGroup

Returns:

  • (Aws::ElasticLoadBalancingV2::Types::TargetGroup)


40
41
42
43
44
# File 'lib/hako/schedulers/ecs_elb_v2.rb', line 40

def describe_target_group
  elb_client.describe_target_groups(names: [target_group_name]).target_groups[0]
rescue Aws::ElasticLoadBalancingV2::Errors::TargetGroupNotFound
  nil
end

#destroynil

Returns:

  • (nil)


199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
# File 'lib/hako/schedulers/ecs_elb_v2.rb', line 199

def destroy
  unless @elb_v2_config
    return false
  end

  unless load_balancer_given?
    load_balancer = describe_load_balancer
    if load_balancer
      if @dry_run
        Hako.logger.info("elb_client.delete_load_balancer(load_balancer_arn: #{load_balancer.load_balancer_arn})")
      else
        elb_client.delete_load_balancer(load_balancer_arn: load_balancer.load_balancer_arn)
        Hako.logger.info "Deleted ELBv2 #{load_balancer.load_balancer_arn}"
      end
    else
      Hako.logger.info "ELBv2 #{elb_name} doesn't exist"
    end
  end

  unless target_group_given?
    target_group = describe_target_group
    if target_group
      if @dry_run
        Hako.logger.info("elb_client.delete_target_group(target_group_arn: #{target_group.target_group_arn})")
      else
        deleted = false
        30.times do
          begin
            elb_client.delete_target_group(target_group_arn: target_group.target_group_arn)
            deleted = true
            break
          rescue Aws::ElasticLoadBalancingV2::Errors::ResourceInUse => e
            Hako.logger.warn("#{e.class}: #{e.message}")
          end
          sleep 1
        end
        unless deleted
          raise Error.new("Cannot delete target group #{target_group.target_group_arn}")
        end

        Hako.logger.info "Deleted target group #{target_group.target_group_arn}"
      end
    end
  end
end

#elb_clientObject (private)



276
277
278
# File 'lib/hako/schedulers/ecs_elb_v2.rb', line 276

def elb_client
  @elb_v2 ||= Aws::ElasticLoadBalancingV2::Client.new(region: @region)
end

#elb_nameString

Returns:

  • (String)


246
247
248
# File 'lib/hako/schedulers/ecs_elb_v2.rb', line 246

def elb_name
  @elb_v2_config.fetch('load_balancer_name', "hako-#{@app_id}")
end

#find_or_create_load_balancer(_front_port) ⇒ nil

Parameters:

  • front_port (Fixnum)

Returns:

  • (nil)


48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/hako/schedulers/ecs_elb_v2.rb', line 48

def find_or_create_load_balancer(_front_port)
  unless @elb_v2_config
    return false
  end

  load_balancer = describe_load_balancer
  if !load_balancer_given? && !load_balancer
    tags = @elb_v2_config.fetch('tags', {}).map { |k, v| { key: k, value: v.to_s } }

    elb_type = @elb_v2_config.fetch('type', nil)
    if elb_type == 'network'
      load_balancer = elb_client.create_load_balancer(
        name: elb_name,
        subnets: @elb_v2_config.fetch('subnets'),
        scheme: @elb_v2_config.fetch('scheme', nil),
        type: 'network',
        tags: tags.empty? ? nil : tags,
      ).load_balancers[0]
      Hako.logger.info "Created ELBv2(NLB) #{load_balancer.dns_name}"
    else
      load_balancer = elb_client.create_load_balancer(
        name: elb_name,
        subnets: @elb_v2_config.fetch('subnets'),
        security_groups: @elb_v2_config.fetch('security_groups'),
        scheme: @elb_v2_config.fetch('scheme', nil),
        type: @elb_v2_config.fetch('type', nil),
        tags: tags.empty? ? nil : tags,
      ).load_balancers[0]
      Hako.logger.info "Created ELBv2 #{load_balancer.dns_name}"
    end
  end

  target_group = describe_target_group
  if !target_group_given? && !target_group
    elb_type = @elb_v2_config.fetch('type', nil)
    target_group = if elb_type == 'network'
                     elb_client.create_target_group(
                       name: target_group_name,
                       port: 80,
                       protocol: 'TCP',
                       vpc_id: @elb_v2_config.fetch('vpc_id'),
                       target_type: @elb_v2_config.fetch('target_type', nil),
                     ).target_groups[0]
                   else
                     elb_client.create_target_group(
                       name: target_group_name,
                       port: 80,
                       protocol: 'HTTP',
                       vpc_id: @elb_v2_config.fetch('vpc_id'),
                       health_check_path: @elb_v2_config.fetch('health_check_path', nil),
                       target_type: @elb_v2_config.fetch('target_type', nil),
                     ).target_groups[0]
                   end

    Hako.logger.info "Created target group #{target_group.target_group_arn}"
  end

  unless load_balancer_given?
    listener_ports = elb_client.describe_listeners(load_balancer_arn: load_balancer.load_balancer_arn).flat_map { |page| page.listeners.map(&:port) }
    @elb_v2_config.fetch('listeners').each do |l|
      params = {
        load_balancer_arn: load_balancer.load_balancer_arn,
        protocol: l.fetch('protocol'),
        port: l.fetch('port'),
        ssl_policy: l['ssl_policy'],
        default_actions: [{ type: 'forward', target_group_arn: target_group.target_group_arn }],
      }
      certificate_arn = l.fetch('certificate_arn', nil)
      if certificate_arn
        params[:certificates] = [{ certificate_arn: certificate_arn }]
      end

      unless listener_ports.include?(params[:port])
        listener = elb_client.create_listener(params).listeners[0]
        Hako.logger.info("Created listener #{listener.listener_arn}")
      end
    end
  end

  true
end

#load_balancer_given?Boolean

Returns:

  • (Boolean)


251
252
253
# File 'lib/hako/schedulers/ecs_elb_v2.rb', line 251

def load_balancer_given?
  @elb_v2_config.key?('load_balancer_name')
end

#load_balancer_params_for_serviceHash

Returns:

  • (Hash)


266
267
268
269
270
271
272
# File 'lib/hako/schedulers/ecs_elb_v2.rb', line 266

def load_balancer_params_for_service
  {
    target_group_arn: describe_target_group.target_group_arn,
    container_name: @elb_v2_config.fetch('container_name', 'front'),
    container_port: @elb_v2_config.fetch('container_port', 80),
  }
end

#modify_attributesnil

Returns:

  • (nil)


131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/hako/schedulers/ecs_elb_v2.rb', line 131

def modify_attributes
  unless @elb_v2_config
    return nil
  end

  unless load_balancer_given?
    load_balancer = describe_load_balancer
    subnets = @elb_v2_config.fetch('subnets').sort
    if load_balancer && subnets != load_balancer.availability_zones.map(&:subnet_id).sort
      if @dry_run
        Hako.logger.info("elb_client.set_subnets(load_balancer_arn: #{load_balancer.load_balancer_arn}, subnets: #{subnets}) (dry-run)")
      else
        Hako.logger.info("Updating ELBv2 subnets to #{subnets}")
        elb_client.set_subnets(load_balancer_arn: load_balancer.load_balancer_arn, subnets: subnets)
      end
    end

    new_listeners = @elb_v2_config.fetch('listeners')
    if load_balancer
      current_listeners = elb_client.describe_listeners(load_balancer_arn: load_balancer.load_balancer_arn).listeners
      new_listeners.each do |new_listener|
        current_listener = current_listeners.find { |l| l.port == new_listener['port'] }
        if current_listener && new_listener['ssl_policy'] && new_listener['ssl_policy'] != current_listener.ssl_policy
          if @dry_run
            Hako.logger.info("elb_client.modify_listener(listener_arn: #{current_listener.listener_arn}, ssl_policy: #{new_listener['ssl_policy']}) (dry-run)")
          else
            Hako.logger.info("Updating ELBv2 listener #{new_listener['port']} ssl_policy to #{new_listener['ssl_policy']}")
            elb_client.modify_listener(listener_arn: current_listener.listener_arn, ssl_policy: new_listener['ssl_policy'])
          end
        end
      end
    end

    if @elb_v2_config.key?('load_balancer_attributes')
      attributes = @elb_v2_config.fetch('load_balancer_attributes').map { |key, value| { key: key, value: value } }
      if @dry_run
        if load_balancer
          Hako.logger.info("elb_client.modify_load_balancer_attributes(load_balancer_arn: #{load_balancer.load_balancer_arn}, attributes: #{attributes.inspect}) (dry-run)")
        else
          Hako.logger.info("elb_client.modify_load_balancer_attributes(load_balancer_arn: unknown, attributes: #{attributes.inspect}) (dry-run)")
        end
      else
        Hako.logger.info("Updating ELBv2 attributes to #{attributes.inspect}")
        elb_client.modify_load_balancer_attributes(load_balancer_arn: load_balancer.load_balancer_arn, attributes: attributes)
      end
    end
  end

  unless target_group_given?
    if @elb_v2_config.key?('target_group_attributes')
      target_group = describe_target_group
      attributes = @elb_v2_config.fetch('target_group_attributes').map { |key, value| { key: key, value: value } }
      if @dry_run
        if target_group
          Hako.logger.info("elb_client.modify_target_group_attributes(target_group_arn: #{target_group.target_group_arn}, attributes: #{attributes.inspect}) (dry-run)")
        else
          Hako.logger.info("elb_client.modify_target_group_attributes(target_group_arn: unknown, attributes: #{attributes.inspect}) (dry-run)")
        end
      else
        Hako.logger.info("Updating target group attributes to #{attributes.inspect}")
        elb_client.modify_target_group_attributes(target_group_arn: target_group.target_group_arn, attributes: attributes)
      end
    end
  end
  nil
end

#show_status(ecs_lb) ⇒ nil

Parameters:

  • ecs_lb (Aws::ECS::Types::LoadBalancer)

Returns:

  • (nil)


23
24
25
26
27
28
29
30
# File 'lib/hako/schedulers/ecs_elb_v2.rb', line 23

def show_status(ecs_lb)
  lb = describe_load_balancer
  elb_client.describe_listeners(load_balancer_arn: lb.load_balancer_arn).each do |page|
    page.listeners.each do |listener|
      puts "  #{lb.dns_name}:#{listener.port} -> #{ecs_lb.container_name}:#{ecs_lb.container_port}"
    end
  end
end

#target_group_given?Boolean

Returns:

  • (Boolean)


261
262
263
# File 'lib/hako/schedulers/ecs_elb_v2.rb', line 261

def target_group_given?
  @elb_v2_config.key?('target_group_name')
end

#target_group_nameString

Returns:

  • (String)


256
257
258
# File 'lib/hako/schedulers/ecs_elb_v2.rb', line 256

def target_group_name
  @elb_v2_config.fetch('target_group_name', "hako-#{@app_id}")
end