ufo 4.5.11 → 5.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +29 -0
- data/README.md +2 -0
- data/docs/_docs/conventions.md +1 -1
- data/docs/_docs/extras/codebuild-iam-role.md +2 -2
- data/docs/_docs/extras/dockerfile-erb.md +2 -2
- data/docs/_docs/extras/ecs-network-mode.md +2 -2
- data/docs/_docs/extras/load-balancer.md +2 -2
- data/docs/_docs/extras/minimal-deploy-iam.md +2 -2
- data/docs/_docs/extras/notification-arns.md +21 -0
- data/docs/_docs/extras/redirection-support.md +2 -2
- data/docs/_docs/extras/route53-support.md +2 -2
- data/docs/_docs/extras/security-groups.md +2 -2
- data/docs/_docs/extras/ssl-support.md +2 -2
- data/docs/_docs/faq.md +2 -2
- data/docs/_docs/helpers.md +7 -5
- data/docs/_docs/iam-roles.md +111 -0
- data/docs/_docs/install.md +1 -1
- data/docs/_docs/more/auto-completion.md +2 -2
- data/docs/_docs/more/automated-cleanup.md +2 -2
- data/docs/_docs/more/customize-cloudformation.md +2 -2
- data/docs/_docs/more/migrations.md +2 -2
- data/docs/_docs/more/run-in-pieces.md +2 -2
- data/docs/_docs/more/single-task.md +2 -2
- data/docs/_docs/more/stuck-cloudformation.md +2 -2
- data/docs/_docs/more/why-cloudformation.md +2 -2
- data/docs/_docs/next-steps.md +2 -2
- data/docs/_docs/quick-start-ec2.md +2 -1
- data/docs/_docs/secrets.md +112 -0
- data/docs/_docs/settings.md +1 -1
- data/docs/_docs/settings/aws_profile.md +1 -1
- data/docs/_docs/settings/cfn.md +1 -1
- data/docs/_docs/settings/cluster.md +8 -14
- data/docs/_docs/settings/network.md +1 -1
- data/docs/_docs/ssl_errors.md +1 -2
- data/docs/_docs/structure.md +1 -1
- data/docs/_docs/tutorial-ufo-docker-build.md +1 -1
- data/docs/_docs/tutorial-ufo-init.md +1 -1
- data/docs/_docs/tutorial-ufo-ship.md +1 -1
- data/docs/_docs/tutorial-ufo-ships.md +1 -1
- data/docs/_docs/tutorial-ufo-tasks-build.md +1 -1
- data/docs/_docs/tutorial.md +1 -1
- data/docs/_docs/ufo-current.md +2 -2
- data/docs/_docs/ufo-env-extra.md +2 -2
- data/docs/_docs/ufo-env.md +2 -2
- data/docs/_docs/ufo-logs.md +50 -0
- data/docs/_docs/ufo-task-params.md +2 -2
- data/docs/_docs/upgrading.md +2 -2
- data/docs/_docs/upgrading/upgrade4.5.md +2 -2
- data/docs/_docs/upgrading/upgrade4.md +2 -2
- data/docs/_docs/variables.md +1 -1
- data/docs/_includes/subnav.html +4 -0
- data/docs/_reference/ufo-deploy.md +1 -2
- data/docs/_reference/ufo-init.md +1 -1
- data/docs/_reference/ufo-logs.md +40 -0
- data/docs/_reference/ufo-rollback.md +2 -0
- data/docs/_reference/ufo-ship.md +1 -2
- data/docs/_reference/ufo-ships.md +1 -2
- data/docs/_reference/ufo-tasks-build.md +1 -2
- data/docs/articles.md +2 -2
- data/docs/docs.md +1 -1
- data/docs/quick-start.md +2 -1
- data/docs/reference.md +1 -0
- data/lib/template/.secrets +3 -0
- data/lib/template/.ufo/settings.yml.tt +1 -0
- data/lib/template/.ufo/settings/cfn/default.yml.tt +27 -27
- data/lib/template/.ufo/settings/network/default.yml.tt +9 -0
- data/lib/template/.ufo/templates/fargate.json.erb +3 -0
- data/lib/template/.ufo/templates/main.json.erb +3 -0
- data/lib/template/.ufo/variables/base.rb.tt +1 -0
- data/lib/ufo.rb +2 -1
- data/lib/ufo/autoloader.rb +9 -0
- data/lib/ufo/cli.rb +12 -1
- data/lib/ufo/command.rb +7 -0
- data/lib/ufo/core.rb +1 -9
- data/lib/ufo/docker/cleaner.rb +1 -1
- data/lib/ufo/dsl.rb +6 -1
- data/lib/ufo/dsl/helper.rb +21 -27
- data/lib/ufo/dsl/helper/vars.rb +98 -0
- data/lib/ufo/dsl/outputter.rb +12 -9
- data/lib/ufo/help/init.md +1 -1
- data/lib/ufo/help/logs.md +10 -0
- data/lib/ufo/log_group.rb +1 -0
- data/lib/ufo/logs.rb +56 -0
- data/lib/ufo/role/builder.rb +66 -0
- data/lib/ufo/role/dsl.rb +21 -0
- data/lib/ufo/role/registry.rb +24 -0
- data/lib/ufo/rollback.rb +2 -1
- data/lib/ufo/setting/profile.rb +11 -7
- data/lib/ufo/setting/security_groups.rb +22 -0
- data/lib/ufo/settings.rb +20 -0
- data/lib/ufo/stack.rb +24 -24
- data/lib/ufo/stack/builder.rb +26 -0
- data/lib/ufo/stack/builder/base.rb +54 -0
- data/lib/ufo/stack/builder/conditions.rb +23 -0
- data/lib/ufo/stack/builder/outputs.rb +24 -0
- data/lib/ufo/stack/builder/parameters.rb +45 -0
- data/lib/ufo/stack/builder/resources.rb +20 -0
- data/lib/ufo/stack/builder/resources/base.rb +4 -0
- data/lib/ufo/stack/builder/resources/dns.rb +17 -0
- data/lib/ufo/stack/builder/resources/ecs.rb +63 -0
- data/lib/ufo/stack/builder/resources/elb.rb +45 -0
- data/lib/ufo/stack/builder/resources/listener.rb +42 -0
- data/lib/ufo/stack/builder/resources/listener_ssl.rb +16 -0
- data/lib/ufo/stack/builder/resources/roles/base.rb +22 -0
- data/lib/ufo/stack/builder/resources/roles/execution_role.rb +4 -0
- data/lib/ufo/stack/builder/resources/roles/task_role.rb +4 -0
- data/lib/ufo/stack/builder/resources/security_group/base.rb +4 -0
- data/lib/ufo/stack/builder/resources/security_group/ecs.rb +44 -0
- data/lib/ufo/stack/builder/resources/security_group/ecs_rule.rb +25 -0
- data/lib/ufo/stack/builder/resources/security_group/elb.rb +57 -0
- data/lib/ufo/stack/builder/resources/target_group.rb +39 -0
- data/lib/ufo/stack/builder/resources/task_definition.rb +24 -0
- data/lib/ufo/stack/builder/resources/task_definition/reconstructor.rb +49 -0
- data/lib/ufo/stack/context.rb +41 -48
- data/lib/ufo/stack/custom_properties.rb +59 -0
- data/lib/ufo/stack/helper.rb +2 -5
- data/lib/ufo/stack/template_body.rb +13 -0
- data/lib/ufo/task.rb +2 -7
- data/lib/ufo/tasks.rb +1 -1
- data/lib/ufo/tasks/builder.rb +0 -1
- data/lib/ufo/tasks/register.rb +11 -8
- data/lib/ufo/template_scope.rb +1 -66
- data/lib/ufo/utils/squeezer.rb +24 -0
- data/lib/ufo/version.rb +1 -1
- data/spec/fixtures/iam_roles/task_role.rb +17 -0
- data/spec/fixtures/mocks/logs/awslogs.json +70 -0
- data/spec/fixtures/mocks/logs/no-awslogs.json +70 -0
- data/spec/lib/logs_spec.rb +55 -0
- data/spec/lib/role/builder_spec.rb +67 -0
- data/spec/lib/role/dsl_spec.rb +12 -0
- data/ufo.gemspec +2 -0
- metadata +82 -5
- data/lib/cfn/stack.yml +0 -283
@@ -0,0 +1,59 @@
|
|
1
|
+
class Ufo::Stack
|
2
|
+
class CustomProperties
|
3
|
+
include Ufo::Settings
|
4
|
+
|
5
|
+
def initialize(template, stack_name)
|
6
|
+
@template, @stack_name = template, stack_name
|
7
|
+
end
|
8
|
+
|
9
|
+
def apply
|
10
|
+
customizations = camelize(cfn)
|
11
|
+
@template["Resources"].each do |logical_id, attrs|
|
12
|
+
custom_props = customizations[logical_id]
|
13
|
+
next unless custom_props
|
14
|
+
attrs["Properties"].deeper_merge!(custom_props, {overwrite_arrays: true})
|
15
|
+
end
|
16
|
+
|
17
|
+
substitute_variables!(@template["Resources"])
|
18
|
+
@template
|
19
|
+
end
|
20
|
+
|
21
|
+
# Keep backward compatiablity but encouraging CamelCase now because in the ufo init generator
|
22
|
+
# the .ufo/settings/cfn/default.yml is now CamelCase
|
23
|
+
def camelize(properties)
|
24
|
+
if ENV['UFO_CAMELIZE'] == '0' || settings[:auto_camelize] == false # provide a way to quickly test full camelize disable
|
25
|
+
return properties.deep_stringify_keys
|
26
|
+
end
|
27
|
+
|
28
|
+
# transform keys: camelize
|
29
|
+
properties.deep_stringify_keys.deep_transform_keys do |key|
|
30
|
+
if key == key.upcase # trying to generalize special rule for dns.TTL
|
31
|
+
key # leave key alone if key is already in all upcase
|
32
|
+
else
|
33
|
+
key.camelize
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Substitute special variables that cannot be baked into the template
|
39
|
+
# because they are dynamically assigned. Only one special variable:
|
40
|
+
#
|
41
|
+
# {stack_name}
|
42
|
+
def substitute_variables!(properties)
|
43
|
+
# transform values and substitute for special values
|
44
|
+
# https://stackoverflow.com/questions/34595142/process-nested-hash-to-convert-all-values-to-strings
|
45
|
+
#
|
46
|
+
# Examples:
|
47
|
+
# "{stack_name}.stag.boltops.com." => development-demo-web.stag.boltops.com.
|
48
|
+
# "{stack_name}.stag.boltops.com." => dev-demo-web-2.stag.boltops.com.
|
49
|
+
properties.deep_merge(properties) do |_,_,v|
|
50
|
+
if v.is_a?(String)
|
51
|
+
v.sub!('{stack_name}', @stack_name) # need shebang, updating in-place
|
52
|
+
else
|
53
|
+
v
|
54
|
+
end
|
55
|
+
end
|
56
|
+
properties
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
data/lib/ufo/stack/helper.rb
CHANGED
@@ -2,6 +2,7 @@ class Ufo::Stack
|
|
2
2
|
module Helper
|
3
3
|
include Ufo::AwsService
|
4
4
|
include Ufo::Util
|
5
|
+
include Ufo::Settings
|
5
6
|
extend Memoist
|
6
7
|
|
7
8
|
def find_stack(stack_name)
|
@@ -34,15 +35,11 @@ class Ufo::Stack
|
|
34
35
|
when "append_nothing", "prepend_nothing"
|
35
36
|
[service, Ufo.env_extra]
|
36
37
|
else # new default. ufo v4.5 and above
|
37
|
-
[service, Ufo.env, Ufo.env_extra]
|
38
|
+
[service, Ufo.env.to_s, Ufo.env_extra]
|
38
39
|
end
|
39
40
|
parts.reject {|x| x==''}.compact.join('-') # stack_name
|
40
41
|
end
|
41
42
|
|
42
|
-
def cfn
|
43
|
-
Ufo::Setting::Profile.new(:cfn, settings[:cfn_profile]).data
|
44
|
-
end
|
45
|
-
|
46
43
|
def status
|
47
44
|
Status.new(@stack_name)
|
48
45
|
end
|
data/lib/ufo/task.rb
CHANGED
@@ -2,8 +2,9 @@ module Ufo
|
|
2
2
|
class Task < Base
|
3
3
|
extend Memoist
|
4
4
|
|
5
|
-
include Util
|
6
5
|
include AwsService
|
6
|
+
include Ufo::Settings
|
7
|
+
include Util
|
7
8
|
|
8
9
|
def initialize(task_definition, options)
|
9
10
|
@task_definition = task_definition
|
@@ -139,12 +140,6 @@ module Ufo
|
|
139
140
|
options
|
140
141
|
end
|
141
142
|
|
142
|
-
def network
|
143
|
-
settings = Ufo.settings
|
144
|
-
Setting::Profile.new(:network, settings[:network_profile]).data
|
145
|
-
end
|
146
|
-
memoize :network
|
147
|
-
|
148
143
|
def cloudwatch_info(task_arn)
|
149
144
|
config = container_definition[:log_configuration]
|
150
145
|
container_name = container_definition[:name]
|
data/lib/ufo/tasks.rb
CHANGED
@@ -2,7 +2,7 @@ module Ufo
|
|
2
2
|
class Tasks < Command
|
3
3
|
desc "build", "Build task definitions."
|
4
4
|
long_desc Help.text("tasks:build")
|
5
|
-
option :
|
5
|
+
option :image_override, desc: "Override image in task definition for quick testing"
|
6
6
|
def build
|
7
7
|
Tasks::Builder.new(options).build
|
8
8
|
end
|
data/lib/ufo/tasks/builder.rb
CHANGED
@@ -6,7 +6,6 @@ module Ufo
|
|
6
6
|
# build and register task definitions. There is little point of running them independently
|
7
7
|
# This method helps us do that.
|
8
8
|
build(options)
|
9
|
-
Tasks::Register.register(task_definition, options)
|
10
9
|
end
|
11
10
|
|
12
11
|
# ship: build and registers task definitions together
|
data/lib/ufo/tasks/register.rb
CHANGED
@@ -70,15 +70,18 @@ module Ufo
|
|
70
70
|
|
71
71
|
definitions = data[:container_definitions]
|
72
72
|
definitions.each_with_index do |definition, i|
|
73
|
-
next unless definition[:log_configuration]
|
74
|
-
|
75
|
-
|
73
|
+
next unless definition[:log_configuration] || definition[:firelens_configuration]
|
74
|
+
{ log_configuration: 'logConfiguration',
|
75
|
+
firelens_configuration: 'firelensConfiguration' }.each_pair do |key, value|
|
76
76
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
77
|
+
next unless definition.dig(key, :options)
|
78
|
+
|
79
|
+
# LogConfiguration and firelensConfiguration options do not get transformed and
|
80
|
+
# keep their original structure:
|
81
|
+
# https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/ECS/Types/ContainerDefinition.html
|
82
|
+
original_definition = original_data["containerDefinitions"][i]
|
83
|
+
definition[key][:options] = original_definition[value]["options"]
|
84
|
+
end
|
82
85
|
end
|
83
86
|
|
84
87
|
data
|
data/lib/ufo/template_scope.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
module Ufo
|
2
2
|
class TemplateScope
|
3
3
|
extend Memoist
|
4
|
+
include Ufo::Settings
|
4
5
|
|
5
6
|
attr_reader :helper
|
6
7
|
attr_reader :task_definition_name
|
@@ -44,72 +45,6 @@ module Ufo
|
|
44
45
|
end
|
45
46
|
end
|
46
47
|
|
47
|
-
def network
|
48
|
-
Ufo::Setting::Profile.new(:network, settings[:network_profile]).data
|
49
|
-
end
|
50
|
-
memoize :network
|
51
|
-
|
52
|
-
def cfn
|
53
|
-
Ufo::Setting::Profile.new(:cfn, settings[:cfn_profile]).data
|
54
|
-
end
|
55
|
-
memoize :cfn
|
56
|
-
|
57
|
-
def settings
|
58
|
-
Ufo.settings
|
59
|
-
end
|
60
|
-
|
61
|
-
def custom_properties(resource)
|
62
|
-
resource = resource.to_s.underscore
|
63
|
-
properties = cfn[resource.to_sym]
|
64
|
-
return unless properties
|
65
|
-
|
66
|
-
# transform keys: camelize
|
67
|
-
properties = properties.deep_stringify_keys.deep_transform_keys do |key|
|
68
|
-
if key == key.upcase # trying to generalize special rule for dns.TTL
|
69
|
-
key # leave key alone if key is already in all upcase
|
70
|
-
else
|
71
|
-
key.camelize
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
substitute_variables!(properties)
|
76
|
-
|
77
|
-
yaml = YAML.dump(properties)
|
78
|
-
# add spaces in front on each line
|
79
|
-
yaml.split("\n")[1..-1].map do |line|
|
80
|
-
" #{line}"
|
81
|
-
end.join("\n") + "\n"
|
82
|
-
end
|
83
|
-
|
84
|
-
# Substitute special variables that cannot be baked into the template
|
85
|
-
# because they are dynamically assigned. Only one special variable:
|
86
|
-
#
|
87
|
-
# {stack_name}
|
88
|
-
def substitute_variables!(properties)
|
89
|
-
# transform values and substitute for special values
|
90
|
-
# https://stackoverflow.com/questions/34595142/process-nested-hash-to-convert-all-values-to-strings
|
91
|
-
#
|
92
|
-
# Examples:
|
93
|
-
# "{stack_name}.stag.boltops.com." => development-demo-web.stag.boltops.com.
|
94
|
-
# "{stack_name}.stag.boltops.com." => dev-demo-web-2.stag.boltops.com.
|
95
|
-
properties.deep_merge(properties) do |_,_,v|
|
96
|
-
if v.is_a?(String)
|
97
|
-
v.sub!('{stack_name}', @stack_name) # unsure why need shebang, but it works
|
98
|
-
else
|
99
|
-
v
|
100
|
-
end
|
101
|
-
end
|
102
|
-
properties
|
103
|
-
end
|
104
|
-
|
105
|
-
def default_target_group_protocol
|
106
|
-
default_elb_protocol
|
107
|
-
end
|
108
|
-
|
109
|
-
def default_elb_protocol
|
110
|
-
@elb_type == "application" ? "HTTP" : "TCP"
|
111
|
-
end
|
112
|
-
|
113
48
|
def pretty_name?
|
114
49
|
# env variable takes highest precedence
|
115
50
|
if ENV["STATIC_NAME"]
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Ufo::Utils
|
2
|
+
class Squeezer
|
3
|
+
def initialize(data)
|
4
|
+
@data = data
|
5
|
+
end
|
6
|
+
|
7
|
+
def squeeze(new_data=nil)
|
8
|
+
data = new_data.nil? ? @data : new_data
|
9
|
+
|
10
|
+
case data
|
11
|
+
when Array
|
12
|
+
data.map! { |v| squeeze(v) }
|
13
|
+
when Hash
|
14
|
+
data.each_with_object({}) do |(k,v), squeezed|
|
15
|
+
# only remove nil and empty Array values within Hash structures
|
16
|
+
squeezed[k] = squeeze(v) unless v.nil? || v.is_a?(Array) && v.empty?
|
17
|
+
squeezed
|
18
|
+
end
|
19
|
+
else
|
20
|
+
data # do not transform
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/ufo/version.rb
CHANGED
@@ -0,0 +1,17 @@
|
|
1
|
+
iam_policy("AmazonS3ReadOnlyAccess",
|
2
|
+
Action: [
|
3
|
+
"s3:Get*",
|
4
|
+
"s3:List*"
|
5
|
+
],
|
6
|
+
Effect: "Allow",
|
7
|
+
Resource: "*"
|
8
|
+
)
|
9
|
+
iam_policy("CloudwatchWrite",
|
10
|
+
Action: [
|
11
|
+
"cloudwatch:PutMetricData",
|
12
|
+
],
|
13
|
+
Effect: "Allow",
|
14
|
+
Resource: "*"
|
15
|
+
)
|
16
|
+
|
17
|
+
managed_iam_policy("AmazonS3ReadOnlyAccess", "AmazonEC2ReadOnlyAccess")
|
@@ -0,0 +1,70 @@
|
|
1
|
+
{
|
2
|
+
"task_definition": {
|
3
|
+
"task_definition_arn": "arn:aws:ecs:us-west-2:112233445566:task-definition/demo-web:1",
|
4
|
+
"container_definitions": [
|
5
|
+
{
|
6
|
+
"name": "web",
|
7
|
+
"image": "112233445566.dkr.ecr.us-west-2.amazonaws.com/demo/sinatra:ufo-2020-01-16T22-56-26-a28378e80",
|
8
|
+
"cpu": 256,
|
9
|
+
"memory": 1024,
|
10
|
+
"memory_reservation": 1024,
|
11
|
+
"port_mappings": [
|
12
|
+
{
|
13
|
+
"container_port": 4567,
|
14
|
+
"host_port": 4567,
|
15
|
+
"protocol": "tcp"
|
16
|
+
}
|
17
|
+
],
|
18
|
+
"essential": true,
|
19
|
+
"command": [
|
20
|
+
"bin/web"
|
21
|
+
],
|
22
|
+
"environment": [],
|
23
|
+
"log_configuration": {
|
24
|
+
"log_driver": "awslogs",
|
25
|
+
"options": {
|
26
|
+
"awslogs-group": "ecs/demo-web",
|
27
|
+
"awslogs-region": "us-west-2",
|
28
|
+
"awslogs-stream-prefix": "demo"
|
29
|
+
}
|
30
|
+
}
|
31
|
+
}
|
32
|
+
],
|
33
|
+
"family": "demo-web",
|
34
|
+
"task_role_arn": "arn:aws:iam::112233445566:role/demo",
|
35
|
+
"network_mode": "awsvpc",
|
36
|
+
"revision": 1,
|
37
|
+
"volumes": [
|
38
|
+
],
|
39
|
+
"status": "ACTIVE",
|
40
|
+
"requires_attributes": [
|
41
|
+
{
|
42
|
+
"name": "com.amazonaws.ecs.capability.logging-driver.awslogs"
|
43
|
+
},
|
44
|
+
{
|
45
|
+
"name": "com.amazonaws.ecs.capability.ecr-auth"
|
46
|
+
},
|
47
|
+
{
|
48
|
+
"name": "com.amazonaws.ecs.capability.docker-remote-api.1.19"
|
49
|
+
},
|
50
|
+
{
|
51
|
+
"name": "com.amazonaws.ecs.capability.docker-remote-api.1.21"
|
52
|
+
},
|
53
|
+
{
|
54
|
+
"name": "com.amazonaws.ecs.capability.task-iam-role"
|
55
|
+
},
|
56
|
+
{
|
57
|
+
"name": "com.amazonaws.ecs.capability.docker-remote-api.1.18"
|
58
|
+
},
|
59
|
+
{
|
60
|
+
"name": "ecs.capability.task-eni"
|
61
|
+
}
|
62
|
+
],
|
63
|
+
"placement_constraints": [
|
64
|
+
|
65
|
+
],
|
66
|
+
"compatibilities": [
|
67
|
+
"EC2"
|
68
|
+
]
|
69
|
+
}
|
70
|
+
}
|
@@ -0,0 +1,70 @@
|
|
1
|
+
{
|
2
|
+
"task_definition": {
|
3
|
+
"task_definition_arn": "arn:aws:ecs:us-west-2:112233445566:task-definition/demo-web:1",
|
4
|
+
"container_definitions": [
|
5
|
+
{
|
6
|
+
"name": "web",
|
7
|
+
"image": "112233445566.dkr.ecr.us-west-2.amazonaws.com/demo/sinatra:ufo-2020-01-16T22-56-26-a28378e80",
|
8
|
+
"cpu": 256,
|
9
|
+
"memory": 1024,
|
10
|
+
"memory_reservation": 1024,
|
11
|
+
"port_mappings": [
|
12
|
+
{
|
13
|
+
"container_port": 4567,
|
14
|
+
"host_port": 4567,
|
15
|
+
"protocol": "tcp"
|
16
|
+
}
|
17
|
+
],
|
18
|
+
"essential": true,
|
19
|
+
"command": [
|
20
|
+
"bin/web"
|
21
|
+
],
|
22
|
+
"environment": [],
|
23
|
+
"log_configuration": {
|
24
|
+
"log_driver": "whatever",
|
25
|
+
"options": {
|
26
|
+
"awslogs-group": "ecs/demo-web",
|
27
|
+
"awslogs-region": "us-west-2",
|
28
|
+
"awslogs-stream-prefix": "demo"
|
29
|
+
}
|
30
|
+
}
|
31
|
+
}
|
32
|
+
],
|
33
|
+
"family": "demo-web",
|
34
|
+
"task_role_arn": "arn:aws:iam::112233445566:role/demo",
|
35
|
+
"network_mode": "awsvpc",
|
36
|
+
"revision": 1,
|
37
|
+
"volumes": [
|
38
|
+
],
|
39
|
+
"status": "ACTIVE",
|
40
|
+
"requires_attributes": [
|
41
|
+
{
|
42
|
+
"name": "com.amazonaws.ecs.capability.logging-driver.awslogs"
|
43
|
+
},
|
44
|
+
{
|
45
|
+
"name": "com.amazonaws.ecs.capability.ecr-auth"
|
46
|
+
},
|
47
|
+
{
|
48
|
+
"name": "com.amazonaws.ecs.capability.docker-remote-api.1.19"
|
49
|
+
},
|
50
|
+
{
|
51
|
+
"name": "com.amazonaws.ecs.capability.docker-remote-api.1.21"
|
52
|
+
},
|
53
|
+
{
|
54
|
+
"name": "com.amazonaws.ecs.capability.task-iam-role"
|
55
|
+
},
|
56
|
+
{
|
57
|
+
"name": "com.amazonaws.ecs.capability.docker-remote-api.1.18"
|
58
|
+
},
|
59
|
+
{
|
60
|
+
"name": "ecs.capability.task-eni"
|
61
|
+
}
|
62
|
+
],
|
63
|
+
"placement_constraints": [
|
64
|
+
|
65
|
+
],
|
66
|
+
"compatibilities": [
|
67
|
+
"EC2"
|
68
|
+
]
|
69
|
+
}
|
70
|
+
}
|
@@ -0,0 +1,55 @@
|
|
1
|
+
describe Ufo::Logs do
|
2
|
+
let(:logs) do
|
3
|
+
logs = Ufo::Logs.new("test-web", {})
|
4
|
+
allow(logs).to receive(:exit).and_return(null)
|
5
|
+
allow(logs).to receive(:info).and_return(null)
|
6
|
+
allow(logs).to receive(:ecs).and_return(ecs)
|
7
|
+
logs
|
8
|
+
end
|
9
|
+
let(:ecs) do
|
10
|
+
ecs = double(:ecs).as_null_object
|
11
|
+
allow(ecs).to receive(:describe_task_definition).and_return(mock_response(fixture))
|
12
|
+
ecs
|
13
|
+
end
|
14
|
+
let(:null) { double(:null).as_null_object }
|
15
|
+
|
16
|
+
context "awslogs conf" do
|
17
|
+
let(:fixture) { "spec/fixtures/mocks/logs/awslogs.json" }
|
18
|
+
it "find_log_group_name" do
|
19
|
+
log_group_name = logs.find_log_group_name
|
20
|
+
expect(log_group_name).to eq({"awslogs-group" => "ecs/demo-web", "awslogs-region" => "us-west-2", "awslogs-stream-prefix" => "demo" })
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context "not a awslogs conf" do
|
25
|
+
let(:fixture) { "spec/fixtures/mocks/logs/no-awslogs.json" }
|
26
|
+
it "find_log_group_name" do
|
27
|
+
log_group_name = logs.find_log_group_name
|
28
|
+
expect(log_group_name).to be nil
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def mock_response(file)
|
33
|
+
data = JSON.load(IO.read(file))
|
34
|
+
|
35
|
+
td = data["task_definition"]
|
36
|
+
container_definitions = td["container_definitions"].map do |c|
|
37
|
+
l = c["log_configuration"]
|
38
|
+
log_configuration = Aws::ECS::Types::LogConfiguration.new(
|
39
|
+
log_driver: l["log_driver"],
|
40
|
+
options: l["options"],
|
41
|
+
)
|
42
|
+
Aws::ECS::Types::ContainerDefinition.new(
|
43
|
+
name: c["name"],
|
44
|
+
log_configuration: log_configuration,
|
45
|
+
)
|
46
|
+
end
|
47
|
+
task_definition = Aws::ECS::Types::TaskDefinition.new(
|
48
|
+
task_definition_arn: td["task_definition_arn"],
|
49
|
+
container_definitions: container_definitions,
|
50
|
+
)
|
51
|
+
Aws::ECS::Types::DescribeTaskDefinitionResponse.new(
|
52
|
+
task_definition: task_definition,
|
53
|
+
)
|
54
|
+
end
|
55
|
+
end
|