ufo 6.3.3 → 6.3.6

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0b97f721b8915f665745b998087e612bb4bae0cc7f2a4046a9efe8492e2eac0c
4
- data.tar.gz: b093ecdafedad9522784798d331256112efdcfabce099c97b980d03a7ddc4e09
3
+ metadata.gz: 586d1502a32e9d1e3aa5a8447371c5b9fc854f189a841b9a822ce2cef4156c0b
4
+ data.tar.gz: 03607a2573b1a27c245f2b42614589513250fa91f2c8c69b5f8767664083aeb9
5
5
  SHA512:
6
- metadata.gz: 787c7cb0f1818a34bdba0e4a075ca428cefc53b5c51fde23deda1fdd180eb12a845af279d6793743dd867ca7be68122366d104d7a56b6c94ed1742f3c7938a2b
7
- data.tar.gz: 1e1a58d83901bf2218faad41263e51095022b1db1fc138cad9502b9c49da08131490b8d649b22e07027cae2ba61782d5a3c1bddc14789675e537b2b2254e6e71
6
+ metadata.gz: b9b72a9063f47a628cf5455f91a9db1f6db89e74416b54a30cd21724a010d4bd040e31b48caf4d2fec381e88d06d4efb8e8202b3d31e2ac7d8913e38a669ec1b
7
+ data.tar.gz: 29d841dd38e9ba2b2132adf00689b9e39eb34dcf3436601d70f7d78675f9b4eece5f08739a29ac9bfd6c0f3762ec4867d72ea9df1b681fe77f04290da3c498af
data/CHANGELOG.md CHANGED
@@ -3,6 +3,17 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  This project *tries* to adhere to [Semantic Versioning](http://semver.org/), even before v1.0.
5
5
 
6
+ ## [6.3.6] - 2022-04-29
7
+ - [#172](https://github.com/tongueroo/ufo/pull/172) support multiple ssl certs
8
+
9
+ ## [6.3.5] - 2022-04-28
10
+ - [#171](https://github.com/tongueroo/ufo/pull/171) default unhealthy_threshold_count = 3
11
+
12
+ ## [6.3.4] - 2022-04-27
13
+ - [#168](https://github.com/tongueroo/ufo/pull/168) ufo ps: show multiple container names
14
+ - [#169](https://github.com/tongueroo/ufo/pull/169) ufo logs improvements
15
+ - [#170](https://github.com/tongueroo/ufo/pull/170) infer ecs managed sg based on awsvpc network mode
16
+
6
17
  ## [6.3.3] - 2022-03-27
7
18
  - [#167](https://github.com/tongueroo/ufo/pull/167) fix edge case include_dir for ruby 2.7
8
19
  - remove update_dockerignore
@@ -18,22 +18,23 @@ class Ufo::Cfn::Stack::Builder
18
18
  def security_groups(type)
19
19
  group_ids = Ufo.config.vpc.security_groups[type] || []
20
20
  # no security groups at all
21
- return if !managed_security_groups? && group_ids.blank?
21
+ return if type == :ecs && !manage_ecs_security_group? && group_ids.blank?
22
22
 
23
23
  groups = []
24
24
  groups += group_ids
25
- groups += [managed_security_group(type.to_s.camelize)] if managed_security_groups?
25
+ groups += [managed_security_group(type)] if manage_ecs_security_group? || type == :elb
26
26
  groups
27
27
  end
28
28
 
29
29
  def managed_security_group(type)
30
- logical_id = managed_security_groups? ? "#{type.camelize}SecurityGroup" : "AWS::NoValue"
30
+ logical_id = type == :elb || manage_ecs_security_group? ? "#{type.to_s.camelize}SecurityGroup" : "AWS::NoValue"
31
31
  {Ref: logical_id}
32
32
  end
33
33
 
34
- def managed_security_groups?
35
- managed = Ufo.config.vpc.security_groups.managed
36
- managed.nil? ? true : managed
34
+ # With network mode is awsvpc always create UFO managed ECS security group
35
+ # With bridge mode, never create as there's no point.
36
+ def manage_ecs_security_group?
37
+ vars[:container][:network_mode].to_s == 'awsvpc'
37
38
  end
38
39
 
39
40
  def self.build(options={})
@@ -0,0 +1,30 @@
1
+ class Ufo::Cfn::Stack::Builder::Resources
2
+ class ListenerCertificate < ListenerSsl
3
+ def build
4
+ return unless certificates.size >= 1 # already removed firt cert
5
+ {
6
+ Type: "AWS::ElasticLoadBalancingV2::ListenerCertificate",
7
+ Condition: "CreateElbIsTrue",
8
+ Properties: properties,
9
+ }
10
+ end
11
+
12
+ def properties
13
+ {
14
+ Certificates: certificates,
15
+ ListenerArn: {Ref: "ListenerSsl"}
16
+ }
17
+ end
18
+
19
+ def certificates
20
+ ssl = Ufo.config.elb.ssl
21
+ certs = normalize(ssl.certificates) if ssl.certificates
22
+ # CloudFormation has weird interface
23
+ # Only one cert allowed at the AWS::ElasticLoadBalancingV2::Listener
24
+ # https://stackoverflow.com/questions/54447250/how-to-set-multiple-certificates-for-awselasticloadbalancingv2listener
25
+ # Also note the docs say "You can specify one certificate per resource."
26
+ # But tested and multiple certs here work
27
+ certs[1..-1] # dont include the first one
28
+ end
29
+ end
30
+ end
@@ -7,7 +7,10 @@ class Ufo::Cfn::Stack::Builder::Resources
7
7
 
8
8
  def properties
9
9
  props = super
10
- props[:Certificates] = certificates
10
+ # CloudFormation has weird interface
11
+ # Only one cert allowed at the AWS::ElasticLoadBalancingV2::Listener
12
+ # https://stackoverflow.com/questions/54447250/how-to-set-multiple-certificates-for-awselasticloadbalancingv2listener
13
+ props[:Certificates] = [certificates.first] # first one only
11
14
  props
12
15
  end
13
16
 
@@ -1,7 +1,8 @@
1
1
  module Ufo::Cfn::Stack::Builder::Resources::SecurityGroup
2
2
  class Ecs < Base
3
3
  def build
4
- return unless managed_security_groups?
4
+ return unless manage_ecs_security_group?
5
+ return unless vars[:container][:network_mode].to_s == 'awsvpc'
5
6
 
6
7
  {
7
8
  Type: "AWS::EC2::SecurityGroup",
@@ -1,8 +1,7 @@
1
1
  module Ufo::Cfn::Stack::Builder::Resources::SecurityGroup
2
2
  class EcsRule < Base
3
3
  def build
4
- return unless managed_security_groups?
5
- return unless vars[:elb_type] == "application"
4
+ return unless manage_ecs_security_group?
6
5
 
7
6
  {
8
7
  Type: "AWS::EC2::SecurityGroupIngress",
@@ -1,7 +1,7 @@
1
1
  module Ufo::Cfn::Stack::Builder::Resources::SecurityGroup
2
2
  class Elb < Base
3
3
  def build
4
- return unless managed_security_groups?
4
+ # Always create elb security group it seems like its required
5
5
  return unless vars[:elb_type] == "application"
6
6
 
7
7
  {
@@ -10,6 +10,7 @@ class Ufo::Cfn::Stack::Builder
10
10
  ElbSecurityGroup: SecurityGroup::Elb.build(@options),
11
11
  ExecutionRole: IamRoles::ExecutionRole.build(@options),
12
12
  Listener: Listener.build(@options),
13
+ ListenerCertificate: ListenerCertificate.build(@options),
13
14
  ListenerSsl: ListenerSsl.build(@options),
14
15
  TargetGroup: TargetGroup.build(@options),
15
16
  TaskDefinition: TaskDefinition.build(@options),
data/lib/ufo/cli/logs.rb CHANGED
@@ -6,11 +6,11 @@ class Ufo::CLI
6
6
 
7
7
  def run
8
8
  log = find_log_group_name
9
- puts "Showing logs for stack: #{@stack_name} log group: #{log["awslogs-group"]} and stream prefix: #{log["awslogs-stream-prefix"]}"
9
+ logger.info "Showing logs for stack: #{@stack_name} log group: #{log["awslogs-group"]} and stream prefix: #{log["awslogs-stream-prefix"]}"
10
10
  if log
11
11
  cloudwatch_tail(log)
12
12
  else
13
- puts "Unable to find log group for service: #{service.service_name}"
13
+ logger.info "Unable to find log group for service: #{service.service_name}"
14
14
  end
15
15
  end
16
16
 
@@ -24,22 +24,40 @@ class Ufo::CLI
24
24
 
25
25
  container_definitions = resp.task_definition.container_definitions
26
26
 
27
- unless container_definitions.size == 1
28
- puts "ERROR: ufo logs command only supports 1 container definition in the ECS task definition".color(:red)
29
- return
27
+ if container_definitions.size > 1 && !@options[:container]
28
+ logger.info "Multiple containers found. ufo logs will use the first container."
29
+ logger.info "You can also use the --container option to set the container to use."
30
+ end
31
+
32
+ definition = if @options[:container]
33
+ container_definitions.find do |c|
34
+ c.name == @options[:container]
35
+ end
36
+ else
37
+ container_definitions.first
38
+ end
39
+
40
+ unless definition
41
+ logger.error "ERROR: unable to find a container".color(:red)
42
+ logger.error "You specified --container #{@options[:container]}" if @options[:container]
43
+ exit
30
44
  end
31
45
 
32
- definition = container_definitions.first
33
46
  log_conf = definition.log_configuration
47
+ unless log_conf
48
+ logger.error "ERROR: Unable to find a log_configuration for container: #{definition.name}".color(:red)
49
+ logger.error "You specified --container #{@options[:container]}" if @options[:container]
50
+ exit 1
51
+ end
34
52
 
35
- if log_conf && log_conf.log_driver == "awslogs"
53
+ if log_conf.log_driver == "awslogs"
36
54
  # options["awslogs-group"]
37
55
  # options["awslogs-region"]
38
56
  # options["awslogs-stream-prefix"]
39
57
  log_conf.options
40
58
  else
41
- puts "Only supports awslogs driver. Detected log_driver: #{log_conf.log_driver}"
42
- return
59
+ logger.error "ERROR: Only supports awslogs driver. Detected log_driver: #{log_conf.log_driver}".color(:red)
60
+ exit 1 unless ENV['UFO_TEST']
43
61
  end
44
62
  end
45
63
 
@@ -16,12 +16,36 @@ class Ufo::CLI::Ps
16
16
 
17
17
  def name
18
18
  container_overrides = @task.dig("overrides", "container_overrides")
19
- overrides = container_overrides.first # assume first is one we want
20
- overrides["name"] if overrides # PENDING wont yet have info
19
+ overrides = container_overrides # assume first is one we want
20
+ if !overrides.empty? # PENDING wont yet have info
21
+ overrides.map { |i| i["name"] }.join(',')
22
+ else
23
+ container_names
24
+ end
21
25
  rescue NoMethodError
22
- container = @task["containers"].first
23
- container["name"] if container # PENDING wont yet have info
26
+ container_names
27
+ end
28
+
29
+ # PENDING wont yet have any containers yet but since using task definition we're ok
30
+ def container_names
31
+ task_definition = task_definition(@task.task_definition_arn)
32
+ names = task_definition.container_definitions.map do |container_definition|
33
+ container_definition.name
34
+ end
35
+ names.join(',')
36
+ end
37
+
38
+ # ECS inconsistently returns the container names in random order
39
+ # Look up the names from the task definition to try and get right order
40
+ # This still seems to return inconsistently.
41
+ # IE: Not the order that was defined in the task definition originally
42
+ def task_definition(task_definition_arn)
43
+ resp = ecs.describe_task_definition(
44
+ task_definition: task_definition_arn,
45
+ )
46
+ resp.task_definition
24
47
  end
48
+ memoize :task_definition
25
49
 
26
50
  def container_instance_arn
27
51
  @task['container_instance_arn'].split('/').last
data/lib/ufo/cli.rb CHANGED
@@ -64,6 +64,7 @@ module Ufo
64
64
  option :since, desc: "From what time to begin displaying logs. By default, logs will be displayed starting from 1 minutes in the past. The value provided can be an ISO 8601 timestamp or a relative time."
65
65
  option :format, default: "short", desc: "The format to display the logs. IE: detailed or short. With detailed, the log stream name is also shown."
66
66
  option :filter_pattern, desc: "The filter pattern to use. If not provided, all the events are matched"
67
+ option :container, aliases: :c, desc: "Container name to show logs for. Only needed when ECS task multiple containers"
67
68
  def logs
68
69
  Logs.new(options).run
69
70
  end
data/lib/ufo/config.rb CHANGED
@@ -70,7 +70,7 @@ module Ufo
70
70
  config.elb.health_check_interval_seconds = 10 # keep at 10 in case of network ELB, which is min 10
71
71
  config.elb.health_check_path = nil # When nil its AWS default /
72
72
  config.elb.healthy_threshold_count = 3 # The AWS usual default is 5
73
- config.elb.unhealthy_threshold_count = 2
73
+ config.elb.unhealthy_threshold_count = 3
74
74
 
75
75
  config.elb.port = 80 # default listener port
76
76
  config.elb.redirect = ActiveSupport::OrderedOptions.new
@@ -138,7 +138,6 @@ module Ufo
138
138
  config.vpc.security_groups = ActiveSupport::OrderedOptions.new
139
139
  config.vpc.security_groups.ecs = nil
140
140
  config.vpc.security_groups.elb = nil
141
- config.vpc.security_groups.managed = true
142
141
  config.vpc.subnets = ActiveSupport::OrderedOptions.new
143
142
  config.vpc.subnets.ecs = nil
144
143
  config.vpc.subnets.elb = nil
data/lib/ufo/info.rb CHANGED
@@ -23,9 +23,18 @@ module Ufo
23
23
  load_balancer = service.load_balancers.first
24
24
  return unless load_balancer
25
25
 
26
- resp = elb.describe_target_groups(
27
- target_group_arns: [load_balancer.target_group_arn]
28
- )
26
+ begin
27
+ resp = elb.describe_target_groups(
28
+ target_group_arns: [load_balancer.target_group_arn]
29
+ )
30
+ rescue Aws::ElasticLoadBalancingV2::Errors::TargetGroupNotFound
31
+ # Super edge case when:
32
+ # 1. deploy with ELB
33
+ # 2. deploy again without ELB
34
+ # 3. ECS service sometimes still thinks there's an ELB
35
+ # Error: https://gist.github.com/tongueroo/dc41f408e65414ab5ee864d0d738d81a
36
+ return
37
+ end
29
38
  target_group = resp.target_groups.first
30
39
  load_balancer_arn = target_group.load_balancer_arns.first # assume first only
31
40
  return unless load_balancer_arn # can occur while stack is being deleted
data/lib/ufo/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Ufo
2
- VERSION = "6.3.3"
2
+ VERSION = "6.3.6"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ufo
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.3.3
4
+ version: 6.3.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tung Nguyen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-03-27 00:00:00.000000000 Z
11
+ date: 2022-04-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aws-logs
@@ -516,6 +516,7 @@ files:
516
516
  - lib/ufo/cfn/stack/builder/resources/iam_roles/execution_role.rb
517
517
  - lib/ufo/cfn/stack/builder/resources/iam_roles/task_role.rb
518
518
  - lib/ufo/cfn/stack/builder/resources/listener.rb
519
+ - lib/ufo/cfn/stack/builder/resources/listener_certificate.rb
519
520
  - lib/ufo/cfn/stack/builder/resources/listener_ssl.rb
520
521
  - lib/ufo/cfn/stack/builder/resources/scaling/base.rb
521
522
  - lib/ufo/cfn/stack/builder/resources/scaling/policy.rb
@@ -716,7 +717,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
716
717
  - !ruby/object:Gem::Version
717
718
  version: '0'
718
719
  requirements: []
719
- rubygems_version: 3.3.10
720
+ rubygems_version: 3.3.12
720
721
  signing_key:
721
722
  specification_version: 4
722
723
  summary: AWS ECS Deploy Tool